Skip to content

Commit

Permalink
Merge pull request #26654 from lurcio/b-asg-attach-retry
Browse files Browse the repository at this point in the history
Retry when creating or deleting asg_autoscaling_attachment resources
  • Loading branch information
ewbankkit authored Sep 9, 2022
2 parents 3a7c9c5 + 7967a87 commit d4aae92
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 47 deletions.
3 changes: 3 additions & 0 deletions .changelog/26654.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:bug
resource/aws_autoscaling_attachment: Retry errors like `ValidationError: Trying to update too many Load Balancers/Target Groups at once. The limit is 10` when creating or deleting resource
```
33 changes: 29 additions & 4 deletions internal/service/autoscaling/attachment.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,14 @@ func resourceAttachmentCreate(d *schema.ResourceData, meta interface{}) error {
LoadBalancerNames: aws.StringSlice([]string{lbName}),
}

if _, err := conn.AttachLoadBalancers(input); err != nil {
_, err := tfresource.RetryWhenAWSErrMessageContains(d.Timeout(schema.TimeoutCreate),
func() (interface{}, error) {
return conn.AttachLoadBalancers(input)
},
// ValidationError: Trying to update too many Load Balancers/Target Groups at once. The limit is 10
ErrCodeValidationError, "update too many")

if err != nil {
return fmt.Errorf("attaching Auto Scaling Group (%s) load balancer (%s): %w", asgName, lbName, err)
}
} else {
Expand All @@ -74,7 +81,13 @@ func resourceAttachmentCreate(d *schema.ResourceData, meta interface{}) error {
TargetGroupARNs: aws.StringSlice([]string{targetGroupARN}),
}

if _, err := conn.AttachLoadBalancerTargetGroups(input); err != nil {
_, err := tfresource.RetryWhenAWSErrMessageContains(d.Timeout(schema.TimeoutCreate),
func() (interface{}, error) {
return conn.AttachLoadBalancerTargetGroups(input)
},
ErrCodeValidationError, "update too many")

if err != nil {
return fmt.Errorf("attaching Auto Scaling Group (%s) target group (%s): %w", asgName, targetGroupARN, err)
}
}
Expand Down Expand Up @@ -128,7 +141,13 @@ func resourceAttachmentDelete(d *schema.ResourceData, meta interface{}) error {
LoadBalancerNames: aws.StringSlice([]string{lbName}),
}

if _, err := conn.DetachLoadBalancers(input); err != nil {
_, err := tfresource.RetryWhenAWSErrMessageContains(d.Timeout(schema.TimeoutCreate),
func() (interface{}, error) {
return conn.DetachLoadBalancers(input)
},
ErrCodeValidationError, "update too many")

if err != nil {
return fmt.Errorf("detaching Auto Scaling Group (%s) load balancer (%s): %w", asgName, lbName, err)
}
} else {
Expand All @@ -144,7 +163,13 @@ func resourceAttachmentDelete(d *schema.ResourceData, meta interface{}) error {
TargetGroupARNs: aws.StringSlice([]string{targetGroupARN}),
}

if _, err := conn.DetachLoadBalancerTargetGroups(input); err != nil {
_, err := tfresource.RetryWhenAWSErrMessageContains(d.Timeout(schema.TimeoutCreate),
func() (interface{}, error) {
return conn.DetachLoadBalancerTargetGroups(input)
},
ErrCodeValidationError, "update too many")

if err != nil {
return fmt.Errorf("detaching Auto Scaling Group (%s) target group (%s): %w", asgName, targetGroupARN, err)
}
}
Expand Down
120 changes: 77 additions & 43 deletions internal/service/autoscaling/attachment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ import (

func TestAccAutoScalingAttachment_elb(t *testing.T) {
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
resource1Name := "aws_autoscaling_attachment.test1"
resource2Name := "aws_autoscaling_attachment.test2"
resourceName := "aws_autoscaling_attachment.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t) },
Expand All @@ -26,57 +25,88 @@ func TestAccAutoScalingAttachment_elb(t *testing.T) {
CheckDestroy: testAccCheckAttachmentDestroy,
Steps: []resource.TestStep{
{
Config: testAccAttachmentConfig_elbOneAssociation(rName),
Config: testAccAttachmentConfig_elb(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAttachmentByLoadBalancerNameExists(resource1Name),
testAccCheckAttachmentByLoadBalancerNameExists(resourceName),
),
},
},
})
}

func TestAccAutoScalingAttachment_albTargetGroup(t *testing.T) {
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
resourceName := "aws_autoscaling_attachment.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t) },
ErrorCheck: acctest.ErrorCheck(t, autoscaling.EndpointsID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckAttachmentDestroy,
Steps: []resource.TestStep{
{
Config: testAccAttachmentConfig_elbTwoAssociations(rName),
Config: testAccAttachmentConfig_targetGroup(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAttachmentByLoadBalancerNameExists(resource1Name),
testAccCheckAttachmentByLoadBalancerNameExists(resource2Name),
testAccCheckAttachmentByTargetGroupARNExists(resourceName),
),
},
},
})
}

func TestAccAutoScalingAttachment_multipleELBs(t *testing.T) {
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
resource1Name := "aws_autoscaling_attachment.test.0"
resource11Name := "aws_autoscaling_attachment.test.10"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t) },
ErrorCheck: acctest.ErrorCheck(t, autoscaling.EndpointsID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckAttachmentDestroy,
Steps: []resource.TestStep{
// Create all the ELBs first.
{
Config: testAccAttachmentConfig_elbOneAssociation(rName),
Config: testAccAttachmentConfig_elbBase(rName, 11),
},
{
Config: testAccAttachmentConfig_multipleELBs(rName, 11),
Check: resource.ComposeTestCheckFunc(
testAccCheckAttachmentByLoadBalancerNameExists(resource1Name),
testAccCheckAttachmentByLoadBalancerNameExists(resource11Name),
),
},
{
Config: testAccAttachmentConfig_elbBase(rName, 11),
},
},
})
}

func TestAccAutoScalingAttachment_albTargetGroup(t *testing.T) {
func TestAccAutoScalingAttachment_multipleALBTargetGroups(t *testing.T) {
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
resource1Name := "aws_autoscaling_attachment.test1"
resource2Name := "aws_autoscaling_attachment.test2"
resource1Name := "aws_autoscaling_attachment.test.0"
resource11Name := "aws_autoscaling_attachment.test.10"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t) },
ErrorCheck: acctest.ErrorCheck(t, autoscaling.EndpointsID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckAttachmentDestroy,
Steps: []resource.TestStep{
// Create all the target groups first.
{
Config: testAccAttachmentConfig_targetGroupOneAssociation(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAttachmentByTargetGroupARNExists(resource1Name),
),
Config: testAccAttachmentConfig_targetGroupBase(rName, 11),
},
{
Config: testAccAttachmentConfig_targetGroupTwoAssociations(rName),
Config: testAccAttachmentConfig_multipleTargetGroups(rName, 11),
Check: resource.ComposeTestCheckFunc(
testAccCheckAttachmentByTargetGroupARNExists(resource1Name),
testAccCheckAttachmentByTargetGroupARNExists(resource2Name),
testAccCheckAttachmentByTargetGroupARNExists(resource11Name),
),
},
{
Config: testAccAttachmentConfig_targetGroupOneAssociation(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAttachmentByTargetGroupARNExists(resource1Name),
),
Config: testAccAttachmentConfig_targetGroupBase(rName, 11),
},
},
})
Expand Down Expand Up @@ -145,10 +175,10 @@ func testAccCheckAttachmentByTargetGroupARNExists(n string) resource.TestCheckFu
}
}

func testAccAttachmentConfig_elbBase(rName string) string {
func testAccAttachmentConfig_elbBase(rName string, elbCount int) string {
return acctest.ConfigCompose(testAccGroupConfig_launchConfigurationBase(rName, "t2.micro"), fmt.Sprintf(`
resource "aws_elb" "test" {
count = 2
count = %[2]d
# "name" cannot be longer than 32 characters.
name = format("%%s-%%d", substr(%[1]q, 0, 28), count.index)
Expand Down Expand Up @@ -182,16 +212,16 @@ resource "aws_autoscaling_group" "test" {
ignore_changes = [load_balancers]
}
}
`, rName))
`, rName, elbCount))
}

