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
This commit is contained in:
Paul Hinze 2015-01-28 05:00:05 -06:00
parent c01f1a5ef0
commit c88c4a33e1
2 changed files with 20 additions and 7 deletions

View File

@ -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)

View File

@ -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(),
),
},