Skip to content

Commit 9dfcf44

Browse files
authored
Merge pull request #10435 from beezly/feature/add_tg_api_limits
Batch up requests with more than 10 target group changes
2 parents c36b56c + d4fe206 commit 9dfcf44

File tree

2 files changed

+229
-12
lines changed

2 files changed

+229
-12
lines changed

aws/resource_aws_autoscaling_group.go

Lines changed: 117 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -767,6 +767,78 @@ func resourceAwsAutoscalingGroupRead(d *schema.ResourceData, meta interface{}) e
767767
return nil
768768
}
769769

770+
func waitUntilAutoscalingGroupLoadBalancerTargetGroupsRemoved(conn *autoscaling.AutoScaling, asgName string) error {
771+
input := &autoscaling.DescribeLoadBalancerTargetGroupsInput{
772+
AutoScalingGroupName: aws.String(asgName),
773+
}
774+
var tgRemoving bool
775+
776+
for {
777+
output, err := conn.DescribeLoadBalancerTargetGroups(input)
778+
779+
if err != nil {
780+
return err
781+
}
782+
783+
for _, tg := range output.LoadBalancerTargetGroups {
784+
if aws.StringValue(tg.State) == "Removing" {
785+
tgRemoving = true
786+
break
787+
}
788+
}
789+
790+
if tgRemoving {
791+
tgRemoving = false
792+
input.NextToken = nil
793+
continue
794+
}
795+
796+
if aws.StringValue(output.NextToken) == "" {
797+
break
798+
}
799+
800+
input.NextToken = output.NextToken
801+
}
802+
803+
return nil
804+
}
805+
806+
func waitUntilAutoscalingGroupLoadBalancerTargetGroupsAdded(conn *autoscaling.AutoScaling, asgName string) error {
807+
input := &autoscaling.DescribeLoadBalancerTargetGroupsInput{
808+
AutoScalingGroupName: aws.String(asgName),
809+
}
810+
var tgAdding bool
811+
812+
for {
813+
output, err := conn.DescribeLoadBalancerTargetGroups(input)
814+
815+
if err != nil {
816+
return err
817+
}
818+
819+
for _, tg := range output.LoadBalancerTargetGroups {
820+
if aws.StringValue(tg.State) == "Adding" {
821+
tgAdding = true
822+
break
823+
}
824+
}
825+
826+
if tgAdding {
827+
tgAdding = false
828+
input.NextToken = nil
829+
continue
830+
}
831+
832+
if aws.StringValue(output.NextToken) == "" {
833+
break
834+
}
835+
836+
input.NextToken = output.NextToken
837+
}
838+
839+
return nil
840+
}
841+
770842
func resourceAwsAutoscalingGroupUpdate(d *schema.ResourceData, meta interface{}) error {
771843
conn := meta.(*AWSClient).autoscalingconn
772844
shouldWaitForCapacity := false
@@ -920,22 +992,55 @@ func resourceAwsAutoscalingGroupUpdate(d *schema.ResourceData, meta interface{})
920992
add := expandStringList(ns.Difference(os).List())
921993

922994
if len(remove) > 0 {
923-
_, err := conn.DetachLoadBalancerTargetGroups(&autoscaling.DetachLoadBalancerTargetGroupsInput{
924-
AutoScalingGroupName: aws.String(d.Id()),
925-
TargetGroupARNs: remove,
926-
})
927-
if err != nil {
928-
return fmt.Errorf("Error updating Load Balancers Target Groups for AutoScaling Group (%s), error: %s", d.Id(), err)
995+
// AWS API only supports adding/removing 10 at a time
996+
var batches [][]*string
997+
998+
batchSize := 10
999+
1000+
for batchSize < len(remove) {
1001+
remove, batches = remove[batchSize:], append(batches, remove[0:batchSize:batchSize])
9291002
}
1003+
batches = append(batches, remove)
1004+
1005+
for _, batch := range batches {
1006+
_, err := conn.DetachLoadBalancerTargetGroups(&autoscaling.DetachLoadBalancerTargetGroupsInput{
1007+
AutoScalingGroupName: aws.String(d.Id()),
1008+
TargetGroupARNs: batch,
1009+
})
1010+
if err != nil {
1011+
return fmt.Errorf("Error updating Load Balancers Target Groups for AutoScaling Group (%s), error: %s", d.Id(), err)
1012+
}
1013+
1014+
if err := waitUntilAutoscalingGroupLoadBalancerTargetGroupsRemoved(conn, d.Id()); err != nil {
1015+
return fmt.Errorf("error describing AutoScaling Group (%s) Load Balancer Target Groups being removed: %s", d.Id(), err)
1016+
}
1017+
}
1018+
9301019
}
9311020

9321021
if len(add) > 0 {
933-
_, err := conn.AttachLoadBalancerTargetGroups(&autoscaling.AttachLoadBalancerTargetGroupsInput{
934-
AutoScalingGroupName: aws.String(d.Id()),
935-
TargetGroupARNs: add,
936-
})
937-
if err != nil {
938-
return fmt.Errorf("Error updating Load Balancers Target Groups for AutoScaling Group (%s), error: %s", d.Id(), err)
1022+
batchSize := 10
1023+
1024+
var batches [][]*string
1025+
1026+
for batchSize < len(add) {
1027+
add, batches = add[batchSize:], append(batches, add[0:batchSize:batchSize])
1028+
}
1029+
batches = append(batches, add)
1030+
1031+
for _, batch := range batches {
1032+
_, err := conn.AttachLoadBalancerTargetGroups(&autoscaling.AttachLoadBalancerTargetGroupsInput{
1033+
AutoScalingGroupName: aws.String(d.Id()),
1034+
TargetGroupARNs: batch,
1035+
})
1036+
1037+
if err != nil {
1038+
return fmt.Errorf("Error updating Load Balancers Target Groups for AutoScaling Group (%s), error: %s", d.Id(), err)
1039+
}
1040+
1041+
if err := waitUntilAutoscalingGroupLoadBalancerTargetGroupsAdded(conn, d.Id()); err != nil {
1042+
return fmt.Errorf("error describing AutoScaling Group (%s) Load Balancer Target Groups being added: %s", d.Id(), err)
1043+
}
9391044
}
9401045
}
9411046
}

aws/resource_aws_autoscaling_group_test.go

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -825,6 +825,118 @@ func TestAccAWSAutoScalingGroup_ALB_TargetGroups(t *testing.T) {
825825
})
826826
}
827827

