provider/aws: Fix issue with Root Block Devices and encrypted flag in Launch Configurations [GH-6512]

Fixed the problem where the root_block_device could cause an apply error
by reading back an "encrypted" parameter that was meant for an
ebs_block_device.  "encrypted" is not part of the root_block_device
schema, since it can't be set explicitly.

Added a check in Create to fail when the root device is incorrectly
specified as an ebs_block_device, as this causes continual refreshing
due to mismatched state between root_block_device and ebs_block_device.

"encrypted" and "snapshot_id" should be guarded with ConflictsWith, but
that doesn't appear to work on nested resources despite #1926.
This commit is contained in:
Paul Forman 2016-06-08 14:56:27 -06:00 committed by Clint
parent c667b2d8cd
commit 391a7f85b0
1 changed files with 20 additions and 4 deletions

View File

@ -331,6 +331,17 @@ func resourceAwsLaunchConfigurationCreate(d *schema.ResourceData, meta interface
var blockDevices []*autoscaling.BlockDeviceMapping var blockDevices []*autoscaling.BlockDeviceMapping
// We'll use this to detect if we're declaring it incorrectly as an ebs_block_device.
rootDeviceName, err := fetchRootDeviceName(d.Get("image_id").(string), ec2conn)
if err != nil {
return err
}
if rootDeviceName == nil {
// We do this so the value is empty so we don't have to do nil checks later
var blank string
rootDeviceName = &blank
}
if v, ok := d.GetOk("ebs_block_device"); ok { if v, ok := d.GetOk("ebs_block_device"); ok {
vL := v.(*schema.Set).List() vL := v.(*schema.Set).List()
for _, v := range vL { for _, v := range vL {
@ -359,6 +370,10 @@ func resourceAwsLaunchConfigurationCreate(d *schema.ResourceData, meta interface
ebs.Iops = aws.Int64(int64(v)) ebs.Iops = aws.Int64(int64(v))
} }
if *aws.String(bd["device_name"].(string)) == *rootDeviceName {
return fmt.Errorf("Root device (%s) declared as an 'ebs_block_device'. Use 'root_block_device' keyword.", *rootDeviceName)
}
blockDevices = append(blockDevices, &autoscaling.BlockDeviceMapping{ blockDevices = append(blockDevices, &autoscaling.BlockDeviceMapping{
DeviceName: aws.String(bd["device_name"].(string)), DeviceName: aws.String(bd["device_name"].(string)),
Ebs: ebs, Ebs: ebs,
@ -435,7 +450,7 @@ func resourceAwsLaunchConfigurationCreate(d *schema.ResourceData, meta interface
// IAM profiles can take ~10 seconds to propagate in AWS: // IAM profiles can take ~10 seconds to propagate in AWS:
// http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html#launch-instance-with-role-console // http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html#launch-instance-with-role-console
err := resource.Retry(30*time.Second, func() *resource.RetryError { err = resource.Retry(30*time.Second, func() *resource.RetryError {
_, err := autoscalingconn.CreateLaunchConfiguration(&createLaunchConfigurationOpts) _, err := autoscalingconn.CreateLaunchConfiguration(&createLaunchConfigurationOpts)
if err != nil { if err != nil {
if awsErr, ok := err.(awserr.Error); ok { if awsErr, ok := err.(awserr.Error); ok {
@ -587,12 +602,13 @@ func readBlockDevicesFromLaunchConfiguration(d *schema.ResourceData, lc *autosca
if bdm.Ebs != nil && bdm.Ebs.Iops != nil { if bdm.Ebs != nil && bdm.Ebs.Iops != nil {
bd["iops"] = *bdm.Ebs.Iops bd["iops"] = *bdm.Ebs.Iops
} }
if bdm.Ebs != nil && bdm.Ebs.Encrypted != nil {
bd["encrypted"] = *bdm.Ebs.Encrypted
}
if bdm.DeviceName != nil && *bdm.DeviceName == *rootDeviceName { if bdm.DeviceName != nil && *bdm.DeviceName == *rootDeviceName {
blockDevices["root"] = bd blockDevices["root"] = bd
} else { } else {
if bdm.Ebs != nil && bdm.Ebs.Encrypted != nil {
bd["encrypted"] = *bdm.Ebs.Encrypted
}
if bdm.DeviceName != nil { if bdm.DeviceName != nil {
bd["device_name"] = *bdm.DeviceName bd["device_name"] = *bdm.DeviceName
} }