From aab14f918859c8aefc518d1cd809bb1c7e0020b6 Mon Sep 17 00:00:00 2001 From: Radek Simko Date: Thu, 16 Nov 2017 14:55:33 +0000 Subject: [PATCH 1/2] Make acceptance test more thorough --- aws/resource_aws_lb_target_group_test.go | 168 ++++++++++++++++++++++- 1 file changed, 163 insertions(+), 5 deletions(-) diff --git a/aws/resource_aws_lb_target_group_test.go b/aws/resource_aws_lb_target_group_test.go index 556dbadfdac..7c9b114fe01 100644 --- a/aws/resource_aws_lb_target_group_test.go +++ b/aws/resource_aws_lb_target_group_test.go @@ -87,7 +87,7 @@ func TestAccAWSLBTargetGroup_basic(t *testing.T) { } func TestAccAWSLBTargetGroup_networkLB_TargetGroup(t *testing.T) { - var conf elbv2.TargetGroup + var confBefore, confAfter elbv2.TargetGroup targetGroupName := fmt.Sprintf("test-target-group-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)) resource.Test(t, resource.TestCase{ @@ -99,7 +99,7 @@ func TestAccAWSLBTargetGroup_networkLB_TargetGroup(t *testing.T) { { Config: testAccAWSLBTargetGroupConfig_typeTCP(targetGroupName), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSLBTargetGroupExists("aws_lb_target_group.test", &conf), + testAccCheckAWSLBTargetGroupExists("aws_lb_target_group.test", &confBefore), resource.TestCheckResourceAttrSet("aws_lb_target_group.test", "arn"), resource.TestCheckResourceAttr("aws_lb_target_group.test", "name", targetGroupName), resource.TestCheckResourceAttr("aws_lb_target_group.test", "port", "8082"), @@ -107,16 +107,51 @@ func TestAccAWSLBTargetGroup_networkLB_TargetGroup(t *testing.T) { resource.TestCheckResourceAttrSet("aws_lb_target_group.test", "vpc_id"), resource.TestCheckResourceAttr("aws_lb_target_group.test", "deregistration_delay", "200"), resource.TestCheckResourceAttr("aws_lb_target_group.test", "health_check.#", "1"), - resource.TestCheckResourceAttr("aws_lb_target_group.test", "health_check.0.interval", "30"), + resource.TestCheckResourceAttr("aws_lb_target_group.test", "health_check.0.interval", "10"), + testAccCheckAWSLBTargetGroupHealthCheckInterval(&confBefore, 10), resource.TestCheckResourceAttr("aws_lb_target_group.test", "health_check.0.port", "traffic-port"), resource.TestCheckResourceAttr("aws_lb_target_group.test", "health_check.0.protocol", "TCP"), resource.TestCheckResourceAttr("aws_lb_target_group.test", "health_check.0.timeout", "10"), + testAccCheckAWSLBTargetGroupHealthCheckTimeout(&confBefore, 10), resource.TestCheckResourceAttr("aws_lb_target_group.test", "health_check.0.healthy_threshold", "3"), + testAccCheckAWSLBTargetGroupHealthyThreshold(&confBefore, 3), resource.TestCheckResourceAttr("aws_lb_target_group.test", "health_check.0.unhealthy_threshold", "3"), + testAccCheckAWSLBTargetGroupUnhealthyThreshold(&confBefore, 3), resource.TestCheckResourceAttr("aws_lb_target_group.test", "tags.%", "1"), resource.TestCheckResourceAttr("aws_lb_target_group.test", "tags.Name", "TestAcc_networkLB_TargetGroup"), ), }, + { + Config: testAccAWSLBTargetGroupConfig_typeTCPThresholdUpdated(targetGroupName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAWSLBTargetGroupExists("aws_lb_target_group.test", &confAfter), + resource.TestCheckResourceAttrSet("aws_lb_target_group.test", "arn"), + resource.TestCheckResourceAttr("aws_lb_target_group.test", "name", targetGroupName), + resource.TestCheckResourceAttr("aws_lb_target_group.test", "port", "8082"), + resource.TestCheckResourceAttr("aws_lb_target_group.test", "protocol", "TCP"), + resource.TestCheckResourceAttrSet("aws_lb_target_group.test", "vpc_id"), + resource.TestCheckResourceAttr("aws_lb_target_group.test", "deregistration_delay", "200"), + resource.TestCheckResourceAttr("aws_lb_target_group.test", "health_check.#", "1"), + resource.TestCheckResourceAttr("aws_lb_target_group.test", "health_check.0.interval", "10"), + testAccCheckAWSLBTargetGroupHealthCheckInterval(&confAfter, 10), + resource.TestCheckResourceAttr("aws_lb_target_group.test", "health_check.0.port", "traffic-port"), + resource.TestCheckResourceAttr("aws_lb_target_group.test", "health_check.0.protocol", "TCP"), + resource.TestCheckResourceAttr("aws_lb_target_group.test", "health_check.0.timeout", "10"), + testAccCheckAWSLBTargetGroupHealthCheckTimeout(&confBefore, 10), + resource.TestCheckResourceAttr("aws_lb_target_group.test", "health_check.0.healthy_threshold", "5"), + testAccCheckAWSLBTargetGroupHealthyThreshold(&confAfter, 5), + resource.TestCheckResourceAttr("aws_lb_target_group.test", "health_check.0.unhealthy_threshold", "5"), + testAccCheckAWSLBTargetGroupUnhealthyThreshold(&confAfter, 5), + resource.TestCheckResourceAttr("aws_lb_target_group.test", "tags.%", "1"), + resource.TestCheckResourceAttr("aws_lb_target_group.test", "tags.Name", "TestAcc_networkLB_TargetGroup"), + ), + }, + { + Config: testAccAWSLBTargetGroupConfig_typeTCPIntervalUpdated(targetGroupName), + + ExpectNonEmptyPlan: true, + ExpectError: regexp.MustCompile("Health check interval cannot be updated"), + }, }, }) } @@ -369,11 +404,14 @@ func TestAccAWSLBTargetGroup_updateHealthCheck(t *testing.T) { resource.TestCheckResourceAttr("aws_lb_target_group.test", "health_check.#", "1"), resource.TestCheckResourceAttr("aws_lb_target_group.test", "health_check.0.path", "/health"), resource.TestCheckResourceAttr("aws_lb_target_group.test", "health_check.0.interval", "60"), + testAccCheckAWSLBTargetGroupHealthCheckInterval(&conf, 60), resource.TestCheckResourceAttr("aws_lb_target_group.test", "health_check.0.port", "8081"), resource.TestCheckResourceAttr("aws_lb_target_group.test", "health_check.0.protocol", "HTTP"), resource.TestCheckResourceAttr("aws_lb_target_group.test", "health_check.0.timeout", "3"), resource.TestCheckResourceAttr("aws_lb_target_group.test", "health_check.0.healthy_threshold", "3"), + testAccCheckAWSLBTargetGroupHealthyThreshold(&conf, 3), resource.TestCheckResourceAttr("aws_lb_target_group.test", "health_check.0.unhealthy_threshold", "3"), + testAccCheckAWSLBTargetGroupUnhealthyThreshold(&conf, 3), resource.TestCheckResourceAttr("aws_lb_target_group.test", "health_check.0.matcher", "200-299"), ), }, @@ -393,11 +431,14 @@ func TestAccAWSLBTargetGroup_updateHealthCheck(t *testing.T) { resource.TestCheckResourceAttr("aws_lb_target_group.test", "health_check.#", "1"), resource.TestCheckResourceAttr("aws_lb_target_group.test", "health_check.0.path", "/health2"), resource.TestCheckResourceAttr("aws_lb_target_group.test", "health_check.0.interval", "30"), + testAccCheckAWSLBTargetGroupHealthCheckInterval(&conf, 30), resource.TestCheckResourceAttr("aws_lb_target_group.test", "health_check.0.port", "8082"), resource.TestCheckResourceAttr("aws_lb_target_group.test", "health_check.0.protocol", "HTTPS"), resource.TestCheckResourceAttr("aws_lb_target_group.test", "health_check.0.timeout", "4"), resource.TestCheckResourceAttr("aws_lb_target_group.test", "health_check.0.healthy_threshold", "4"), + testAccCheckAWSLBTargetGroupHealthyThreshold(&conf, 4), resource.TestCheckResourceAttr("aws_lb_target_group.test", "health_check.0.unhealthy_threshold", "4"), + testAccCheckAWSLBTargetGroupUnhealthyThreshold(&conf, 4), resource.TestCheckResourceAttr("aws_lb_target_group.test", "health_check.0.matcher", "200"), ), }, @@ -521,6 +562,62 @@ func testAccCheckAWSLBTargetGroupExists(n string, res *elbv2.TargetGroup) resour } } +func testAccCheckAWSLBTargetGroupHealthCheckInterval(res *elbv2.TargetGroup, expected int64) resource.TestCheckFunc { + return func(s *terraform.State) error { + if res.HealthCheckIntervalSeconds == nil { + return fmt.Errorf("Expected HealthCheckIntervalSeconds to be %d, given: %#v", + expected, res.HealthCheckIntervalSeconds) + } + if *res.HealthCheckIntervalSeconds != expected { + return fmt.Errorf("Expected HealthCheckIntervalSeconds to be %d, given: %d", + expected, *res.HealthCheckIntervalSeconds) + } + return nil + } +} + +func testAccCheckAWSLBTargetGroupHealthCheckTimeout(res *elbv2.TargetGroup, expected int64) resource.TestCheckFunc { + return func(s *terraform.State) error { + if res.HealthCheckTimeoutSeconds == nil { + return fmt.Errorf("Expected HealthCheckTimeoutSeconds to be %d, given: %#v", + expected, res.HealthCheckTimeoutSeconds) + } + if *res.HealthCheckTimeoutSeconds != expected { + return fmt.Errorf("Expected HealthCheckTimeoutSeconds to be %d, given: %d", + expected, *res.HealthCheckTimeoutSeconds) + } + return nil + } +} + +func testAccCheckAWSLBTargetGroupHealthyThreshold(res *elbv2.TargetGroup, expected int64) resource.TestCheckFunc { + return func(s *terraform.State) error { + if res.HealthyThresholdCount == nil { + return fmt.Errorf("Expected HealthyThresholdCount to be %d, given: %#v", + expected, res.HealthyThresholdCount) + } + if *res.HealthyThresholdCount != expected { + return fmt.Errorf("Expected HealthyThresholdCount to be %d, given: %d", + expected, *res.HealthyThresholdCount) + } + return nil + } +} + +func testAccCheckAWSLBTargetGroupUnhealthyThreshold(res *elbv2.TargetGroup, expected int64) resource.TestCheckFunc { + return func(s *terraform.State) error { + if res.UnhealthyThresholdCount == nil { + return fmt.Errorf("Expected.UnhealthyThresholdCount to be %d, given: %#v", + expected, res.UnhealthyThresholdCount) + } + if *res.UnhealthyThresholdCount != expected { + return fmt.Errorf("Expected.UnhealthyThresholdCount to be %d, given: %d", + expected, *res.UnhealthyThresholdCount) + } + return nil + } +} + func testAccCheckAWSLBTargetGroupDestroy(s *terraform.State) error { conn := testAccProvider.Meta().(*AWSClient).elbv2conn @@ -839,10 +936,9 @@ func testAccAWSLBTargetGroupConfig_typeTCP(targetGroupName string) string { deregistration_delay = 200 health_check { - interval = 30 + interval = 10 port = "traffic-port" protocol = "TCP" - timeout = 10 healthy_threshold = 3 unhealthy_threshold = 3 } @@ -861,6 +957,68 @@ resource "aws_vpc" "test" { }`, targetGroupName) } +func testAccAWSLBTargetGroupConfig_typeTCPThresholdUpdated(targetGroupName string) string { + return fmt.Sprintf(`resource "aws_lb_target_group" "test" { + name = "%s" + port = 8082 + protocol = "TCP" + vpc_id = "${aws_vpc.test.id}" + + deregistration_delay = 200 + + health_check { + interval = 10 + port = "traffic-port" + protocol = "TCP" + healthy_threshold = 5 + unhealthy_threshold = 5 + } + + tags { + Name = "TestAcc_networkLB_TargetGroup" + } +} + +resource "aws_vpc" "test" { + cidr_block = "10.0.0.0/16" + + tags { + Name = "TestAcc_networkLB_TargetGroup" + } +}`, targetGroupName) +} + +func testAccAWSLBTargetGroupConfig_typeTCPIntervalUpdated(targetGroupName string) string { + return fmt.Sprintf(`resource "aws_lb_target_group" "test" { + name = "%s" + port = 8082 + protocol = "TCP" + vpc_id = "${aws_vpc.test.id}" + + deregistration_delay = 200 + + health_check { + interval = 30 + port = "traffic-port" + protocol = "TCP" + healthy_threshold = 5 + unhealthy_threshold = 5 + } + + tags { + Name = "TestAcc_networkLB_TargetGroup" + } +} + +resource "aws_vpc" "test" { + cidr_block = "10.0.0.0/16" + + tags { + Name = "TestAcc_networkLB_TargetGroup" + } +}`, targetGroupName) +} + func testAccAWSLBTargetGroupConfig_stickiness(targetGroupName string, addStickinessBlock bool, enabled bool) string { var stickinessBlock string From 77cd556319c6a59f6619151aa61f3d60ff3210f9 Mon Sep 17 00:00:00 2001 From: Radek Simko Date: Thu, 16 Nov 2017 14:47:38 +0000 Subject: [PATCH 2/2] r/lb_target_group: Respect threshold & error on interval change for TCP-based TGs --- aws/resource_aws_lb_target_group.go | 34 ++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/aws/resource_aws_lb_target_group.go b/aws/resource_aws_lb_target_group.go index b5317ad753b..4f1fa2c57c6 100644 --- a/aws/resource_aws_lb_target_group.go +++ b/aws/resource_aws_lb_target_group.go @@ -22,6 +22,9 @@ func resourceAwsLbTargetGroup() *schema.Resource { Read: resourceAwsLbTargetGroupRead, Update: resourceAwsLbTargetGroupUpdate, Delete: resourceAwsLbTargetGroupDelete, + + // Health Check Interval is not updatable for TCP-based Target Groups + CustomizeDiff: resourceAwsLbTargetGroupCustomizeDiff, Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, }, @@ -210,6 +213,7 @@ func resourceAwsLbTargetGroupCreate(d *schema.ResourceData, meta interface{}) er params.HealthCheckPort = aws.String(healthCheck["port"].(string)) params.HealthCheckProtocol = aws.String(healthCheck["protocol"].(string)) params.HealthyThresholdCount = aws.Int64(int64(healthCheck["healthy_threshold"].(int))) + params.UnhealthyThresholdCount = aws.Int64(int64(healthCheck["unhealthy_threshold"].(int))) if *params.Protocol != "TCP" { params.HealthCheckTimeoutSeconds = aws.Int64(int64(healthCheck["timeout"].(int))) @@ -217,7 +221,6 @@ func resourceAwsLbTargetGroupCreate(d *schema.ResourceData, meta interface{}) er params.Matcher = &elbv2.Matcher{ HttpCode: aws.String(healthCheck["matcher"].(string)), } - params.UnhealthyThresholdCount = aws.Int64(int64(healthCheck["unhealthy_threshold"].(int))) } } @@ -273,10 +276,11 @@ func resourceAwsLbTargetGroupUpdate(d *schema.ResourceData, meta interface{}) er healthCheck := healthChecks[0].(map[string]interface{}) params = &elbv2.ModifyTargetGroupInput{ - TargetGroupArn: aws.String(d.Id()), - HealthCheckPort: aws.String(healthCheck["port"].(string)), - HealthCheckProtocol: aws.String(healthCheck["protocol"].(string)), - HealthyThresholdCount: aws.Int64(int64(healthCheck["healthy_threshold"].(int))), + TargetGroupArn: aws.String(d.Id()), + HealthCheckPort: aws.String(healthCheck["port"].(string)), + HealthCheckProtocol: aws.String(healthCheck["protocol"].(string)), + HealthyThresholdCount: aws.Int64(int64(healthCheck["healthy_threshold"].(int))), + UnhealthyThresholdCount: aws.Int64(int64(healthCheck["unhealthy_threshold"].(int))), } healthCheckProtocol := strings.ToLower(healthCheck["protocol"].(string)) @@ -287,7 +291,6 @@ func resourceAwsLbTargetGroupUpdate(d *schema.ResourceData, meta interface{}) er } params.HealthCheckPath = aws.String(healthCheck["path"].(string)) params.HealthCheckIntervalSeconds = aws.Int64(int64(healthCheck["interval"].(int))) - params.UnhealthyThresholdCount = aws.Int64(int64(healthCheck["unhealthy_threshold"].(int))) params.HealthCheckTimeoutSeconds = aws.Int64(int64(healthCheck["timeout"].(int))) } } else { @@ -564,3 +567,22 @@ func flattenAwsLbTargetGroupResource(d *schema.ResourceData, meta interface{}, t return nil } + +func resourceAwsLbTargetGroupCustomizeDiff(diff *schema.ResourceDiff, v interface{}) error { + protocol := diff.Get("protocol").(string) + if protocol != "TCP" { + return nil + } + + if diff.Id() == "" { + return nil + } + + if diff.HasChange("health_check.0.interval") { + old, new := diff.GetChange("health_check.0.interval") + return fmt.Errorf("Health check interval cannot be updated from %d to %d for TCP based Target Group %s,"+ + " use 'terraform taint' to recreate the resource if you wish", + old, new, diff.Id()) + } + return nil +}