Skip to content

Commit 888a8c5

Browse files
committed
feat: support in-place NLB subnet changes
Fixes #41418.
1 parent 3e61156 commit 888a8c5

File tree

6 files changed

+21
-1174
lines changed

6 files changed

+21
-1174
lines changed

CHANGELOG.md

Lines changed: 0 additions & 1140 deletions
This file was deleted.

internal/service/elbv2/load_balancer.go

Lines changed: 13 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1281,24 +1281,19 @@ func suffixFromARN(arn *string) string {
12811281
return ""
12821282
}
12831283

1284-
// Load balancers of type 'network' cannot have their subnets updated,
1285-
// cannot have security groups added if none are present, and cannot have
1286-
// all security groups removed. If the type is 'network' and any of these
1287-
// conditions are met, mark the diff as a ForceNew operation.
1284+
// Load balancers of type 'network' cannot have security groups added if none
1285+
// are present, and cannot have all security groups removed. If the type is
1286+
// 'network' and any of these conditions are met, mark the diff as a ForceNew operation.
12881287
func customizeDiffLoadBalancerNLB(_ context.Context, diff *schema.ResourceDiff, v any) error {
12891288
// The current criteria for determining if the operation should be ForceNew:
12901289
// - lb of type "network"
12911290
// - existing resource (id is not "")
1292-
// - there are subnet removals
1293-
// OR security groups are being added where none currently exist
1291+
// - security groups are being added where none currently exist
12941292
// OR all security groups are being removed
12951293
// OR secondary IPv4 addresses are being decreased
12961294
//
1297-
// Any other combination should be treated as normal. At this time, subnet
1298-
// handling is the only known difference between Network Load Balancers and
1299-
// Application Load Balancers, so the logic below is simple individual checks.
1300-
// If other differences arise we'll want to refactor to check other
1301-
// conditions in combinations, but for now all we handle is subnets
1295+
// Note: As of February 2025, AWS supports full subnet management for NLBs,
1296+
// including adding and removing subnets, matching ALB capabilities.
13021297
if lbType := awstypes.LoadBalancerTypeEnum(diff.Get("load_balancer_type").(string)); lbType != awstypes.LoadBalancerTypeEnumNetwork {
13031298
return nil
13041299
}
@@ -1321,12 +1316,16 @@ func customizeDiffLoadBalancerNLB(_ context.Context, diff *schema.ResourceDiff,
13211316
switch {
13221317
case deltaN == 0:
13231318
// No change in number of subnet mappings, but one of the mappings did change.
1324-
fallthrough
1325-
case deltaN < 0:
1326-
// Subnet mappings removed.
13271319
if err := diff.ForceNew("subnet_mapping"); err != nil {
13281320
return err
13291321
}
1322+
case deltaN < 0:
1323+
// Subnet mappings removed. Ensure that the remaining mappings didn't change.
1324+
if os.Intersection(ns).Len() != ns.Len() {
1325+
if err := diff.ForceNew("subnet_mapping"); err != nil {
1326+
return err
1327+
}
1328+
}
13301329
case deltaN > 0:
13311330
// Subnet mappings added. Ensure that the previous mappings didn't change.
13321331
if ns.Intersection(os).Len() != os.Len() {
@@ -1342,18 +1341,6 @@ func customizeDiffLoadBalancerNLB(_ context.Context, diff *schema.ResourceDiff,
13421341
}
13431342
}
13441343
if hasSubnetsChanges {
1345-
if v := config.GetAttr(names.AttrSubnets); v.IsWhollyKnown() {
1346-
o, n := diff.GetChange(names.AttrSubnets)
1347-
os, ns := o.(*schema.Set), n.(*schema.Set)
1348-
1349-
// In-place increase in number of subnets only.
1350-
if deltaN := ns.Len() - os.Len(); deltaN <= 0 {
1351-
if err := diff.ForceNew(names.AttrSubnets); err != nil {
1352-
return err
1353-
}
1354-
}
1355-
}
1356-
13571344
if err := diff.SetNewComputed("subnet_mapping"); err != nil {
13581345
return err
13591346
}

internal/service/elbv2/load_balancer_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1977,7 +1977,7 @@ func TestAccELBV2LoadBalancer_NetworkLoadBalancer_deleteSubnet(t *testing.T) {
19771977
Config: testAccLoadBalancerConfig_nlbSubnetCount(rName, 2),
19781978
Check: resource.ComposeAggregateTestCheckFunc(
19791979
testAccCheckLoadBalancerExists(ctx, resourceName, &post),
1980-
testAccCheckLoadBalancerRecreated(&post, &pre),
1980+
testAccCheckLoadBalancerNotRecreated(&pre, &post),
19811981
resource.TestCheckResourceAttr(resourceName, "subnets.#", "2"),
19821982
),
19831983
},
@@ -2050,7 +2050,7 @@ func TestAccELBV2LoadBalancer_NetworkLoadBalancer_deleteSubnetMapping(t *testing
20502050
Config: testAccLoadBalancerConfig_nlbSubnetMappingCount(rName, false, false, 2),
20512051
Check: resource.ComposeAggregateTestCheckFunc(
20522052
testAccCheckLoadBalancerExists(ctx, resourceName, &post),
2053-
testAccCheckLoadBalancerRecreated(&pre, &post),
2053+
testAccCheckLoadBalancerNotRecreated(&pre, &post),
20542054
resource.TestCheckResourceAttr(resourceName, "subnet_mapping.#", "2"),
20552055
resource.TestCheckResourceAttr(resourceName, "subnets.#", "2"),
20562056
),

website/docs/cdktf/python/r/lb.html.markdown

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,8 @@ This resource supports the following arguments:
161161
* `security_groups` - (Optional) List of security group IDs to assign to the LB. Only valid for Load Balancers of type `application` or `network`. For load balancers of type `network` security groups cannot be added if none are currently present, and cannot all be removed once added. If either of these conditions are met, this will force a recreation of the resource.
162162
* `preserve_host_header` - (Optional) Whether the Application Load Balancer should preserve the Host header in the HTTP request and send it to the target without any change. Defaults to `false`.
163163
* `secondary_ips_auto_assigned_per_subnet` - (Optional) The number of secondary IP addresses to configure for your load balancer nodes. Only valid for Load Balancers of type `network`. The valid range is 0-7. When decreased, this will force a recreation of the resource. Default: `0`.
164-
* `subnet_mapping` - (Optional) Subnet mapping block. See below. For Load Balancers of type `network` subnet mappings can only be added.
165-
* `subnets` - (Optional) List of subnet IDs to attach to the LB. For Load Balancers of type `network` subnets can only be added (see [Availability Zones](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/network-load-balancers.html#availability-zones)), deleting a subnet for load balancers of type `network` will force a recreation of the resource.
164+
* `subnet_mapping` - (Optional) Subnet mapping block. See below.
165+
* `subnets` - (Optional) List of subnet IDs to attach to the LB. Subnets can be added or removed for Load Balancers of type `network` (see [Availability Zones](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/network-load-balancers.html#availability-zones)).
166166
* `tags` - (Optional) Map of tags to assign to the resource. If configured with a provider [`default_tags` configuration block](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level.
167167
* `xff_header_processing_mode` - (Optional) Determines how the load balancer modifies the `X-Forwarded-For` header in the HTTP request before sending the request to the target. The possible values are `append`, `preserve`, and `remove`. Only valid for Load Balancers of type `application`. The default is `append`.
168168

website/docs/cdktf/typescript/r/lb.html.markdown

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,8 +181,8 @@ This resource supports the following arguments:
181181
* `securityGroups` - (Optional) List of security group IDs to assign to the LB. Only valid for Load Balancers of type `application` or `network`. For load balancers of type `network` security groups cannot be added if none are currently present, and cannot all be removed once added. If either of these conditions are met, this will force a recreation of the resource.
182182
* `preserveHostHeader` - (Optional) Whether the Application Load Balancer should preserve the Host header in the HTTP request and send it to the target without any change. Defaults to `false`.
183183
* `secondaryIpsAutoAssignedPerSubnet` - (Optional) The number of secondary IP addresses to configure for your load balancer nodes. Only valid for Load Balancers of type `network`. The valid range is 0-7. When decreased, this will force a recreation of the resource. Default: `0`.
184-
* `subnetMapping` - (Optional) Subnet mapping block. See below. For Load Balancers of type `network` subnet mappings can only be added.
185-
* `subnets` - (Optional) List of subnet IDs to attach to the LB. For Load Balancers of type `network` subnets can only be added (see [Availability Zones](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/network-load-balancers.html#availability-zones)), deleting a subnet for load balancers of type `network` will force a recreation of the resource.
184+
* `subnetMapping` - (Optional) Subnet mapping block. See below.
185+
* `subnets` - (Optional) List of subnet IDs to attach to the LB. Subnets can be added or removed for Load Balancers of type `network` (see [Availability Zones](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/network-load-balancers.html#availability-zones)).
186186
* `tags` - (Optional) Map of tags to assign to the resource. If configured with a provider [`defaultTags` configuration block](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level.
187187
* `xffHeaderProcessingMode` - (Optional) Determines how the load balancer modifies the `X-Forwarded-For` header in the HTTP request before sending the request to the target. The possible values are `append`, `preserve`, and `remove`. Only valid for Load Balancers of type `application`. The default is `append`.
188188

website/docs/r/lb.html.markdown

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,8 @@ This resource supports the following arguments:
124124
* `security_groups` - (Optional) List of security group IDs to assign to the LB. Only valid for Load Balancers of type `application` or `network`. For load balancers of type `network` security groups cannot be added if none are currently present, and cannot all be removed once added. If either of these conditions are met, this will force a recreation of the resource.
125125
* `preserve_host_header` - (Optional) Whether the Application Load Balancer should preserve the Host header in the HTTP request and send it to the target without any change. Defaults to `false`.
126126
* `secondary_ips_auto_assigned_per_subnet` - (Optional) The number of secondary IP addresses to configure for your load balancer nodes. Only valid for Load Balancers of type `network`. The valid range is 0-7. When decreased, this will force a recreation of the resource. Default: `0`.
127-
* `subnet_mapping` - (Optional) Subnet mapping block. See below. For Load Balancers of type `network` subnet mappings can only be added.
128-
* `subnets` - (Optional) List of subnet IDs to attach to the LB. For Load Balancers of type `network` subnets can only be added (see [Availability Zones](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/network-load-balancers.html#availability-zones)), deleting a subnet for load balancers of type `network` will force a recreation of the resource.
127+
* `subnet_mapping` - (Optional) Subnet mapping block. See below.
128+
* `subnets` - (Optional) List of subnet IDs to attach to the LB. Subnets can be added or removed for Load Balancers of type `network` (see [Availability Zones](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/network-load-balancers.html#availability-zones)).
129129
* `tags` - (Optional) Map of tags to assign to the resource. If configured with a provider [`default_tags` configuration block](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level.
130130
* `xff_header_processing_mode` - (Optional) Determines how the load balancer modifies the `X-Forwarded-For` header in the HTTP request before sending the request to the target. The possible values are `append`, `preserve`, and `remove`. Only valid for Load Balancers of type `application`. The default is `append`.
131131

0 commit comments

Comments
 (0)