func testAccAttachmentConfig_targetGroupBase(rName string) string {
func testAccAttachmentConfig_targetGroupBase(rName string, targetGroupCount int) string {
return acctest.ConfigCompose(
acctest.ConfigLatestAmazonLinuxHVMEBSAMI(),
acctest.ConfigVPCWithSubnets(rName, 1),
fmt.Sprintf(`
resource "aws_lb_target_group" "test" {
count = 2
count = %[2]d
# "name" cannot be longer than 32 characters.
name = format("%%s-%%d", substr(%[1]q, 0, 28), count.index)
Expand Down Expand Up @@ -226,41 +256,45 @@ resource "aws_autoscaling_group" "test" {
ignore_changes = [target_group_arns]
}
}
`, rName))
`, rName, targetGroupCount))
}

func testAccAttachmentConfig_elbOneAssociation(rName string) string {
return acctest.ConfigCompose(testAccAttachmentConfig_elbBase(rName), `
resource "aws_autoscaling_attachment" "test1" {
func testAccAttachmentConfig_elb(rName string) string {
return acctest.ConfigCompose(testAccAttachmentConfig_elbBase(rName, 1), `
resource "aws_autoscaling_attachment" "test" {
autoscaling_group_name = aws_autoscaling_group.test.id
elb = aws_elb.test[0].id
}
`)
}

func testAccAttachmentConfig_elbTwoAssociations(rName string) string {
return acctest.ConfigCompose(testAccAttachmentConfig_elbOneAssociation(rName), `
resource "aws_autoscaling_attachment" "test2" {
func testAccAttachmentConfig_multipleELBs(rName string, n int) string {
return acctest.ConfigCompose(testAccAttachmentConfig_elbBase(rName, n), fmt.Sprintf(`
resource "aws_autoscaling_attachment" "test" {
count = %[1]d
autoscaling_group_name = aws_autoscaling_group.test.id
elb = aws_elb.test[1].id
elb = aws_elb.test[count.index].id
}
`)
`, n))
}

func testAccAttachmentConfig_targetGroupOneAssociation(rName string) string {
return acctest.ConfigCompose(testAccAttachmentConfig_targetGroupBase(rName), `
resource "aws_autoscaling_attachment" "test1" {
func testAccAttachmentConfig_targetGroup(rName string) string {
return acctest.ConfigCompose(testAccAttachmentConfig_targetGroupBase(rName, 1), `
resource "aws_autoscaling_attachment" "test" {
autoscaling_group_name = aws_autoscaling_group.test.id
lb_target_group_arn = aws_lb_target_group.test[0].arn
}
`)
}

func testAccAttachmentConfig_targetGroupTwoAssociations(rName string) string {
return acctest.ConfigCompose(testAccAttachmentConfig_targetGroupOneAssociation(rName), `
resource "aws_autoscaling_attachment" "test2" {
func testAccAttachmentConfig_multipleTargetGroups(rName string, n int) string {
return acctest.ConfigCompose(testAccAttachmentConfig_targetGroupBase(rName, n), fmt.Sprintf(`
resource "aws_autoscaling_attachment" "test" {
count = %[1]d
autoscaling_group_name = aws_autoscaling_group.test.id
alb_target_group_arn = aws_lb_target_group.test[1].arn
lb_target_group_arn = aws_lb_target_group.test[0].arn
}
`)
`, n))
}

0 comments on commit d4aae92

Please sign in to comment.