Fill Role names in kops-controller-config instead of instance profile names when it is specified

The role names are checked in node bootstrap.
If profile names are provided, bootstrap will fail.
Because profile name and role name do not always mactch in AWS IAM
This commit is contained in:
AkiraFukushima 2021-02-11 14:28:49 +09:00
parent f7b0f4444a
commit 36acadca59
6 changed files with 49 additions and 2 deletions

View File

@ -37,6 +37,7 @@ go_library(
"//vendor/github.com/aws/aws-sdk-go/aws:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/service/ec2:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/service/elbv2:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/service/iam:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/service/route53:go_default_library",
"//vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors:go_default_library",
"//vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/zones:go_default_library",

View File

@ -26,6 +26,7 @@ import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go/service/elbv2"
"github.com/aws/aws-sdk-go/service/iam"
"github.com/aws/aws-sdk-go/service/route53"
"github.com/gophercloud/gophercloud/openstack/compute/v2/flavors"
"github.com/gophercloud/gophercloud/openstack/dns/v2/zones"
@ -256,6 +257,17 @@ func (h *IntegrationTestHarness) SetupMockAWS() *awsup.MockAWSCloud {
Name: aws.String("my-external-tg-3"),
})
mockIAM.CreateRole(&iam.CreateRoleInput{
RoleName: aws.String("kops-custom-node-role"),
})
mockIAM.CreateInstanceProfile(&iam.CreateInstanceProfileInput{
InstanceProfileName: aws.String("kops-custom-node-role"),
})
mockIAM.AddRoleToInstanceProfile(&iam.AddRoleToInstanceProfileInput{
InstanceProfileName: aws.String("kops-custom-node-role"),
RoleName: aws.String("kops-custom-node-role"),
})
return cloud
}

View File

@ -492,6 +492,7 @@ func (c *ApplyClusterCmd) Run(ctx context.Context) error {
tf := &TemplateFunctions{
KopsModelContext: *modelContext,
cloud: cloud,
}
{

View File

@ -1751,3 +1751,18 @@ func (c *awsCloudImplementation) AccountInfo() (string, string, error) {
}
return arn.AccountID, arn.Partition, nil
}
// GetRolesInInstanceProfile return role names which are associated with the instance profile specified by profileName.
func GetRolesInInstanceProfile(c AWSCloud, profileName string) ([]string, error) {
output, err := c.IAM().GetInstanceProfile(&iam.GetInstanceProfileInput{
InstanceProfileName: aws.String(profileName),
})
if err != nil {
return nil, err
}
var roleNames []string
for _, role := range output.InstanceProfile.Roles {
roleNames = append(roleNames, *role.RoleName)
}
return roleNames, nil
}

View File

@ -154,6 +154,7 @@ func runChannelBuilderTest(t *testing.T, key string, addonManifests []string) {
tf := &TemplateFunctions{
KopsModelContext: kopsModel,
cloud: cloud,
}
tf.AddTo(templates.TemplateFunctions, secretStore)

View File

@ -59,6 +59,8 @@ import (
// TemplateFunctions provides a collection of methods used throughout the templates
type TemplateFunctions struct {
model.KopsModelContext
cloud fi.Cloud
}
// AddTo defines the available functions we can use in our YAML models.
@ -445,9 +447,24 @@ func (tf *TemplateFunctions) KopsControllerConfig() (string, error) {
if ig.Spec.Role == kops.InstanceGroupRoleNode {
profile, err := tf.LinkToIAMInstanceProfile(ig)
if err != nil {
return "", fmt.Errorf("getting role for ig %s: %v", ig.Name, err)
return "", fmt.Errorf("getting profile for ig %s: %v", ig.Name, err)
}
// The IAM Instance Profile has not been created at this point if it is not specified.
// Because the IAM Instance Profile and the IAM Role are created in IAMModelBuilder tasks.
// Therefore, the IAM Role associated with IAM Instance Profile is acquired only when it is not specified.
if ig.Spec.IAM != nil && ig.Spec.IAM.Profile != nil {
c := tf.cloud.(awsup.AWSCloud)
roles, err := awsup.GetRolesInInstanceProfile(c, *profile.Name)
if err != nil {
return "", fmt.Errorf("getting role from profile %s: %v", *profile.Name, err)
}
nodesRoles.Insert(roles...)
} else {
// When the IAM Instance Profile is not specified, IAM Instance Profile is created by kOps.
// In this case, the IAM Instance Profile name and IAM Role name are same.
// So there is no problem even if IAM Instance Profile name is inserted as role name in nodesRoles.
nodesRoles.Insert(*profile.Name)
}
nodesRoles.Insert(*profile.Name)
}
}
config.Server.Provider.AWS = &awsup.AWSVerifierOptions{