diff --git a/builtin/providers/aws/resource_aws_autoscaling_group.go b/builtin/providers/aws/resource_aws_autoscaling_group.go index 98c77a81c..2dc460dee 100644 --- a/builtin/providers/aws/resource_aws_autoscaling_group.go +++ b/builtin/providers/aws/resource_aws_autoscaling_group.go @@ -169,6 +169,13 @@ func resourceAwsAutoscalingGroup() *schema.Resource { Default: false, }, + "target_group_arns": &schema.Schema{ + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Set: schema.HashString, + }, + "tag": autoscalingTagsSchema(), }, } @@ -236,6 +243,10 @@ func resourceAwsAutoscalingGroupCreate(d *schema.ResourceData, meta interface{}) autoScalingGroupOpts.TerminationPolicies = expandStringList(v.([]interface{})) } + if v, ok := d.GetOk("target_group_arns"); ok && len(v.(*schema.Set).List()) > 0 { + autoScalingGroupOpts.TargetGroupARNs = expandStringList(v.(*schema.Set).List()) + } + log.Printf("[DEBUG] AutoScaling Group create configuration: %#v", autoScalingGroupOpts) _, err := conn.CreateAutoScalingGroup(&autoScalingGroupOpts) if err != nil { @@ -279,6 +290,9 @@ func resourceAwsAutoscalingGroupRead(d *schema.ResourceData, meta interface{}) e d.Set("health_check_type", g.HealthCheckType) d.Set("launch_configuration", g.LaunchConfigurationName) d.Set("load_balancers", flattenStringList(g.LoadBalancerNames)) + if err := d.Set("target_group_arns", flattenStringList(g.TargetGroupARNs)); err != nil { + log.Printf("[ERR] Error setting target groups: %s", err) + } d.Set("min_size", g.MinSize) d.Set("max_size", g.MaxSize) d.Set("placement_group", g.PlacementGroup) @@ -422,6 +436,42 @@ func resourceAwsAutoscalingGroupUpdate(d *schema.ResourceData, meta interface{}) } } + if d.HasChange("target_group_arns") { + + o, n := d.GetChange("target_group_arns") + if o == nil { + o = new(schema.Set) + } + if n == nil { + n = new(schema.Set) + } + + os := o.(*schema.Set) + ns := n.(*schema.Set) + remove := expandStringList(os.Difference(ns).List()) + add := expandStringList(ns.Difference(os).List()) + + if len(remove) > 0 { + _, err := conn.DetachLoadBalancerTargetGroups(&autoscaling.DetachLoadBalancerTargetGroupsInput{ + AutoScalingGroupName: aws.String(d.Id()), + TargetGroupARNs: remove, + }) + if err != nil { + return fmt.Errorf("[WARN] Error updating Load Balancers Target Groups for AutoScaling Group (%s), error: %s", d.Id(), err) + } + } + + if len(add) > 0 { + _, err := conn.AttachLoadBalancerTargetGroups(&autoscaling.AttachLoadBalancerTargetGroupsInput{ + AutoScalingGroupName: aws.String(d.Id()), + TargetGroupARNs: add, + }) + if err != nil { + return fmt.Errorf("[WARN] Error updating Load Balancers Target Groups for AutoScaling Group (%s), error: %s", d.Id(), err) + } + } + } + if shouldWaitForCapacity { waitForASGCapacity(d, meta, capacitySatifiedUpdate) } diff --git a/builtin/providers/aws/resource_aws_autoscaling_group_test.go b/builtin/providers/aws/resource_aws_autoscaling_group_test.go index bd737872c..716042dba 100644 --- a/builtin/providers/aws/resource_aws_autoscaling_group_test.go +++ b/builtin/providers/aws/resource_aws_autoscaling_group_test.go @@ -4,12 +4,14 @@ import ( "fmt" "reflect" "regexp" + "sort" "strings" "testing" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/autoscaling" + "github.com/aws/aws-sdk-go/service/elbv2" "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" @@ -318,6 +320,83 @@ func TestAccAWSAutoScalingGroup_withMetrics(t *testing.T) { }) } +func TestAccAWSAutoScalingGroup_ALB_TargetGroups(t *testing.T) { + var group autoscaling.Group + var tg elbv2.TargetGroup + var tg2 elbv2.TargetGroup + + testCheck := func(targets []*elbv2.TargetGroup) resource.TestCheckFunc { + return func(*terraform.State) error { + var ts []string + var gs []string + for _, t := range targets { + ts = append(ts, *t.TargetGroupArn) + } + + for _, s := range group.TargetGroupARNs { + gs = append(gs, *s) + } + + sort.Strings(ts) + sort.Strings(gs) + + if !reflect.DeepEqual(ts, gs) { + return fmt.Errorf("Error: target group match not found!\nASG Target groups: %#v\nTarget Group: %#v", ts, gs) + } + return nil + } + } + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSAutoScalingGroupDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccAWSAutoScalingGroupConfig_ALB_TargetGroup_pre, + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAWSAutoScalingGroupExists("aws_autoscaling_group.bar", &group), + testAccCheckAWSALBTargetGroupExists("aws_alb_target_group.test", &tg), + resource.TestCheckResourceAttr( + "aws_autoscaling_group.bar", "target_group_arns.#", "0"), + ), + }, + + resource.TestStep{ + Config: testAccAWSAutoScalingGroupConfig_ALB_TargetGroup_post_duo, + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAWSAutoScalingGroupExists("aws_autoscaling_group.bar", &group), + testAccCheckAWSALBTargetGroupExists("aws_alb_target_group.test", &tg), + testAccCheckAWSALBTargetGroupExists("aws_alb_target_group.test_more", &tg2), + testCheck([]*elbv2.TargetGroup{&tg, &tg2}), + resource.TestCheckResourceAttr( + "aws_autoscaling_group.bar", "target_group_arns.#", "2"), + ), + }, + + resource.TestStep{ + Config: testAccAWSAutoScalingGroupConfig_ALB_TargetGroup_post, + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAWSAutoScalingGroupExists("aws_autoscaling_group.bar", &group), + testAccCheckAWSALBTargetGroupExists("aws_alb_target_group.test", &tg), + testCheck([]*elbv2.TargetGroup{&tg}), + resource.TestCheckResourceAttr( + "aws_autoscaling_group.bar", "target_group_arns.#", "1"), + ), + }, + + resource.TestStep{ + Config: testAccAWSAutoScalingGroupConfig_ALB_TargetGroup_pre, + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAWSAutoScalingGroupExists("aws_autoscaling_group.bar", &group), + resource.TestCheckResourceAttr( + "aws_autoscaling_group.bar", "target_group_arns.#", "0"), + ), + }, + }, + }) +} + func testAccCheckAWSAutoScalingGroupDestroy(s *terraform.State) error { conn := testAccProvider.Meta().(*AWSClient).autoscalingconn @@ -881,3 +960,263 @@ resource "aws_autoscaling_group" "bar" { metrics_granularity = "1Minute" } ` + +const testAccAWSAutoScalingGroupConfig_ALB_TargetGroup_pre = ` +provider "aws" { + region = "us-west-2" +} + +resource "aws_vpc" "default" { + cidr_block = "10.0.0.0/16" + + tags { + Name = "testAccAWSAutoScalingGroupConfig_ALB_TargetGroup" + } +} + +resource "aws_alb_target_group" "test" { + name = "tf-example-alb-tg" + port = 80 + protocol = "HTTP" + vpc_id = "${aws_vpc.default.id}" +} + +resource "aws_subnet" "main" { + vpc_id = "${aws_vpc.default.id}" + cidr_block = "10.0.1.0/24" + availability_zone = "us-west-2a" + + tags { + Name = "testAccAWSAutoScalingGroupConfig_ALB_TargetGroup" + } +} + +resource "aws_subnet" "alt" { + vpc_id = "${aws_vpc.default.id}" + cidr_block = "10.0.2.0/24" + availability_zone = "us-west-2b" + + tags { + Name = "testAccAWSAutoScalingGroupConfig_ALB_TargetGroup" + } +} + +resource "aws_launch_configuration" "foobar" { + # Golang-base from cts-hashi aws account, shared with tf testing account + image_id = "ami-1817d178" + instance_type = "t2.micro" + enable_monitoring = false +} + +resource "aws_autoscaling_group" "bar" { + vpc_zone_identifier = [ + "${aws_subnet.main.id}", + "${aws_subnet.alt.id}", + ] + + max_size = 2 + min_size = 0 + health_check_grace_period = 300 + health_check_type = "ELB" + desired_capacity = 0 + force_delete = true + termination_policies = ["OldestInstance"] + launch_configuration = "${aws_launch_configuration.foobar.name}" + +} + +resource "aws_security_group" "tf_test_self" { + name = "tf_test_alb_asg" + description = "tf_test_alb_asg" + vpc_id = "${aws_vpc.default.id}" + + ingress { + from_port = 80 + to_port = 80 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + + tags { + Name = "testAccAWSAutoScalingGroupConfig_ALB_TargetGroup" + } +} +` + +const testAccAWSAutoScalingGroupConfig_ALB_TargetGroup_post = ` +provider "aws" { + region = "us-west-2" +} + +resource "aws_vpc" "default" { + cidr_block = "10.0.0.0/16" + + tags { + Name = "testAccAWSAutoScalingGroupConfig_ALB_TargetGroup" + } +} + +resource "aws_alb_target_group" "test" { + name = "tf-example-alb-tg" + port = 80 + protocol = "HTTP" + vpc_id = "${aws_vpc.default.id}" +} + +resource "aws_subnet" "main" { + vpc_id = "${aws_vpc.default.id}" + cidr_block = "10.0.1.0/24" + availability_zone = "us-west-2a" + + tags { + Name = "testAccAWSAutoScalingGroupConfig_ALB_TargetGroup" + } +} + +resource "aws_subnet" "alt" { + vpc_id = "${aws_vpc.default.id}" + cidr_block = "10.0.2.0/24" + availability_zone = "us-west-2b" + + tags { + Name = "testAccAWSAutoScalingGroupConfig_ALB_TargetGroup" + } +} + +resource "aws_launch_configuration" "foobar" { + # Golang-base from cts-hashi aws account, shared with tf testing account + image_id = "ami-1817d178" + instance_type = "t2.micro" + enable_monitoring = false +} + +resource "aws_autoscaling_group" "bar" { + vpc_zone_identifier = [ + "${aws_subnet.main.id}", + "${aws_subnet.alt.id}", + ] + + target_group_arns = ["${aws_alb_target_group.test.arn}"] + + max_size = 2 + min_size = 0 + health_check_grace_period = 300 + health_check_type = "ELB" + desired_capacity = 0 + force_delete = true + termination_policies = ["OldestInstance"] + launch_configuration = "${aws_launch_configuration.foobar.name}" + +} + +resource "aws_security_group" "tf_test_self" { + name = "tf_test_alb_asg" + description = "tf_test_alb_asg" + vpc_id = "${aws_vpc.default.id}" + + ingress { + from_port = 80 + to_port = 80 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + + tags { + Name = "testAccAWSAutoScalingGroupConfig_ALB_TargetGroup" + } +} +` + +const testAccAWSAutoScalingGroupConfig_ALB_TargetGroup_post_duo = ` +provider "aws" { + region = "us-west-2" +} + +resource "aws_vpc" "default" { + cidr_block = "10.0.0.0/16" + + tags { + Name = "testAccAWSAutoScalingGroupConfig_ALB_TargetGroup" + } +} + +resource "aws_alb_target_group" "test" { + name = "tf-example-alb-tg" + port = 80 + protocol = "HTTP" + vpc_id = "${aws_vpc.default.id}" +} + +resource "aws_alb_target_group" "test_more" { + name = "tf-example-alb-tg-more" + port = 80 + protocol = "HTTP" + vpc_id = "${aws_vpc.default.id}" +} + +resource "aws_subnet" "main" { + vpc_id = "${aws_vpc.default.id}" + cidr_block = "10.0.1.0/24" + availability_zone = "us-west-2a" + + tags { + Name = "testAccAWSAutoScalingGroupConfig_ALB_TargetGroup" + } +} + +resource "aws_subnet" "alt" { + vpc_id = "${aws_vpc.default.id}" + cidr_block = "10.0.2.0/24" + availability_zone = "us-west-2b" + + tags { + Name = "testAccAWSAutoScalingGroupConfig_ALB_TargetGroup" + } +} + +resource "aws_launch_configuration" "foobar" { + # Golang-base from cts-hashi aws account, shared with tf testing account + image_id = "ami-1817d178" + instance_type = "t2.micro" + enable_monitoring = false +} + +resource "aws_autoscaling_group" "bar" { + vpc_zone_identifier = [ + "${aws_subnet.main.id}", + "${aws_subnet.alt.id}", + ] + + target_group_arns = [ + "${aws_alb_target_group.test.arn}", + "${aws_alb_target_group.test_more.arn}", + ] + + max_size = 2 + min_size = 0 + health_check_grace_period = 300 + health_check_type = "ELB" + desired_capacity = 0 + force_delete = true + termination_policies = ["OldestInstance"] + launch_configuration = "${aws_launch_configuration.foobar.name}" + +} + +resource "aws_security_group" "tf_test_self" { + name = "tf_test_alb_asg" + description = "tf_test_alb_asg" + vpc_id = "${aws_vpc.default.id}" + + ingress { + from_port = 80 + to_port = 80 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + + tags { + Name = "testAccAWSAutoScalingGroupConfig_ALB_TargetGroup" + } +} +` diff --git a/website/source/docs/providers/aws/r/autoscaling_group.html.markdown b/website/source/docs/providers/aws/r/autoscaling_group.html.markdown index f3caab2d9..d11062cb5 100644 --- a/website/source/docs/providers/aws/r/autoscaling_group.html.markdown +++ b/website/source/docs/providers/aws/r/autoscaling_group.html.markdown @@ -67,6 +67,8 @@ The following arguments are supported: * `load_balancers` (Optional) A list of load balancer names to add to the autoscaling group names. * `vpc_zone_identifier` (Optional) A list of subnet IDs to launch resources in. +* `target_group_arns` (Optional) A list of `aws_target_group` ARNs, for use with +Application Load Balancing * `termination_policies` (Optional) A list of policies to decide how the instances in the auto scale group should be terminated. The allowed values are `OldestInstance`, `NewestInstance`, `OldestLaunchConfiguration`, `ClosestToNextInstanceHour`, `Default`. * `tag` (Optional) A list of tag blocks. Tags documented below. * `placement_group` (Optional) The name of the placement group into which you'll launch your instances, if any. @@ -114,6 +116,8 @@ The following attributes are exported: * `vpc_zone_identifier` (Optional) - The VPC zone identifier * `load_balancers` (Optional) The load balancer names associated with the autoscaling group. +* `target_group_arns` (Optional) list of Target Group ARNs that apply to this +AutoScaling Group ~> **NOTE:** When using `ELB` as the health_check_type, `health_check_grace_period` is required. @@ -186,4 +190,4 @@ AutoScaling Groups can be imported using the `name`, e.g. ``` $ terraform import aws_autoscaling_group.web web-asg -``` \ No newline at end of file +```