From 067b2e0e2c1784aeff9d1f0af10549865ecd3a1d Mon Sep 17 00:00:00 2001 From: Omar Gonzalez Date: Tue, 30 Nov 2021 14:48:18 -0800 Subject: [PATCH 1/4] add ip_address_type to lb_target_group --- internal/service/elbv2/target_group.go | 21 +++ .../service/elbv2/target_group_data_source.go | 4 + internal/service/elbv2/target_group_test.go | 166 ++++++++++++++++++ website/docs/r/lb_target_group.html.markdown | 1 + 4 files changed, 192 insertions(+) diff --git a/internal/service/elbv2/target_group.go b/internal/service/elbv2/target_group.go index 2ee94e1e5038..e528773a1459 100644 --- a/internal/service/elbv2/target_group.go +++ b/internal/service/elbv2/target_group.go @@ -124,6 +124,13 @@ func ResourceTargetGroup() *schema.Resource { }, }, }, + "ip_address_type": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Default: elbv2.TargetGroupIpAddressTypeEnumIpv4, + ValidateFunc: validation.StringInSlice(elbv2.TargetGroupIpAddressTypeEnum_Values(), true), + }, "lambda_multi_value_headers_enabled": { Type: schema.TypeBool, Optional: true, @@ -330,6 +337,16 @@ func resourceTargetGroupCreate(d *schema.ResourceData, meta interface{}) error { params.VpcId = aws.String(d.Get("vpc_id").(string)) } + if d.Get("target_type").(string) == elbv2.TargetTypeEnumIp { + params.IpAddressType = aws.String(d.Get("ip_address_type").(string)) + } else { + if _, ok := d.GetOk("ip_address_type"); ok { + if d.Get("ip_address_type").(string) == elbv2.TargetGroupIpAddressTypeEnumIpv6 { + return fmt.Errorf("IPv6 target groups only support IP type targets") + } + } + } + if healthChecks := d.Get("health_check").([]interface{}); len(healthChecks) == 1 { healthCheck := healthChecks[0].(map[string]interface{}) @@ -893,6 +910,10 @@ func flattenTargetGroupResource(d *schema.ResourceData, meta interface{}, target d.Set("protocol", targetGroup.Protocol) } + if v, _ := d.Get("target_type").(string); v == elbv2.TargetTypeEnumIp { + d.Set("ip_address_type", targetGroup.IpAddressType) + } + switch d.Get("protocol").(string) { case elbv2.ProtocolEnumHttp, elbv2.ProtocolEnumHttps: d.Set("protocol_version", targetGroup.ProtocolVersion) diff --git a/internal/service/elbv2/target_group_data_source.go b/internal/service/elbv2/target_group_data_source.go index fe1bdcb8d9e5..f33c95302d24 100644 --- a/internal/service/elbv2/target_group_data_source.go +++ b/internal/service/elbv2/target_group_data_source.go @@ -76,6 +76,10 @@ func DataSourceTargetGroup() *schema.Resource { }, }, }, + "ip_address_type": { + Type: schema.TypeString, + Computed: true, + }, "lambda_multi_value_headers_enabled": { Type: schema.TypeBool, Computed: true, diff --git a/internal/service/elbv2/target_group_test.go b/internal/service/elbv2/target_group_test.go index 91eb6f2471c3..1c728b5f7532 100644 --- a/internal/service/elbv2/target_group_test.go +++ b/internal/service/elbv2/target_group_test.go @@ -444,6 +444,83 @@ func TestAccELBV2TargetGroup_basicUdp(t *testing.T) { }) } +func TestAccELBV2TargetGroup_basicIPv6(t *testing.T) { + var conf elbv2.TargetGroup + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_lb_target_group.test" + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, elbv2.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckTargetGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccTargetGroupConfig_basicIPv6(rName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckTargetGroupExists(resourceName, &conf), + resource.TestCheckResourceAttrSet(resourceName, "arn"), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "ip_address_type", "ipv6"), + resource.TestCheckResourceAttr(resourceName, "port", "514"), + resource.TestCheckResourceAttr(resourceName, "protocol", "TCP"), + resource.TestCheckResourceAttrSet(resourceName, "vpc_id"), + resource.TestCheckResourceAttr(resourceName, "health_check.#", "1"), + resource.TestCheckResourceAttr(resourceName, "health_check.0.port", "514"), + resource.TestCheckResourceAttr(resourceName, "health_check.0.protocol", "TCP"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.Name", rName), + ), + }, + }, + }) +} + +func TestAccELBV2TargetGroup_changeIPAddressTypeForceNew(t *testing.T) { + var before, after elbv2.TargetGroup + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_lb_target_group.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, elbv2.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckTargetGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccTargetGroupConfig_basicIPv4(rName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckTargetGroupExists(resourceName, &before), + resource.TestCheckResourceAttr(resourceName, "ip_address_type", "ipv4"), + ), + }, + { + Config: testAccTargetGroupConfig_basicIPv6(rName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckTargetGroupExists(resourceName, &after), + resource.TestCheckResourceAttr(resourceName, "ip_address_type", "ipv6"), + ), + }, + }, + }) +} + +func TestAccELBV2TargetGroup_targetTypeInvalidWithIPv6(t *testing.T) { + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, elbv2.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckTargetGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccTargetGroupConfig_invalidIPv6(rName), + ExpectError: regexp.MustCompile("IPv6 target groups only support IP type targets"), + }, + }, + }) +} + func TestAccELBV2TargetGroup_changeNameForceNew(t *testing.T) { var before, after elbv2.TargetGroup rNameBefore := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -2499,6 +2576,95 @@ resource "aws_vpc" "test" { `, rName) } +func testAccTargetGroupConfig_basicIPv4(rName string) string { + return fmt.Sprintf(` +resource "aws_lb_target_group" "test" { + name = %[1]q + ip_address_type = "ipv4" + port = 514 + protocol = "TCP" + target_type = "ip" + vpc_id = aws_vpc.test.id + + health_check { + protocol = "TCP" + port = 514 + } + + tags = { + Name = %[1]q + } +} + +resource "aws_vpc" "test" { + cidr_block = "10.0.0.0/16" + + tags = { + Name = %[1]q + } +} +`, rName) +} + +func testAccTargetGroupConfig_basicIPv6(rName string) string { + return fmt.Sprintf(` +resource "aws_lb_target_group" "test" { + name = %[1]q + ip_address_type = "ipv6" + port = 514 + protocol = "TCP" + target_type = "ip" + vpc_id = aws_vpc.test.id + + health_check { + protocol = "TCP" + port = 514 + } + + tags = { + Name = %[1]q + } +} + +resource "aws_vpc" "test" { + cidr_block = "10.0.0.0/16" + + tags = { + Name = %[1]q + } +} +`, rName) +} + +func testAccTargetGroupConfig_invalidIPv6(rName string) string { + return fmt.Sprintf(` +resource "aws_lb_target_group" "test" { + name = %[1]q + ip_address_type = "ipv6" + port = 514 + protocol = "TCP" + vpc_id = aws_vpc.test.id + + health_check { + protocol = "TCP" + port = 514 + } + + tags = { + Name = %[1]q + } +} + +resource "aws_vpc" "test" { + cidr_block = "10.0.0.0/16" + + tags = { + Name = %[1]q + } +} +`, rName) +} + func testAccTargetGroupConfig_enableHealthcheck(rName string) string { return fmt.Sprintf(` resource "aws_lb_target_group" "test" { diff --git a/website/docs/r/lb_target_group.html.markdown b/website/docs/r/lb_target_group.html.markdown index f1ac369f1fe4..9a40c28038e8 100644 --- a/website/docs/r/lb_target_group.html.markdown +++ b/website/docs/r/lb_target_group.html.markdown @@ -61,6 +61,7 @@ The following arguments are supported: * `connection_termination` - (Optional) Whether to terminate connections at the end of the deregistration timeout on Network Load Balancers. See [doc](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/load-balancer-target-groups.html#deregistration-delay) for more information. Default is `false`. * `deregistration_delay` - (Optional) Amount time for Elastic Load Balancing to wait before changing the state of a deregistering target from draining to unused. The range is 0-3600 seconds. The default value is 300 seconds. * `health_check` - (Optional, Maximum of 1) Health Check configuration block. Detailed below. +* `ip_address_type` - (Optional, Forces new resource) When `target_type` is `ip`, specifies desired address family. Supported values are `ipv4` and `ipv6`. Default is `ipv4`. See [doc](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/load-balancer-target-groups.html#target-group-ip-address-type) for more information. * `lambda_multi_value_headers_enabled` - (Optional) Whether the request and response headers exchanged between the load balancer and the Lambda function include arrays of values or strings. Only applies when `target_type` is `lambda`. Default is `false`. * `load_balancing_algorithm_type` - (Optional) Determines how the load balancer selects targets when routing requests. Only applicable for Application Load Balancer Target Groups. The value is `round_robin` or `least_outstanding_requests`. The default is `round_robin`. * `name_prefix` - (Optional, Forces new resource) Creates a unique name beginning with the specified prefix. Conflicts with `name`. Cannot be longer than 6 characters. From a20db5c7f9d3491e4f3739f715327748c3885a20 Mon Sep 17 00:00:00 2001 From: Omar Gonzalez Date: Tue, 30 Nov 2021 15:03:00 -0800 Subject: [PATCH 2/4] adding changelog --- .changelog/21973.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/21973.txt diff --git a/.changelog/21973.txt b/.changelog/21973.txt new file mode 100644 index 000000000000..fbda2dd88f16 --- /dev/null +++ b/.changelog/21973.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/aws_lb_target_group: Add `ip_address_type` attribute +``` From 6bebdf1748c3e28c91436c6209735382cd8cc323 Mon Sep 17 00:00:00 2001 From: Omar Gonzalez Date: Tue, 30 Nov 2021 15:20:12 -0800 Subject: [PATCH 3/4] ignore ip_address_type in TestAccELBV2TargetGroup_A_lambdaMultiValueHeadersEnabled the only valid value is "ipv4" --- internal/service/elbv2/target_group_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/service/elbv2/target_group_test.go b/internal/service/elbv2/target_group_test.go index 1c728b5f7532..b924b580e0c4 100644 --- a/internal/service/elbv2/target_group_test.go +++ b/internal/service/elbv2/target_group_test.go @@ -1819,6 +1819,7 @@ func TestAccELBV2TargetGroup_A_lambdaMultiValueHeadersEnabled(t *testing.T) { ImportStateVerifyIgnore: []string{ "connection_termination", "deregistration_delay", + "ip_address_type", "proxy_protocol_v2", "slow_start", "load_balancing_algorithm_type", From 6d82c04fb770fe136deac1b01419f4f9f59b7bdb Mon Sep 17 00:00:00 2001 From: Omar Gonzalez Date: Tue, 30 Nov 2021 16:05:38 -0800 Subject: [PATCH 4/4] ignore ip_address_type in additional tests the only valid value is "ipv4" --- internal/service/elbv2/target_group_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/internal/service/elbv2/target_group_test.go b/internal/service/elbv2/target_group_test.go index b924b580e0c4..b826dc0f0a0d 100644 --- a/internal/service/elbv2/target_group_test.go +++ b/internal/service/elbv2/target_group_test.go @@ -1009,6 +1009,7 @@ func TestAccELBV2TargetGroup_protocolGeneve(t *testing.T) { ImportStateVerify: true, ImportStateVerifyIgnore: []string{ "connection_termination", + "ip_address_type", "lambda_multi_value_headers_enabled", "proxy_protocol_v2", "slow_start", @@ -1784,6 +1785,7 @@ func TestAccELBV2TargetGroup_A_lambda(t *testing.T) { ImportStateVerifyIgnore: []string{ "connection_termination", "deregistration_delay", + "ip_address_type", "proxy_protocol_v2", "slow_start", "load_balancing_algorithm_type",