Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix aws_autoscaling_group to handle launch template name change #34027

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changelog/34027.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:bug
resource/aws_autoscaling_group: Update launch template related attributes when there is change in launch template name
```
64 changes: 61 additions & 3 deletions internal/service/autoscaling/group.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import ( // nosemgrep:ci.semgrep.aws.multiple-service-imports
"errors"
"fmt"
"log"
"reflect"
"strconv"
"strings"
"time"
Expand Down Expand Up @@ -1274,7 +1275,8 @@ func resourceGroupUpdate(ctx context.Context, d *schema.ResourceData, meta inter

if d.HasChange("launch_template") {
if v, ok := d.GetOk("launch_template"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil {
input.LaunchTemplate = expandLaunchTemplateSpecification(v.([]interface{})[0].(map[string]interface{}))
tfMap := removeIdIfNameChanged(v.([]interface{})[0].(map[string]interface{}), d.HasChange("launch_template.0.name"), "name", "id", "")
input.LaunchTemplate = expandLaunchTemplateSpecification(tfMap)
}
shouldRefreshInstances = true
}
Expand All @@ -1294,7 +1296,23 @@ func resourceGroupUpdate(ctx context.Context, d *schema.ResourceData, meta inter

if d.HasChange("mixed_instances_policy") {
if v, ok := d.GetOk("mixed_instances_policy"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil {
input.MixedInstancesPolicy = expandMixedInstancesPolicy(v.([]interface{})[0].(map[string]interface{}))
tfMap := removeIdIfNameChanged(v.([]interface{})[0].(map[string]interface{}),
d.HasChange("mixed_instances_policy.0.launch_template.0.launch_template_specification.0.launch_template_name"),
"launch_template_name", "launch_template_id", "launch_template.0.launch_template_specification.0")

if d.HasChange("mixed_instances_policy.0.launch_template.0.override") {
if v, ok := d.GetOk("mixed_instances_policy.0.launch_template.0.override"); ok && len(v.([]interface{})) > 0 {
for i, v := range v.([]interface{}) {
overrideMap := v.(map[string]interface{})
if v, ok := overrideMap["launch_template_specification"]; ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil {
removeIdIfNameChanged(overrideMap,
d.HasChange("mixed_instances_policy.0.launch_template.0.override."+strconv.Itoa(i)+".launch_template_specification.0.launch_template_name"),
"launch_template_name", "launch_template_id", "launch_template_specification.0")
}
}
}
}
input.MixedInstancesPolicy = expandMixedInstancesPolicy(tfMap)
}
shouldRefreshInstances = true
}
Expand Down Expand Up @@ -1493,7 +1511,8 @@ func resourceGroupUpdate(ctx context.Context, d *schema.ResourceData, meta inter
var launchTemplate *autoscaling.LaunchTemplateSpecification

if v, ok := d.GetOk("launch_template"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil {
launchTemplate = expandLaunchTemplateSpecification(v.([]interface{})[0].(map[string]interface{}))
tfMap := removeIdIfNameChanged(v.([]interface{})[0].(map[string]interface{}), d.HasChange("launch_template.0.name"), "name", "id", "")
launchTemplate = expandLaunchTemplateSpecification(tfMap)
}

var mixedInstancesPolicy *autoscaling.MixedInstancesPolicy
Expand Down Expand Up @@ -3933,3 +3952,42 @@ func validateGroupInstanceRefreshTriggerFields(i interface{}, path cty.Path) dia

return diag.Errorf("'%s' is not a recognized parameter name for aws_autoscaling_group", v)
}

func removeIdIfNameChanged(tfMap map[string]interface{}, changed bool, nameKey, idKey, address string) map[string]interface{} {
if !changed {
return tfMap
}
paths := strings.Split(address, ".")
var nestedResource interface{} = tfMap
if len(paths) > 0 {
nestedResource = extractNestedResource(paths, nestedResource)
}
resourceMap := nestedResource.(map[string]interface{})
// Remove ID if there are changes in name or else ID will be preferred.
if v, ok := resourceMap[nameKey]; ok && v != "" {
delete(resourceMap, idKey)
}
return tfMap
}

func extractNestedResource(paths []string, resource interface{}) interface{} {
for _, path := range paths {
if v, err := strconv.Atoi(path); err == nil {
// Path is index for list
val := reflect.ValueOf(resource)
if val.Len() > v {
resource = val.Index(v).Interface()
} else {
break
}
} else {
// Path is key for map
if v, ok := resource.(map[string]interface{})[path]; ok {
resource = v
} else {
break
}
}
}
return resource
}
57 changes: 47 additions & 10 deletions internal/service/autoscaling/group_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1127,7 +1127,7 @@ func TestAccAutoScalingGroup_LaunchTemplate_update(t *testing.T) {
),
},
{
Config: testAccGroupConfig_launchTemplateName(rName),
Config: testAccGroupConfig_launchTemplateName(rName, rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckGroupExists(ctx, resourceName, &group),
resource.TestCheckResourceAttr(resourceName, "launch_configuration", ""),
Expand All @@ -1137,6 +1137,18 @@ func TestAccAutoScalingGroup_LaunchTemplate_update(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "launch_template.0.version", ""),
),
},
{
Config: testAccGroupConfig_launchTemplateName(rName, rName+"-name-change"),
Check: resource.ComposeTestCheckFunc(
testAccCheckGroupExists(ctx, resourceName, &group),
resource.TestCheckResourceAttr(resourceName, "launch_configuration", ""),
resource.TestCheckResourceAttr(resourceName, "launch_template.#", "1"),
resource.TestCheckResourceAttr(resourceName, "launch_template.0.name", rName+"-name-change"),
resource.TestCheckResourceAttrPair(resourceName, "launch_template.0.id", "aws_launch_template.test", "id"),
resource.TestCheckResourceAttrPair(resourceName, "launch_template.0.name", "aws_launch_template.test", "name"),
resource.TestCheckResourceAttr(resourceName, "launch_template.0.version", ""),
),
},
{
Config: testAccGroupConfig_launchTemplateLatestVersion(rName),
Check: resource.ComposeTestCheckFunc(
Expand Down Expand Up @@ -1982,7 +1994,7 @@ func TestAccAutoScalingGroup_MixedInstancesPolicyLaunchTemplateLaunchTemplateSpe
CheckDestroy: testAccCheckGroupDestroy(ctx),
Steps: []resource.TestStep{
{
Config: testAccGroupConfig_mixedInstancesPolicyLaunchTemplateLaunchTemplateSpecificationLaunchTemplateName(rName),
Config: testAccGroupConfig_mixedInstancesPolicyLaunchTemplateLaunchTemplateSpecificationLaunchTemplateName(rName, rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckGroupExists(ctx, resourceName, &group),
resource.TestCheckResourceAttr(resourceName, "mixed_instances_policy.#", "1"),
Expand All @@ -1991,6 +2003,17 @@ func TestAccAutoScalingGroup_MixedInstancesPolicyLaunchTemplateLaunchTemplateSpe
resource.TestCheckResourceAttrSet(resourceName, "mixed_instances_policy.0.launch_template.0.launch_template_specification.0.launch_template_name"),
),
},
{
Config: testAccGroupConfig_mixedInstancesPolicyLaunchTemplateLaunchTemplateSpecificationLaunchTemplateName(rName, rName+"-name-change"),
Check: resource.ComposeTestCheckFunc(
testAccCheckGroupExists(ctx, 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.launch_template_specification.#", "1"),
resource.TestCheckResourceAttrSet(resourceName, "mixed_instances_policy.0.launch_template.0.launch_template_specification.0.launch_template_name"),
resource.TestCheckResourceAttr(resourceName, "mixed_instances_policy.0.launch_template.0.launch_template_specification.0.launch_template_name", rName+"-name-change"),
),
},
testAccGroupImportStep(resourceName),
},
})
Expand Down Expand Up @@ -2085,7 +2108,7 @@ func TestAccAutoScalingGroup_MixedInstancesPolicyLaunchTemplateOverride_instance
CheckDestroy: testAccCheckGroupDestroy(ctx),
Steps: []resource.TestStep{
{
Config: testAccGroupConfig_mixedInstancesPolicyLaunchTemplateOverrideInstanceTypeLaunchTemplateSpecification(rName),
Config: testAccGroupConfig_mixedInstancesPolicyLaunchTemplateOverrideInstanceTypeLaunchTemplateSpecification(rName, rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckGroupExists(ctx, resourceName, &group),
resource.TestCheckResourceAttr(resourceName, "mixed_instances_policy.#", "1"),
Expand All @@ -2097,6 +2120,20 @@ func TestAccAutoScalingGroup_MixedInstancesPolicyLaunchTemplateOverride_instance
resource.TestCheckResourceAttrPair(resourceName, "mixed_instances_policy.0.launch_template.0.override.1.launch_template_specification.0.launch_template_id", "aws_launch_template.test-arm", "id"),
),
},
{
Config: testAccGroupConfig_mixedInstancesPolicyLaunchTemplateOverrideInstanceTypeLaunchTemplateSpecification(rName, rName+"-name-change"),
Check: resource.ComposeTestCheckFunc(
testAccCheckGroupExists(ctx, 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.small"),
resource.TestCheckResourceAttrPair(resourceName, "mixed_instances_policy.0.launch_template.0.override.1.launch_template_specification.0.launch_template_id", "aws_launch_template.test-arm", "id"),
resource.TestCheckResourceAttr(resourceName, "mixed_instances_policy.0.launch_template.0.override.1.launch_template_specification.0.launch_template_name", rName+"-name-change-arm"),
),
},
testAccGroupImportStep(resourceName),
},
})
Expand Down Expand Up @@ -4801,8 +4838,8 @@ resource "aws_autoscaling_group" "test" {
`, rName))
}