828+
// Reference: https://github.com/terraform-providers/terraform-provider-aws/issues/256
829+
func TestAccAWSAutoScalingGroup_TargetGroupArns(t *testing.T) {
830+
var group autoscaling.Group
831+
resourceName := "aws_autoscaling_group.test"
832+
rName := acctest.RandomWithPrefix("tf-acc-test")
833+
834+
resource.ParallelTest(t, resource.TestCase{
835+
PreCheck: func() { testAccPreCheck(t) },
836+
Providers: testAccProviders,
837+
CheckDestroy: testAccCheckAWSAutoScalingGroupDestroy,
838+
Steps: []resource.TestStep{
839+
{
840+
Config: testAccAWSAutoScalingGroupConfig_TargetGroupArns(rName, 11),
841+
Check: resource.ComposeTestCheckFunc(
842+
testAccCheckAWSAutoScalingGroupExists(resourceName, &group),
843+
resource.TestCheckResourceAttr(resourceName, "target_group_arns.#", "11"),
844+
),
845+
},
846+
{
847+
ResourceName: resourceName,
848+
ImportState: true,
849+
ImportStateVerify: true,
850+
ImportStateVerifyIgnore: []string{
851+
"force_delete",
852+
"initial_lifecycle_hook",
853+
"name_prefix",
854+
"tag",
855+
"tags",
856+
"wait_for_capacity_timeout",
857+
"wait_for_elb_capacity",
858+
},
859+
},
860+
{
861+
Config: testAccAWSAutoScalingGroupConfig_TargetGroupArns(rName, 0),
862+
Check: resource.ComposeTestCheckFunc(
863+
testAccCheckAWSAutoScalingGroupExists(resourceName, &group),
864+
resource.TestCheckResourceAttr(resourceName, "target_group_arns.#", "0"),
865+
),
866+
},
867+
{
868+
Config: testAccAWSAutoScalingGroupConfig_TargetGroupArns(rName, 11),
869+
Check: resource.ComposeTestCheckFunc(
870+
testAccCheckAWSAutoScalingGroupExists(resourceName, &group),
871+
resource.TestCheckResourceAttr(resourceName, "target_group_arns.#", "11"),
872+
),
873+
},
874+
},
875+
})
876+
}
877+
878+
func testAccAWSAutoScalingGroupConfig_TargetGroupArns(rName string, tgCount int) string {
879+
return fmt.Sprintf(`
880+
data "aws_ami" "test" {
881+
most_recent = true
882+
owners = ["amazon"]
883+
884+
filter {
885+
name = "name"
886+
values = ["amzn-ami-hvm-*-x86_64-gp2"]
887+
}
888+
}
889+
890+
data "aws_availability_zones" "available" {
891+
state = "available"
892+
}
893+
894+
resource "aws_launch_template" "test" {
895+
image_id = data.aws_ami.test.id
896+
instance_type = "t3.micro"
897+
name = %[1]q
898+
}
899+
900+
resource "aws_vpc" "test" {
901+
cidr_block = "10.0.0.0/16"
902+
903+
tags = {
904+
Name = %[1]q
905+
}
906+
}
907+
908+
resource "aws_subnet" "test" {
909+
availability_zone = data.aws_availability_zones.available.names[0]
910+
cidr_block = "10.0.0.0/24"
911+
vpc_id = aws_vpc.test.id
912+
913+
tags = {
914+
Name = %[1]q
915+
}
916+
}
917+
918+
resource "aws_lb_target_group" "test" {
919+
count = %[2]d
920+
921+
port = 80
922+
protocol = "HTTP"
923+
vpc_id = "${aws_vpc.test.id}"
924+
}
925+
926+
resource "aws_autoscaling_group" "test" {
927+
force_delete = true
928+
max_size = 0
929+
min_size = 0
930+
target_group_arns = length(aws_lb_target_group.test) > 0 ? aws_lb_target_group.test[*].arn : []
931+
vpc_zone_identifier = [aws_subnet.test.id]
932+
933+
launch_template {
934+
id = aws_launch_template.test.id
935+
}
936+
}
937+
`, rName, tgCount)
938+
}
939+
828940
func TestAccAWSAutoScalingGroup_initialLifecycleHook(t *testing.T) {
829941
var group autoscaling.Group
830942

0 commit comments

Comments
 (0)