diff --git a/.changelog/16325.txt b/.changelog/16325.txt new file mode 100644 index 000000000000..0f375a56b0b4 --- /dev/null +++ b/.changelog/16325.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/aws_autoscaling_group: Added support Auto Scaling groups with multiple launch templates using a mixed instances policy +``` \ No newline at end of file diff --git a/aws/resource_aws_autoscaling_group.go b/aws/resource_aws_autoscaling_group.go index 23550037f161..fe0d98e4930b 100644 --- a/aws/resource_aws_autoscaling_group.go +++ b/aws/resource_aws_autoscaling_group.go @@ -194,6 +194,31 @@ func resourceAwsAutoscalingGroup() *schema.Resource { Type: schema.TypeString, Optional: true, }, + "launch_template_specification": { + Type: schema.TypeList, + Optional: true, + MinItems: 0, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "launch_template_id": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "launch_template_name": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "version": { + Type: schema.TypeString, + Optional: true, + Default: "$Default", + }, + }, + }, + }, "weighted_capacity": { Type: schema.TypeString, Optional: true, @@ -1678,6 +1703,10 @@ func expandAutoScalingLaunchTemplateOverride(m map[string]interface{}) *autoscal launchTemplateOverrides.InstanceType = aws.String(v.(string)) } + if v, ok := m["launch_template_specification"]; ok && v.([]interface{}) != nil { + launchTemplateOverrides.LaunchTemplateSpecification = expandAutoScalingLaunchTemplateSpecification(m["launch_template_specification"].([]interface{})) + } + if v, ok := m["weighted_capacity"]; ok && v.(string) != "" { launchTemplateOverrides.WeightedCapacity = aws.String(v.(string)) } @@ -1769,8 +1798,9 @@ func flattenAutoScalingLaunchTemplateOverrides(launchTemplateOverrides []*autosc continue } m := map[string]interface{}{ - "instance_type": aws.StringValue(launchTemplateOverride.InstanceType), - "weighted_capacity": aws.StringValue(launchTemplateOverride.WeightedCapacity), + "instance_type": aws.StringValue(launchTemplateOverride.InstanceType), + "launch_template_specification": flattenAutoScalingLaunchTemplateSpecification(launchTemplateOverride.LaunchTemplateSpecification), + "weighted_capacity": aws.StringValue(launchTemplateOverride.WeightedCapacity), } l[i] = m } diff --git a/aws/resource_aws_autoscaling_group_test.go b/aws/resource_aws_autoscaling_group_test.go index 41aa98811408..121dcd95a2c3 100644 --- a/aws/resource_aws_autoscaling_group_test.go +++ b/aws/resource_aws_autoscaling_group_test.go @@ -2166,6 +2166,48 @@ func TestAccAWSAutoScalingGroup_MixedInstancesPolicy_LaunchTemplate_Override_Ins }) } +func TestAccAWSAutoScalingGroup_MixedInstancesPolicy_LaunchTemplate_Override_InstanceType_With_LaunchTemplateSpecification(t *testing.T) { + var group autoscaling.Group + resourceName := "aws_autoscaling_group.test" + rName := acctest.RandomWithPrefix("tf-acc-test") + rName2 := acctest.RandomWithPrefix("tf-acc-test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSAutoScalingGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSAutoScalingGroupConfig_MixedInstancesPolicy_LaunchTemplate_Override_InstanceType_With_LaunchTemplateSpecification(rName, rName2), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSAutoScalingGroupExists(resourceName, &group), + resource.TestCheckResourceAttr(resourceName, "mixed_instances_policy.#", "1"), + resource.TestCheckResourceAttr(resourceName, "mixed_instances_policy.0.launch_template.#", "1"), + resource.TestCheckResourceAttr(resourceName, "mixed_instances_policy.0.launch_template.0.override.#", "2"), + resource.TestCheckResourceAttr(resourceName, "mixed_instances_policy.0.launch_template.0.override.0.instance_type", "t2.micro"), + resource.TestCheckNoResourceAttr(resourceName, "mixed_instances_policy.0.launch_template.0.override.0.launch_template_specification.#"), + resource.TestCheckResourceAttr(resourceName, "mixed_instances_policy.0.launch_template.0.override.1.instance_type", "t4g.micro"), + resource.TestCheckResourceAttrPair(resourceName, "mixed_instances_policy.0.launch_template.0.override.1.launch_template_specification.0.launch_template_id", "aws_launch_template.testarm", "id"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "force_delete", + "initial_lifecycle_hook", + "name_prefix", + "tag", + "tags", + "wait_for_capacity_timeout", + "wait_for_elb_capacity", + }, + }, + }, + }) +} + func TestAccAWSAutoScalingGroup_MixedInstancesPolicy_LaunchTemplate_Override_WeightedCapacity(t *testing.T) { var group autoscaling.Group resourceName := "aws_autoscaling_group.test" @@ -3938,6 +3980,26 @@ resource "aws_launch_template" "test" { `, rName) } +func testAccAWSAutoScalingGroupConfig_MixedInstancesPolicy_Arm_Base(rName string) string { + return fmt.Sprintf(` +data "aws_ami" "testarm" { + most_recent = true + owners = ["amazon"] + + filter { + name = "name" + values = ["amzn2-ami-hvm-*-arm64-gp2"] + } +} + +resource "aws_launch_template" "testarm" { + image_id = data.aws_ami.testarm.id + instance_type = "t4g.micro" + name = %q +} +`, rName) +} + func testAccAWSAutoScalingGroupConfig_MixedInstancesPolicy(rName string) string { return testAccAWSAutoScalingGroupConfig_MixedInstancesPolicy_Base(rName) + fmt.Sprintf(` @@ -4276,6 +4338,39 @@ resource "aws_autoscaling_group" "test" { `, rName, instanceType) } +func testAccAWSAutoScalingGroupConfig_MixedInstancesPolicy_LaunchTemplate_Override_InstanceType_With_LaunchTemplateSpecification(rName, rName2 string) string { + return testAccAWSAutoScalingGroupConfig_MixedInstancesPolicy_Base(rName) + + testAccAWSAutoScalingGroupConfig_MixedInstancesPolicy_Arm_Base(rName2) + + fmt.Sprintf(` + +resource "aws_autoscaling_group" "test" { + availability_zones = [data.aws_availability_zones.available.names[0]] + desired_capacity = 0 + max_size = 0 + min_size = 0 + name = %q + + mixed_instances_policy { + launch_template { + launch_template_specification { + launch_template_id = aws_launch_template.test.id + } + + override { + instance_type = "t2.micro" + } + override { + instance_type = "t4g.micro" + launch_template_specification { + launch_template_id = aws_launch_template.testarm.id + } + } + } + } +} +`, rName) +} + func testAccAWSAutoScalingGroupConfig_MixedInstancesPolicy_LaunchTemplate_Override_WeightedCapacity(rName string) string { return testAccAWSAutoScalingGroupConfig_MixedInstancesPolicy_Base(rName) + fmt.Sprintf(` diff --git a/website/docs/r/autoscaling_group.html.markdown b/website/docs/r/autoscaling_group.html.markdown index 2e0354080da2..d9bd775984bc 100644 --- a/website/docs/r/autoscaling_group.html.markdown +++ b/website/docs/r/autoscaling_group.html.markdown @@ -174,6 +174,51 @@ resource "aws_autoscaling_group" "example" { } ``` +### Mixed Instances Policy with Instance level LaunchTemplateSpecification Overrides + +When using a diverse instance set, some instance types might require a launch template with configuration values unique to that instance type such as a different AMI (Graviton2), architecture specific user data script, different EBS configuration, or different networking configuration. + +```hcl +resource "aws_launch_template" "example" { + name_prefix = "example" + image_id = data.aws_ami.example.id + instance_type = "c5.large" +} + +resource "aws_launch_template" "example2" { + name_prefix = "example2" + image_id = data.aws_ami.example2.id +} + +resource "aws_autoscaling_group" "example" { + availability_zones = ["us-east-1a"] + desired_capacity = 1 + max_size = 1 + min_size = 1 + + mixed_instances_policy { + launch_template { + launch_template_specification { + launch_template_id = aws_launch_template.example.id + } + + override { + instance_type = "c4.large" + weighted_capacity = "3" + } + + override { + instance_type = "c6g.large" + launch_template_specification { + launch_template_id = aws_launch_template.example2.id + } + weighted_capacity = "2" + } + } + } +} +``` + ### Interpolated tags ```hcl @@ -378,6 +423,7 @@ This configuration block supports the following: This configuration block supports the following: * `instance_type` - (Optional) Override the instance type in the Launch Template. +* `launch_template_specification` - (Optional) Override the instance launch template specification in the Launch Template. * `weighted_capacity` - (Optional) The number of capacity units, which gives the instance type a proportional weight to other instance types. ### tag and tags