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

r/aws_autoscaling_group: launch_template name update #34086

Merged
merged 8 commits into from
Oct 25, 2023
Merged
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/34086.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:bug
resource/aws_autoscaling_group: Fix error when `launch_template` name is updated.
```
4 changes: 4 additions & 0 deletions internal/service/autoscaling/consts.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,7 @@ const (
TrafficSourceStateRemoving = "Removing"
TrafficSourceStateRemoved = "Removed"
)

const (
launchTemplateIDUnknown = "unknown"
)
66 changes: 58 additions & 8 deletions internal/service/autoscaling/group.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ func ResourceGroup() *schema.Resource {
Type: schema.TypeList,
MaxItems: 1,
Optional: true,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"id": {
Expand Down Expand Up @@ -309,6 +310,7 @@ func ResourceGroup() *schema.Resource {
"mixed_instances_policy": {
Type: schema.TypeList,
Optional: true,
Computed: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
Expand Down Expand Up @@ -396,6 +398,7 @@ func ResourceGroup() *schema.Resource {
"override": {
Type: schema.TypeList,
Optional: true,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"instance_requirements": {
Expand Down Expand Up @@ -865,16 +868,63 @@ func ResourceGroup() *schema.Resource {
},

CustomizeDiff: customdiff.Sequence(
customdiff.ComputedIf("launch_template.0.id", func(_ context.Context, diff *schema.ResourceDiff, meta interface{}) bool {
return diff.HasChange("launch_template.0.name")
}),
customdiff.ComputedIf("launch_template.0.name", func(_ context.Context, diff *schema.ResourceDiff, meta interface{}) bool {
return diff.HasChange("launch_template.0.id")
}),
launchTemplateCustomDiff("launch_template", "launch_template.0.name"),
launchTemplateCustomDiff("mixed_instances_policy", "mixed_instances_policy.0.launch_template.0.launch_template_specification.0.launch_template_name"),
launchTemplateCustomDiff("mixed_instances_policy", "mixed_instances_policy.0.launch_template.0.override"),
),
}
}

func launchTemplateCustomDiff(baseAttribute, subAttribute string) schema.CustomizeDiffFunc {
return func(_ context.Context, diff *schema.ResourceDiff, _ interface{}) error {
if diff.HasChange(subAttribute) {
n := diff.Get(baseAttribute)
ba, ok := n.([]interface{})
if !ok {
return nil
}

if baseAttribute == "launch_template" {
launchTemplate := ba[0].(map[string]interface{})
launchTemplate["id"] = launchTemplateIDUnknown

if err := diff.SetNew(baseAttribute, ba); err != nil {
return err
}
}

if baseAttribute == "mixed_instances_policy" && !strings.Contains(subAttribute, "override") {
launchTemplate := ba[0].(map[string]interface{})["launch_template"].([]interface{})[0].(map[string]interface{})["launch_template_specification"].([]interface{})[0]
launchTemplateSpecification := launchTemplate.(map[string]interface{})
launchTemplateSpecification["launch_template_id"] = launchTemplateIDUnknown

if err := diff.SetNew(baseAttribute, ba); err != nil {
return err
}
}

if baseAttribute == "mixed_instances_policy" && strings.Contains(subAttribute, "override") {
launchTemplate := ba[0].(map[string]interface{})["launch_template"].([]interface{})[0].(map[string]interface{})["override"].([]interface{})

for i := range launchTemplate {
key := fmt.Sprintf("mixed_instances_policy.0.launch_template.0.override.%d.launch_template_specification.0.launch_template_name", i)

if diff.HasChange(key) {
launchTemplateSpecification := launchTemplate[i].(map[string]interface{})["launch_template_specification"].([]interface{})[0].(map[string]interface{})
launchTemplateSpecification["launch_template_id"] = launchTemplateIDUnknown
}
}

if err := diff.SetNew(baseAttribute, ba); err != nil {
return err
}
}
}

return nil
}
}

func resourceGroupCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
var diags diag.Diagnostics
conn := meta.(*conns.AWSClient).AutoScalingConn(ctx)
Expand Down Expand Up @@ -3035,7 +3085,7 @@ func expandLaunchTemplateSpecificationForMixedInstancesPolicy(tfMap map[string]i
// API returns both ID and name, which Terraform saves to state. Next update returns:
// ValidationError: Valid requests must contain either launchTemplateId or LaunchTemplateName
// Prefer the ID if we have both.
if v, ok := tfMap["launch_template_id"]; ok && v != "" {
if v, ok := tfMap["launch_template_id"]; ok && v != "" && v != launchTemplateIDUnknown {
apiObject.LaunchTemplateId = aws.String(v.(string))
} else if v, ok := tfMap["launch_template_name"]; ok && v != "" {
apiObject.LaunchTemplateName = aws.String(v.(string))
Expand All @@ -3057,7 +3107,7 @@ func expandLaunchTemplateSpecification(tfMap map[string]interface{}) *autoscalin

// DescribeAutoScalingGroups returns both name and id but LaunchTemplateSpecification
// allows only one of them to be set.
if v, ok := tfMap["id"]; ok && v != "" {
if v, ok := tfMap["id"]; ok && v != "" && v != launchTemplateIDUnknown {
apiObject.LaunchTemplateId = aws.String(v.(string))
} else if v, ok := tfMap["name"]; ok && v != "" {
apiObject.LaunchTemplateName = aws.String(v.(string))
Expand Down
36 changes: 29 additions & 7 deletions internal/service/autoscaling/group_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1098,6 +1098,7 @@ func TestAccAutoScalingGroup_LaunchTemplate_update(t *testing.T) {
ctx := acctest.Context(t)
var group autoscaling.Group
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
launchTemplateNameUpdated := fmt.Sprintf("%s_updated", rName)
resourceName := "aws_autoscaling_group.test"

resource.ParallelTest(t, resource.TestCase{
Expand Down Expand Up @@ -1127,7 +1128,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 Down Expand Up @@ -1159,6 +1160,17 @@ func TestAccAutoScalingGroup_LaunchTemplate_update(t *testing.T) {
resource.TestCheckResourceAttrPair(resourceName, "launch_template.0.version", "aws_launch_template.test", "default_version"),
),
},
{
Config: testAccGroupConfig_launchTemplateName(rName, launchTemplateNameUpdated),
Check: resource.ComposeTestCheckFunc(
testAccCheckGroupExists(ctx, resourceName, &group),
resource.TestCheckResourceAttr(resourceName, "launch_configuration", ""),
resource.TestCheckResourceAttr(resourceName, "launch_template.#", "1"),
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", ""),
),
},
},
})
}
Expand Down Expand Up @@ -1974,15 +1986,15 @@ func TestAccAutoScalingGroup_MixedInstancesPolicyLaunchTemplateLaunchTemplateSpe
var group autoscaling.Group
resourceName := "aws_autoscaling_group.test"
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)

launchTemplateNameUpdated := fmt.Sprintf("%s_updated", rName)
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(ctx, t) },
ErrorCheck: acctest.ErrorCheck(t, autoscaling.EndpointsID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
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 @@ -1992,6 +2004,16 @@ func TestAccAutoScalingGroup_MixedInstancesPolicyLaunchTemplateLaunchTemplateSpe
),
},
testAccGroupImportStep(resourceName),
{
Config: testAccGroupConfig_mixedInstancesPolicyLaunchTemplateLaunchTemplateSpecificationLaunchTemplateName(rName, launchTemplateNameUpdated),
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"),
),
},
},
})
}
Expand Down Expand Up @@ -4801,8 +4823,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 +5740,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
Loading