From 2a7ab027f48d1fadc6c4a45f78918503527e85f4 Mon Sep 17 00:00:00 2001 From: Paul Stack Date: Tue, 21 Mar 2017 20:26:41 +0200 Subject: [PATCH] provider/aws: Only call replace Iam Instance Profile on existing (#12922) machines Fixes: #12898 The way aws_instance works is that we call the Create func then the Update func then the Read func. The way the work to implement the change to iam_instance_profile was added meant that when a machine was created with an iam_instance_profile, it would then try and update that iam_instance_profile because the state hadn't been updated at that point We have changed the Update func to only check for the change to iam_instance_profile when it *is an existing machine* - this will solve the problem of those bringing up new machines and getting hit with the permissions error As requested, added a test that adds an IAM Instance Profile from creation ``` % make testacc TEST=./builtin/providers/aws TESTARGS='-run=TestAccAWSInstance_withIamInstanceProfile' ==> Checking that code complies with gofmt requirements... go generate $(go list ./... | grep -v /terraform/vendor/) 2017/03/21 17:51:32 Generated command/internal_plugin_list.go TF_ACC=1 go test ./builtin/providers/aws -v -run=TestAccAWSInstance_withIamInstanceProfile -timeout 120m === RUN TestAccAWSInstance_withIamInstanceProfile --- PASS: TestAccAWSInstance_withIamInstanceProfile (154.29s) PASS ok github.com/hashicorp/terraform/builtin/providers/aws 154.325s ``` --- .../providers/aws/resource_aws_instance.go | 2 +- .../aws/resource_aws_instance_test.go | 35 +++++++++++++++++-- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/builtin/providers/aws/resource_aws_instance.go b/builtin/providers/aws/resource_aws_instance.go index e31baf5e8..65e348d34 100644 --- a/builtin/providers/aws/resource_aws_instance.go +++ b/builtin/providers/aws/resource_aws_instance.go @@ -611,7 +611,7 @@ func resourceAwsInstanceUpdate(d *schema.ResourceData, meta interface{}) error { d.SetPartial("tags") } - if d.HasChange("iam_instance_profile") { + if d.HasChange("iam_instance_profile") && !d.IsNewResource() { request := &ec2.DescribeIamInstanceProfileAssociationsInput{ Filters: []*ec2.Filter{ &ec2.Filter{ diff --git a/builtin/providers/aws/resource_aws_instance_test.go b/builtin/providers/aws/resource_aws_instance_test.go index f4ace2c44..2b835f6d7 100644 --- a/builtin/providers/aws/resource_aws_instance_test.go +++ b/builtin/providers/aws/resource_aws_instance_test.go @@ -656,7 +656,38 @@ func TestAccAWSInstance_instanceProfileChange(t *testing.T) { ), }, { - Config: testAccInstanceConfigAttachInstanceProfile(rName), + Config: testAccInstanceConfigWithInstanceProfile(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckInstanceExists("aws_instance.foo", &v), + testCheckInstanceProfile(), + ), + }, + }, + }) +} + +func TestAccAWSInstance_withIamInstanceProfile(t *testing.T) { + var v ec2.Instance + rName := acctest.RandString(5) + + testCheckInstanceProfile := func() resource.TestCheckFunc { + return func(*terraform.State) error { + if v.IamInstanceProfile == nil { + return fmt.Errorf("Instance Profile is nil - we expected an InstanceProfile associated with the Instance") + } + + return nil + } + } + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + IDRefreshName: "aws_instance.foo", + Providers: testAccProviders, + CheckDestroy: testAccCheckInstanceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccInstanceConfigWithInstanceProfile(rName), Check: resource.ComposeTestCheckFunc( testAccCheckInstanceExists("aws_instance.foo", &v), testCheckInstanceProfile(), @@ -1281,7 +1312,7 @@ resource "aws_instance" "foo" { }`, rName, rName) } -func testAccInstanceConfigAttachInstanceProfile(rName string) string { +func testAccInstanceConfigWithInstanceProfile(rName string) string { return fmt.Sprintf(` resource "aws_iam_role" "test" { name = "test-%s"