From c88c4a33e1fbea77fa32ecbed4bf15f63483f2eb Mon Sep 17 00:00:00 2001 From: Paul Hinze Date: Wed, 28 Jan 2015 05:00:05 -0600 Subject: [PATCH] providers/aws: ignore ec2 root devices fixes #859 EC2 root block devices are attached automatically at launch [1] and show up in DescribeInstances responses from then on. By skipping these when recording state, Terraform can avoid thinking there should be block device changes when there are none. Note this requires that https://github.com/mitchellh/goamz/pull/214 land first so the proper field is exposed. [1] http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/RootDeviceStorage.html --- .../providers/aws/resource_aws_instance.go | 22 +++++++++++++------ .../aws/resource_aws_instance_test.go | 5 +++++ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/builtin/providers/aws/resource_aws_instance.go b/builtin/providers/aws/resource_aws_instance.go index 01e42b0c6..35402ba80 100644 --- a/builtin/providers/aws/resource_aws_instance.go +++ b/builtin/providers/aws/resource_aws_instance.go @@ -377,11 +377,19 @@ func resourceAwsInstanceRead(d *schema.ResourceData, meta interface{}) error { } d.Set("security_groups", sgs) - volIDs := make([]string, len(instance.BlockDevices)) - bdByVolID := make(map[string]ec2.BlockDevice) - for i, bd := range instance.BlockDevices { - volIDs[i] = bd.VolumeId - bdByVolID[bd.VolumeId] = bd + blockDevices := make(map[string]ec2.BlockDevice) + for _, bd := range instance.BlockDevices { + // Skip root device; AWS attaches it automatically and terraform does not + // manage it + if bd.DeviceName == instance.RootDeviceName { + continue + } + blockDevices[bd.VolumeId] = bd + } + + volIDs := make([]string, 0, len(blockDevices)) + for volID := range blockDevices { + volIDs = append(volIDs, volID) } volResp, err := ec2conn.Volumes(volIDs, ec2.NewFilter()) @@ -396,11 +404,11 @@ func resourceAwsInstanceRead(d *schema.ResourceData, meta interface{}) error { return err } bds[i] = make(map[string]interface{}) - bds[i]["device_name"] = bdByVolID[vol.VolumeId].DeviceName + bds[i]["device_name"] = blockDevices[vol.VolumeId].DeviceName bds[i]["snapshot_id"] = vol.SnapshotId bds[i]["volume_type"] = vol.VolumeType bds[i]["volume_size"] = volSize - bds[i]["delete_on_termination"] = bdByVolID[vol.VolumeId].DeleteOnTermination + bds[i]["delete_on_termination"] = blockDevices[vol.VolumeId].DeleteOnTermination bds[i]["encrypted"] = vol.Encrypted } d.Set("block_device", bds) diff --git a/builtin/providers/aws/resource_aws_instance_test.go b/builtin/providers/aws/resource_aws_instance_test.go index cdf3554d4..60afe27e3 100644 --- a/builtin/providers/aws/resource_aws_instance_test.go +++ b/builtin/providers/aws/resource_aws_instance_test.go @@ -97,6 +97,11 @@ func TestAccAWSInstance_blockDevicesCheck(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckInstanceExists( "aws_instance.foo", &v), + // though two block devices exist in EC2, terraform state should only + // have the one block device we created, as terraform does not manage + // the root device + resource.TestCheckResourceAttr( + "aws_instance.foo", "block_device.#", "1"), testCheck(), ), },