From eca03a37eef7cf8d22b8c6abc903b92f2f007a0b Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Thu, 18 Jan 2018 11:17:15 -0500 Subject: [PATCH 1/2] resource/aws_instance: Retry IAM instance profile (re)association for eventual consistency on update --- aws/resource_aws_instance.go | 38 +++++++++++++++++++++++-------- aws/resource_aws_instance_test.go | 7 +----- 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/aws/resource_aws_instance.go b/aws/resource_aws_instance.go index 52e088e2c8e..b2f32997358 100644 --- a/aws/resource_aws_instance.go +++ b/aws/resource_aws_instance.go @@ -822,11 +822,20 @@ func resourceAwsInstanceUpdate(d *schema.ResourceData, meta interface{}) error { if _, ok := d.GetOk("iam_instance_profile"); ok { // Does not have an Iam Instance Profile associated with it, need to associate if len(resp.IamInstanceProfileAssociations) == 0 { - _, err := conn.AssociateIamInstanceProfile(&ec2.AssociateIamInstanceProfileInput{ - InstanceId: aws.String(d.Id()), - IamInstanceProfile: &ec2.IamInstanceProfileSpecification{ - Name: aws.String(d.Get("iam_instance_profile").(string)), - }, + err := resource.Retry(2*time.Minute, func() *resource.RetryError { + _, err := conn.AssociateIamInstanceProfile(&ec2.AssociateIamInstanceProfileInput{ + InstanceId: aws.String(d.Id()), + IamInstanceProfile: &ec2.IamInstanceProfileSpecification{ + Name: aws.String(d.Get("iam_instance_profile").(string)), + }, + }) + if err != nil { + if isAWSErr(err, "InvalidParameterValue", "Invalid IAM Instance Profile") { + return resource.RetryableError(err) + } + return resource.NonRetryableError(err) + } + return nil }) if err != nil { return err @@ -836,11 +845,20 @@ func resourceAwsInstanceUpdate(d *schema.ResourceData, meta interface{}) error { // Has an Iam Instance Profile associated with it, need to replace the association associationId := resp.IamInstanceProfileAssociations[0].AssociationId - _, err := conn.ReplaceIamInstanceProfileAssociation(&ec2.ReplaceIamInstanceProfileAssociationInput{ - AssociationId: associationId, - IamInstanceProfile: &ec2.IamInstanceProfileSpecification{ - Name: aws.String(d.Get("iam_instance_profile").(string)), - }, + err := resource.Retry(2*time.Minute, func() *resource.RetryError { + _, err := conn.ReplaceIamInstanceProfileAssociation(&ec2.ReplaceIamInstanceProfileAssociationInput{ + AssociationId: associationId, + IamInstanceProfile: &ec2.IamInstanceProfileSpecification{ + Name: aws.String(d.Get("iam_instance_profile").(string)), + }, + }) + if err != nil { + if isAWSErr(err, "InvalidParameterValue", "Invalid IAM Instance Profile") { + return resource.RetryableError(err) + } + return resource.NonRetryableError(err) + } + return nil }) if err != nil { return err diff --git a/aws/resource_aws_instance_test.go b/aws/resource_aws_instance_test.go index 0c9f9e52a99..f2632c2929d 100644 --- a/aws/resource_aws_instance_test.go +++ b/aws/resource_aws_instance_test.go @@ -2072,18 +2072,13 @@ resource "aws_iam_role" "test" { assume_role_policy = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"Service\":[\"ec2.amazonaws.com\"]},\"Action\":[\"sts:AssumeRole\"]}]}" } -resource "aws_iam_instance_profile" "test" { - name = "test-%s" - roles = ["${aws_iam_role.test.name}"] -} - resource "aws_instance" "foo" { ami = "ami-4fccb37f" instance_type = "m1.small" tags { bar = "baz" } -}`, rName, rName) +}`, rName) } func testAccInstanceConfigWithInstanceProfile(rName string) string { From 6ca1a85bdf0232f527ade24eb4a50852802f7205 Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Thu, 18 Jan 2018 12:06:44 -0500 Subject: [PATCH 2/2] resource/aws_instance: Lower IAM instance profile retry timeout from 2 minutes to 1 minute initially Generally we would prefer to surface actual IAM issues (bad profile, etc.) sooner rather than later. --- aws/resource_aws_instance.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aws/resource_aws_instance.go b/aws/resource_aws_instance.go index b2f32997358..29024e1ebc5 100644 --- a/aws/resource_aws_instance.go +++ b/aws/resource_aws_instance.go @@ -822,7 +822,7 @@ func resourceAwsInstanceUpdate(d *schema.ResourceData, meta interface{}) error { if _, ok := d.GetOk("iam_instance_profile"); ok { // Does not have an Iam Instance Profile associated with it, need to associate if len(resp.IamInstanceProfileAssociations) == 0 { - err := resource.Retry(2*time.Minute, func() *resource.RetryError { + err := resource.Retry(1*time.Minute, func() *resource.RetryError { _, err := conn.AssociateIamInstanceProfile(&ec2.AssociateIamInstanceProfileInput{ InstanceId: aws.String(d.Id()), IamInstanceProfile: &ec2.IamInstanceProfileSpecification{ @@ -845,7 +845,7 @@ func resourceAwsInstanceUpdate(d *schema.ResourceData, meta interface{}) error { // Has an Iam Instance Profile associated with it, need to replace the association associationId := resp.IamInstanceProfileAssociations[0].AssociationId - err := resource.Retry(2*time.Minute, func() *resource.RetryError { + err := resource.Retry(1*time.Minute, func() *resource.RetryError { _, err := conn.ReplaceIamInstanceProfileAssociation(&ec2.ReplaceIamInstanceProfileAssociationInput{ AssociationId: associationId, IamInstanceProfile: &ec2.IamInstanceProfileSpecification{