v0.11.10
v0.11.11
resource "aws_lb" "platform_int" {
count = "${var.is_nlb_internal == true ? 1 : 0}"
name = "nlb-platform-${var.environment}"
internal = true
load_balancer_type = "network"
ip_address_type = "ipv4"
subnet_mapping {
subnet_id = "${var.subnet_id_lb}"
}
tags {
Name = "nlb-platform-${var.environment}"
env = "${var.environment}"
team = "${var.tag_team}"
live = "${var.tag_live}"
visibility = "int"
managed_by = "Terraform"
}
}
The NLB should be left untouched as there are no changes to the subnet allocation.
The NLB is to be deleted and re-created every time as per the output. It seems this is related to the otherwise "optional" attribute allocation_id in the subnet mapping. When the NLB is created as internet-facing with an EIP pre-allocated there is no flopping.
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
-/+ destroy and then create replacement
Terraform will perform the following actions:
-/+ module.lendable_platform.aws_lb.platform_int (new resource required)
id: "arn:aws:elasticloadbalancing:eu-west-1:<redacted>:loadbalancer/net/nlb-platform-prestg/75f75ac883f141a6" => <computed> (forces new resource)
arn: "arn:aws:elasticloadbalancing:eu-west-1:<redacted>:loadbalancer/net/nlb-platform-prestg/75f75ac883f141a6" => <computed>
arn_suffix: "net/nlb-platform-prestg/75f75ac883f141a6" => <computed>
dns_name: "nlb-platform-prestg-75f75ac883f141a6.elb.eu-west-1.amazonaws.com" => <computed>
enable_cross_zone_load_balancing: "false" => "false"
enable_deletion_protection: "false" => "false"
internal: "true" => "true"
ip_address_type: "ipv4" => "ipv4"
load_balancer_type: "network" => "network"
name: "nlb-platform-prestg" => "nlb-platform-prestg"
security_groups.#: "0" => <computed>
subnet_mapping.#: "0" => "1" (forces new resource)
subnet_mapping.3090889211.allocation_id: "" => ""
subnet_mapping.3090889211.subnet_id: "" => "subnet-0f3817005d5e35ad7" (forces new resource)
subnets.#: "1" => <computed>
tags.%: "6" => "6"
tags.Name: "nlb-platform-prestg" => "nlb-platform-prestg"
tags.env: "prestg" => "prestg"
tags.live: "no" => "no"
tags.managed_by: "Terraform" => "Terraform"
tags.team: "appdev" => "appdev"
tags.visibility: "ext" => "int"
vpc_id: "vpc-<redacted>" => <computed>
zone_id: "<redacted>" => <computed>
.
.
.
terraform applyBog standard stuff
This in fact is an old issue: https://github.com/terraform-providers/terraform-provider-aws/issues/3797#issuecomment-386677567
This is happening to me since some time. I was investigating and the issue is on when getting the data to save in the state.
If you define the subnet_mapping with the allocation id, then the availabilityZones object looks like (Faked values to avoid exposing them):
2019-01-31T20:07:02.776-0300 [DEBUG] plugin.terraform-provider-aws_v1.57.0_x4: 2019/01/31 20:07:02 [DEBUG] SUBNET MAPPING: [{
2019-01-31T20:07:02.776-0300 [DEBUG] plugin.terraform-provider-aws_v1.57.0_x4: LoadBalancerAddresses: [{
2019-01-31T20:07:02.776-0300 [DEBUG] plugin.terraform-provider-aws_v1.57.0_x4: AllocationId: "eipalloc-xxxxxxx1",
2019-01-31T20:07:02.776-0300 [DEBUG] plugin.terraform-provider-aws_v1.57.0_x4: IpAddress: "1.1.1.1"
2019-01-31T20:07:02.776-0300 [DEBUG] plugin.terraform-provider-aws_v1.57.0_x4: }],
2019-01-31T20:07:02.776-0300 [DEBUG] plugin.terraform-provider-aws_v1.57.0_x4: SubnetId: "subnet-yyyyy1",
2019-01-31T20:07:02.776-0300 [DEBUG] plugin.terraform-provider-aws_v1.57.0_x4: ZoneName: "us-east-1a"
2019-01-31T20:07:02.776-0300 [DEBUG] plugin.terraform-provider-aws_v1.57.0_x4: } {
2019-01-31T20:07:02.776-0300 [DEBUG] plugin.terraform-provider-aws_v1.57.0_x4: LoadBalancerAddresses: [{
2019-01-31T20:07:02.776-0300 [DEBUG] plugin.terraform-provider-aws_v1.57.0_x4: AllocationId: "eipalloc-xxxxxxx2",
2019-01-31T20:07:02.776-0300 [DEBUG] plugin.terraform-provider-aws_v1.57.0_x4: IpAddress: "1.1.1.2"
2019-01-31T20:07:02.776-0300 [DEBUG] plugin.terraform-provider-aws_v1.57.0_x4: }],
2019-01-31T20:07:02.776-0300 [DEBUG] plugin.terraform-provider-aws_v1.57.0_x4: SubnetId: "subnet-yyyyy2",
2019-01-31T20:07:02.776-0300 [DEBUG] plugin.terraform-provider-aws_v1.57.0_x4: ZoneName: "us-east-1c"
2019-01-31T20:07:02.776-0300 [DEBUG] plugin.terraform-provider-aws_v1.57.0_x4: } {
2019-01-31T20:07:02.776-0300 [DEBUG] plugin.terraform-provider-aws_v1.57.0_x4: LoadBalancerAddresses: [{
2019-01-31T20:07:02.776-0300 [DEBUG] plugin.terraform-provider-aws_v1.57.0_x4: AllocationId: "eipalloc-xxxxxxx3",
2019-01-31T20:07:02.776-0300 [DEBUG] plugin.terraform-provider-aws_v1.57.0_x4: IpAddress: "1.1.1.3"
2019-01-31T20:07:02.776-0300 [DEBUG] plugin.terraform-provider-aws_v1.57.0_x4: }],
2019-01-31T20:07:02.776-0300 [DEBUG] plugin.terraform-provider-aws_v1.57.0_x4: SubnetId: "subnet-yyyyy3",
2019-01-31T20:07:02.776-0300 [DEBUG] plugin.terraform-provider-aws_v1.57.0_x4: ZoneName: "us-east-1e"
2019-01-31T20:07:02.776-0300 [DEBUG] plugin.terraform-provider-aws_v1.57.0_x4: } {
2019-01-31T20:07:02.776-0300 [DEBUG] plugin.terraform-provider-aws_v1.57.0_x4: LoadBalancerAddresses: [{
2019-01-31T20:07:02.776-0300 [DEBUG] plugin.terraform-provider-aws_v1.57.0_x4: AllocationId: "eipalloc-xxxxxxx4",
2019-01-31T20:07:02.776-0300 [DEBUG] plugin.terraform-provider-aws_v1.57.0_x4: IpAddress: "1.1.1.4"
2019-01-31T20:07:02.776-0300 [DEBUG] plugin.terraform-provider-aws_v1.57.0_x4: }],
2019-01-31T20:07:02.776-0300 [DEBUG] plugin.terraform-provider-aws_v1.57.0_x4: SubnetId: "subnet-yyyyy4",
2019-01-31T20:07:02.776-0300 [DEBUG] plugin.terraform-provider-aws_v1.57.0_x4: ZoneName: "us-east-1d"
2019-01-31T20:07:02.776-0300 [DEBUG] plugin.terraform-provider-aws_v1.57.0_x4: }]
But, if the subnet_mapping does not contain the allocation id, then it looks as you would have defined the subnets using subnets:
2019-01-31T28:02:02.171-0300 [DEBUG] plugin.terraform-provider-aws_v1.57.0_x4: 2019/01/31 20:07:02 [DEBUG] SUBNET MAPPING: [{
2019-01-31T28:02:02.171-0300 [DEBUG] plugin.terraform-provider-aws_v1.57.0_x4: SubnetId: "subnet-yyyyy1",
2019-01-31T28:02:02.171-0300 [DEBUG] plugin.terraform-provider-aws_v1.57.0_x4: ZoneName: "us-east-1a"
2019-01-31T28:02:02.171-0300 [DEBUG] plugin.terraform-provider-aws_v1.57.0_x4: } {
2019-01-31T28:02:02.171-0300 [DEBUG] plugin.terraform-provider-aws_v1.57.0_x4: SubnetId: "subnet-yyyyy2",
2019-01-31T28:02:02.171-0300 [DEBUG] plugin.terraform-provider-aws_v1.57.0_x4: ZoneName: "us-east-1c"
2019-01-31T28:02:02.171-0300 [DEBUG] plugin.terraform-provider-aws_v1.57.0_x4: } {
2019-01-31T28:02:02.171-0300 [DEBUG] plugin.terraform-provider-aws_v1.57.0_x4: SubnetId: "subnet-yyyyy3",
2019-01-31T28:02:02.171-0300 [DEBUG] plugin.terraform-provider-aws_v1.57.0_x4: ZoneName: "us-east-1e"
2019-01-31T28:02:02.171-0300 [DEBUG] plugin.terraform-provider-aws_v1.57.0_x4: } {
2019-01-31T28:02:02.171-0300 [DEBUG] plugin.terraform-provider-aws_v1.57.0_x4: SubnetId: "subnet-yyyyy4",
2019-01-31T28:02:02.171-0300 [DEBUG] plugin.terraform-provider-aws_v1.57.0_x4: ZoneName: "us-east-1d"
2019-01-31T28:02:02.171-0300 [DEBUG] plugin.terraform-provider-aws_v1.57.0_x4: }]
The data to the state is flatten and recovered by the availabilityZones structure for both subnets and subnet_mapping. The value for subnet_mapping is recovered specifically from availabilityZone.LoadBalancerAddresses:
func flattenSubnetsFromAvailabilityZones(availabilityZones []*elbv2.AvailabilityZone) []string {
var result []string
for _, az := range availabilityZones {
result = append(result, aws.StringValue(az.SubnetId))
}
return result
}
func flattenSubnetMappingsFromAvailabilityZones(availabilityZones []*elbv2.AvailabilityZone) []map[string]interface{} {
l := make([]map[string]interface{}, 0)
for _, availabilityZone := range availabilityZones {
for _, loadBalancerAddress := range availabilityZone.LoadBalancerAddresses {
m := make(map[string]interface{})
m["subnet_id"] = aws.StringValue(availabilityZone.SubnetId)
if loadBalancerAddress.AllocationId != nil {
m["allocation_id"] = aws.StringValue(loadBalancerAddress.AllocationId)
}
l = append(l, m)
}
}
return l
}
Thus, as availabilityZone.LoadBalancerAddresses is empty when using subnet_mapping without the allocation id, it seems to not be a way to differentiate between the following state results:
subnets = [ "subnet-xxxx1", "subnet-xxxx2" ]
or
subnet_mapping {
subnet_id = "subnet-xxxx1"
}
subnet_mapping {
subnet_id = "subnet-xxxx2"
}
Ignoring it would be an ugly workaround.. but I don't see another better approach so far:
lifecycle {
ignore_changes = ["subnet_mapping"]
}
I've created the PR #7434 that should ensure subnet_mapping is saved on creation/update. Let's wait for feedback from collaborators and owners.
@facundovictor thanks for the reply. I'm, in fact, ignoring the changes till this is not fixed. As workarounds go it is fine.
@zskulcsar how are you ignoring the changes? This is preventing me from updating production, as the 'flapping' causes an unnecessary rebuild of my network load-balancers, which would take all 21 product clusters out-of-service and create issues related to DNS replication for long-cache customers. I am literally dead in the water due to the issue.
@johntoups see lifecycle section at the end:
resource "aws_lb" "platform_int" {
count = "${var.is_nlb_internal == true ? 1 : 0}"
name = "nlb-platform-${var.environment}"
internal = true
load_balancer_type = "network"
ip_address_type = "ipv4"
subnet_mapping {
subnet_id = "${var.subnet_id_lb}"
}
lifecycle {
ignore_changes = ["subnet_mapping"]
}
}
For reference: https://www.terraform.io/docs/configuration/resources.html#lifecycle
The fix to prevent the difference when allocation_id is omitted has been merged and will release with version 2.8.0 of the Terraform AWS Provider, likely later this week. 👍
This has been released in version 2.8.0 of the Terraform AWS provider. Please see the Terraform documentation on provider versioning or reach out if you need any assistance upgrading.
I'm going to lock this issue because it has been closed for _30 days_ ⏳. This helps our maintainers find and focus on the active issues.
If you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. Thanks!
Most helpful comment
The fix to prevent the difference when
allocation_idis omitted has been merged and will release with version 2.8.0 of the Terraform AWS Provider, likely later this week. 👍