func testAccGroupConfig_launchTemplateName(rName string) string {
return acctest.ConfigCompose(testAccGroupConfig_launchTemplateBase(rName, "t2.micro"), fmt.Sprintf(`
func testAccGroupConfig_launchTemplateName(rName, launchTemplateName string) string {
return acctest.ConfigCompose(testAccGroupConfig_launchTemplateBase(launchTemplateName, "t2.micro"), fmt.Sprintf(`
resource "aws_autoscaling_group" "test" {
availability_zones = [data.aws_availability_zones.available.names[0]]
max_size = 0
Expand Down Expand Up @@ -5718,8 +5755,8 @@ resource "aws_autoscaling_group" "test" {
`, rName, spotMaxPrice))
}

func testAccGroupConfig_mixedInstancesPolicyLaunchTemplateLaunchTemplateSpecificationLaunchTemplateName(rName string) string {
return acctest.ConfigCompose(testAccGroupConfig_launchTemplateBase(rName, "t3.micro"), fmt.Sprintf(`
func testAccGroupConfig_mixedInstancesPolicyLaunchTemplateLaunchTemplateSpecificationLaunchTemplateName(rName, launchTemplateName string) string {
return acctest.ConfigCompose(testAccGroupConfig_launchTemplateBase(launchTemplateName, "t3.micro"), fmt.Sprintf(`
resource "aws_autoscaling_group" "test" {
availability_zones = [data.aws_availability_zones.available.names[0]]
desired_capacity = 0
Expand Down Expand Up @@ -5803,7 +5840,7 @@ resource "aws_autoscaling_group" "test" {
`, rName, instanceType))
}

func testAccGroupConfig_mixedInstancesPolicyLaunchTemplateOverrideInstanceTypeLaunchTemplateSpecification(rName string) string {
func testAccGroupConfig_mixedInstancesPolicyLaunchTemplateOverrideInstanceTypeLaunchTemplateSpecification(rName, overrideLaunchTemplateName string) string {
return acctest.ConfigCompose(
testAccGroupConfig_launchTemplateBase(rName, "t3.micro"),
acctest.ConfigLatestAmazonLinux2HVMEBSARM64AMI(),
Expand All @@ -5819,7 +5856,7 @@ resource "aws_autoscaling_group" "test" {
desired_capacity = 0
max_size = 0
min_size = 0
name = %[1]q
name = %[2]q

mixed_instances_policy {
launch_template {
Expand All @@ -5841,7 +5878,7 @@ resource "aws_autoscaling_group" "test" {
}
}
}
`, rName))
`, overrideLaunchTemplateName, rName))
}

func testAccGroupConfig_mixedInstancesPolicyLaunchTemplateOverrideWeightedCapacity(rName string) string {
Expand Down
Loading