From acfc9157c56b019992d775edf4b0e5dec8526db8 Mon Sep 17 00:00:00 2001 From: Joakim Bomelin Date: Fri, 5 Oct 2018 15:19:15 +0200 Subject: [PATCH 1/2] Add Retry to instanceProfileAddRole to handle IAM's eventual consistency --- aws/resource_aws_iam_instance_profile.go | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/aws/resource_aws_iam_instance_profile.go b/aws/resource_aws_iam_instance_profile.go index 070614cb212..f2a5282fee6 100644 --- a/aws/resource_aws_iam_instance_profile.go +++ b/aws/resource_aws_iam_instance_profile.go @@ -160,7 +160,23 @@ func instanceProfileAddRole(iamconn *iam.IAM, profileName, roleName string) erro RoleName: aws.String(roleName), } - _, err := iamconn.AddRoleToInstanceProfile(request) + var createResp *iam.AddRoleToInstanceProfileOutput + err := resource.Retry(30*time.Second, func() *resource.RetryError { + var err error + createResp, err = iamconn.AddRoleToInstanceProfile(request) + + // Todo: handle retryable and non-retryable errors + // if isAWSErr(err, "MalformedPolicyDocument", "Invalid principal in policy") { + // return resource.RetryableError(err) + // } + //return resource.NonRetryableError(err) + + return resource.RetryableError(err) + }) + if err != nil { + return fmt.Errorf("Error adding IAM Role %s to Instance Profile %s: %s", roleName, profileName, err) + } + return err } From c72089459c1452dc39e9e70d12f41aa47ef83d3b Mon Sep 17 00:00:00 2001 From: Joakim Bomelin Date: Fri, 5 Oct 2018 15:19:15 +0200 Subject: [PATCH 2/2] Add Retry to instanceProfileAddRole to handle IAM's eventual consistency --- aws/resource_aws_iam_instance_profile.go | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/aws/resource_aws_iam_instance_profile.go b/aws/resource_aws_iam_instance_profile.go index f2a5282fee6..7414ddd29da 100644 --- a/aws/resource_aws_iam_instance_profile.go +++ b/aws/resource_aws_iam_instance_profile.go @@ -160,18 +160,19 @@ func instanceProfileAddRole(iamconn *iam.IAM, profileName, roleName string) erro RoleName: aws.String(roleName), } - var createResp *iam.AddRoleToInstanceProfileOutput err := resource.Retry(30*time.Second, func() *resource.RetryError { var err error - createResp, err = iamconn.AddRoleToInstanceProfile(request) - - // Todo: handle retryable and non-retryable errors - // if isAWSErr(err, "MalformedPolicyDocument", "Invalid principal in policy") { - // return resource.RetryableError(err) - // } - //return resource.NonRetryableError(err) - - return resource.RetryableError(err) + _, err = iamconn.AddRoleToInstanceProfile(request) + // IAM unfortunately does not provide a better error code or message for eventual consistency + // InvalidParameterValue: Value (XXX) for parameter iamInstanceProfile.name is invalid. Invalid IAM Instance Profile name + // NoSuchEntity: The request was rejected because it referenced an entity that does not exist. The error message describes the entity. HTTP Status Code: 404 + if isAWSErr(err, "InvalidParameterValue", "Invalid IAM Instance Profile name") || isAWSErr(err, "NoSuchEntity", "The role with name") { + return resource.RetryableError(err) + } + if err != nil { + return resource.NonRetryableError(err) + } + return nil }) if err != nil { return fmt.Errorf("Error adding IAM Role %s to Instance Profile %s: %s", roleName, profileName, err)