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_tag: new resource for tagging existing ASGs #20009

Closed
wants to merge 1 commit 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/20009.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:new-resource
aws_autoscaling_group_tag
```
1 change: 1 addition & 0 deletions aws/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,7 @@ func Provider() *schema.Provider {
"aws_athena_workgroup": resourceAwsAthenaWorkgroup(),
"aws_autoscaling_attachment": resourceAwsAutoscalingAttachment(),
"aws_autoscaling_group": resourceAwsAutoscalingGroup(),
"aws_autoscaling_group_tag": resourceAwsAutoscalingGroupTag(),
"aws_autoscaling_lifecycle_hook": resourceAwsAutoscalingLifecycleHook(),
"aws_autoscaling_notification": resourceAwsAutoscalingNotification(),
"aws_autoscaling_policy": resourceAwsAutoscalingPolicy(),
Expand Down
143 changes: 143 additions & 0 deletions aws/resource_aws_autoscaling_group_tag.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
package aws

import (
"fmt"
"log"
"strings"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags"
)

func resourceAwsAutoscalingGroupTag() *schema.Resource {
return &schema.Resource{
Create: resourceAwsAutoscalingGroupTagCreate,
Read: resourceAwsAutoscalingGroupTagRead,
Update: resourceAwsAutoscalingGroupTagUpdate,
Delete: resourceAwsAutoscalingGroupTagDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},

Schema: map[string]*schema.Schema{
"asg_name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"tag": {
Type: schema.TypeList,
MaxItems: 1,
Required: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"key": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"value": {
Type: schema.TypeString,
Required: true,
},
"propagate_at_launch": {
Type: schema.TypeBool,
Required: true,
},
},
},
},
},
}
}

func extractAutoscalingGroupNameAndKeyFromAutoscalingGroupTagID(id string) (string, string, error) {
parts := strings.SplitN(id, ",", 2)

if len(parts) != 2 {
return "", "", fmt.Errorf("Invalid resource ID; cannot look up resource: %s", id)
}

return parts[0], parts[1], nil
}

func resourceAwsAutoscalingGroupTagCreate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).autoscalingconn

asgName := d.Get("asg_name").(string)
tags := d.Get("tag").([]interface{})

tag := tags[0].(map[string]interface{})
key := tag["key"].(string)

if err := keyvaluetags.AutoscalingUpdateTags(conn, asgName, autoscalingTagResourceTypeAutoScalingGroup, nil, tags); err != nil {
return fmt.Errorf("error updating Autoscaling Tag (%s) for resource (%s): %w", key, asgName, err)
}

d.SetId(fmt.Sprintf("%s,%s", asgName, key))

return resourceAwsAutoscalingGroupTagRead(d, meta)
}

func resourceAwsAutoscalingGroupTagRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).autoscalingconn
asgName, key, err := extractAutoscalingGroupNameAndKeyFromAutoscalingGroupTagID(d.Id())

if err != nil {
return err
}

exists, tagData, err := keyvaluetags.AutoscalingGetTag(conn, asgName, autoscalingTagResourceTypeAutoScalingGroup, key)

if err != nil {
return fmt.Errorf("error reading Autoscaling Tag (%s) for resource (%s): %w", key, asgName, err)
}

if !exists {
log.Printf("[WARN] Autoscaling Tag (%s) for resource (%s) not found, removing from state", key, asgName)
d.SetId("")
return nil
}

d.Set("asg_name", asgName)

tag := map[string]interface{}{
"key": key,
"value": tagData.Value,

"propagate_at_launch": tagData.AdditionalBoolFields["PropagateAtLaunch"],
}
d.Set("tag", []map[string]interface{}{tag})

return nil
}

func resourceAwsAutoscalingGroupTagUpdate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).autoscalingconn
asgName, key, err := extractAutoscalingGroupNameAndKeyFromAutoscalingGroupTagID(d.Id())

if err != nil {
return err
}

if err := keyvaluetags.AutoscalingUpdateTags(conn, asgName, autoscalingTagResourceTypeAutoScalingGroup, nil, d.Get("tag")); err != nil {
return fmt.Errorf("error updating Autoscaling Tag (%s) for resource (%s): %w", key, asgName, err)
}

return resourceAwsAutoscalingGroupTagRead(d, meta)
}

func resourceAwsAutoscalingGroupTagDelete(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).autoscalingconn
asgName, key, err := extractAutoscalingGroupNameAndKeyFromAutoscalingGroupTagID(d.Id())

if err != nil {
return err
}

if err := keyvaluetags.AutoscalingUpdateTags(conn, asgName, autoscalingTagResourceTypeAutoScalingGroup, d.Get("tag"), nil); err != nil {
return fmt.Errorf("error deleting Autoscaling Tag (%s) for resource (%s): %w", key, asgName, err)
}

return nil
}
204 changes: 204 additions & 0 deletions aws/resource_aws_autoscaling_group_tag_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
package aws

import (
"fmt"
"testing"

"github.com/aws/aws-sdk-go/service/autoscaling"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags"
)

func TestAccAWSAutoscalingGroupTag_basic(t *testing.T) {
resourceName := "aws_autoscaling_group_tag.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ErrorCheck: testAccErrorCheck(t, autoscaling.EndpointsID),
Providers: testAccProviders,
CheckDestroy: testAccCheckAutoscalingGroupTagDestroy,
Steps: []resource.TestStep{
{
Config: testAccAutoscalingGroupTagConfig("key1", "value1"),
Check: resource.ComposeTestCheckFunc(
testAccCheckAutoscalingGroupTagExists(resourceName),
resource.TestCheckResourceAttr(resourceName, "tag.0.key", "key1"),
resource.TestCheckResourceAttr(resourceName, "tag.0.value", "value1"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func TestAccAWSAutoscalingGroupTag_disappears(t *testing.T) {
resourceName := "aws_autoscaling_group_tag.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ErrorCheck: testAccErrorCheck(t, autoscaling.EndpointsID),
Providers: testAccProviders,
CheckDestroy: testAccCheckAutoscalingGroupTagDestroy,
Steps: []resource.TestStep{
{
Config: testAccAutoscalingGroupTagConfig("key1", "value1"),
Check: resource.ComposeTestCheckFunc(
testAccCheckAutoscalingGroupTagExists(resourceName),
testAccCheckResourceDisappears(testAccProvider, resourceAwsAutoscalingGroupTag(), resourceName),
),
ExpectNonEmptyPlan: true,
},
},
})
}

func TestAccAWSAutoscalingGroupTag_Value(t *testing.T) {
resourceName := "aws_autoscaling_group_tag.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ErrorCheck: testAccErrorCheck(t, autoscaling.EndpointsID),
Providers: testAccProviders,
CheckDestroy: testAccCheckAutoscalingGroupTagDestroy,
Steps: []resource.TestStep{
{
Config: testAccAutoscalingGroupTagConfig("key1", "value1"),
Check: resource.ComposeTestCheckFunc(
testAccCheckAutoscalingGroupTagExists(resourceName),
resource.TestCheckResourceAttr(resourceName, "tag.0.key", "key1"),
resource.TestCheckResourceAttr(resourceName, "tag.0.value", "value1"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccAutoscalingGroupTagConfig("key1", "value1updated"),
Check: resource.ComposeTestCheckFunc(
testAccCheckAutoscalingGroupTagExists(resourceName),
resource.TestCheckResourceAttr(resourceName, "tag.0.key", "key1"),
resource.TestCheckResourceAttr(resourceName, "tag.0.value", "value1updated"),
),
},
},
})
}

func testAccCheckAutoscalingGroupTagDestroy(s *terraform.State) error {
conn := testAccProvider.Meta().(*AWSClient).autoscalingconn

for _, rs := range s.RootModule().Resources {
if rs.Type != "aws_autoscaling_group_tag" {
continue
}

asgName, key, err := extractAutoscalingGroupNameAndKeyFromAutoscalingGroupTagID(rs.Primary.ID)

if err != nil {
return err
}

exists, _, err := keyvaluetags.AutoscalingGetTag(conn, asgName, autoscalingTagResourceTypeAutoScalingGroup, key)

if err != nil {
return err
}

if exists {
return fmt.Errorf("Tag (%s) for resource (%s) still exists", key, asgName)
}
}

return nil
}

func testAccCheckAutoscalingGroupTagExists(n string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("Not found: %s", n)
}

if rs.Primary.ID == "" {
return fmt.Errorf("No ID is set")
}

asgName, key, err := extractAutoscalingGroupNameAndKeyFromAutoscalingGroupTagID(rs.Primary.ID)

if err != nil {
return err
}

conn := testAccProvider.Meta().(*AWSClient).autoscalingconn

exists, _, err := keyvaluetags.AutoscalingGetTag(conn, asgName, autoscalingTagResourceTypeAutoScalingGroup, key)

if err != nil {
return err
}

if !exists {
return fmt.Errorf("Tag (%s) for resource (%s) not found", key, asgName)
}

return nil
}
}

func testAccAutoscalingGroupTagConfig(key string, value string) string {
return fmt.Sprintf(`
data "aws_ami" "latest_al2" {
owners = ["amazon"]
most_recent = true

filter {
name = "name"
values = ["amzn2-ami-hvm-*-x86_64-ebs"]
}
}

resource "aws_launch_template" "test" {
name_prefix = "terraform-test-"
image_id = data.aws_ami.latest_al2.id
instance_type = "t2.nano"
}

data "aws_availability_zones" "available" {
state = "available"
}

resource "aws_autoscaling_group" "test" {
lifecycle {
ignore_changes = [tag]
}

availability_zones = data.aws_availability_zones.available.names

min_size = 0
max_size = 0

launch_template {
id = aws_launch_template.test.id
version = "$Latest"
}
}

resource "aws_autoscaling_group_tag" "test" {
asg_name = aws_autoscaling_group.test.name

tag {
key = %[1]q
value = %[2]q

propagate_at_launch = true
}
}
`, key, value)
}
Loading