diff --git a/aws/resource_aws_launch_template.go b/aws/resource_aws_launch_template.go index 1ab156c58af..ca1fb2d662b 100644 --- a/aws/resource_aws_launch_template.go +++ b/aws/resource_aws_launch_template.go @@ -159,8 +159,14 @@ func resourceAwsLaunchTemplate() *schema.Resource { }, "ebs_optimized": { - Type: schema.TypeBool, - Optional: true, + // Use TypeString to allow an "unspecified" value, + // since TypeBool only has true/false with false default. + // The conversion from bare true/false values in + // configurations to TypeString value is currently safe. + Type: schema.TypeString, + Optional: true, + DiffSuppressFunc: suppressEquivalentTypeStringBoolean, + ValidateFunc: validateTypeStringNullableBoolean, }, "elastic_gpu_specifications": { @@ -538,7 +544,6 @@ func resourceAwsLaunchTemplateRead(d *schema.ResourceData, meta interface{}) err ltData := dltv.LaunchTemplateVersions[0].LaunchTemplateData d.Set("disable_api_termination", ltData.DisableApiTermination) - d.Set("ebs_optimized", ltData.EbsOptimized) d.Set("image_id", ltData.ImageId) d.Set("instance_initiated_shutdown_behavior", ltData.InstanceInitiatedShutdownBehavior) d.Set("instance_type", ltData.InstanceType) @@ -548,6 +553,11 @@ func resourceAwsLaunchTemplateRead(d *schema.ResourceData, meta interface{}) err d.Set("security_group_names", aws.StringValueSlice(ltData.SecurityGroups)) d.Set("user_data", ltData.UserData) d.Set("vpc_security_group_ids", aws.StringValueSlice(ltData.SecurityGroupIds)) + d.Set("ebs_optimized", "") + + if ltData.EbsOptimized != nil { + d.Set("ebs_optimized", strconv.FormatBool(aws.BoolValue(ltData.EbsOptimized))) + } if err := d.Set("block_device_mappings", getBlockDeviceMappings(ltData.BlockDeviceMappings)); err != nil { return err @@ -856,8 +866,12 @@ func buildLaunchTemplateData(d *schema.ResourceData, meta interface{}) (*ec2.Req opts.DisableApiTermination = aws.Bool(v.(bool)) } - if v, ok := d.GetOk("ebs_optimized"); ok { - opts.EbsOptimized = aws.Bool(v.(bool)) + if v, ok := d.GetOk("ebs_optimized"); ok && v.(string) != "" { + vBool, err := strconv.ParseBool(v.(string)) + if err != nil { + return nil, fmt.Errorf("error converting ebs_optimized %q from string to boolean: %s", v.(string), err) + } + opts.EbsOptimized = aws.Bool(vBool) } if v, ok := d.GetOk("security_group_names"); ok { diff --git a/aws/resource_aws_launch_template_test.go b/aws/resource_aws_launch_template_test.go index bb9c6bc4c3e..c151c15e709 100644 --- a/aws/resource_aws_launch_template_test.go +++ b/aws/resource_aws_launch_template_test.go @@ -29,6 +29,7 @@ func TestAccAWSLaunchTemplate_basic(t *testing.T) { resource.TestCheckResourceAttr(resName, "default_version", "1"), resource.TestCheckResourceAttr(resName, "latest_version", "1"), resource.TestCheckResourceAttrSet(resName, "arn"), + resource.TestCheckResourceAttr(resName, "ebs_optimized", ""), ), }, }, @@ -122,6 +123,7 @@ func TestAccAWSLaunchTemplate_data(t *testing.T) { resource.TestCheckResourceAttr(resName, "block_device_mappings.#", "1"), resource.TestCheckResourceAttr(resName, "credit_specification.#", "1"), resource.TestCheckResourceAttrSet(resName, "disable_api_termination"), + resource.TestCheckResourceAttr(resName, "ebs_optimized", "false"), resource.TestCheckResourceAttr(resName, "elastic_gpu_specifications.#", "1"), resource.TestCheckResourceAttr(resName, "iam_instance_profile.#", "1"), resource.TestCheckResourceAttrSet(resName, "image_id"), @@ -431,7 +433,7 @@ resource "aws_launch_template" "foo" { disable_api_termination = true - ebs_optimized = true + ebs_optimized = false elastic_gpu_specifications { type = "test"