Why terraform thinks that I changed many atttributes from "" to null?

Viewed 986

I just executed terraform plan and it report a lots of spurious changes. It reports that it needs to recreate a lot of resource because some attributes that were ""(empty string) are not null.

For example it think that I changed this route in

route            = [
      - {
          - cidr_block                = "0.0.0.0/0"
          - egress_only_gateway_id    = ""
          - gateway_id                = "igw-xxxx"
          - instance_id               = ""
          - ipv6_cidr_block           = ""
          - nat_gateway_id            = ""
          - network_interface_id      = ""
          - transit_gateway_id        = ""
          - vpc_peering_connection_id = ""
        },
      + {
          + cidr_block                = "0.0.0.0/0"
          + egress_only_gateway_id    = null
          + gateway_id                = "igw-xxxx"
          + instance_id               = null
          + ipv6_cidr_block           = null
          + nat_gateway_id            = null
          + network_interface_id      = null
          + transit_gateway_id        = null
          + vpc_peering_connection_id = null
        },

As far as I can tell, there is no actual change (in the terraform configuration) so I suspect this must be some discrepancy betweent the stores state and how terraform computes the "desired" state.

What is causing this? Is this a change between terraform 0.13.1 and 0.13.5?

1 Answers

I ran into the same issue. This reply nailed the workaround: https://discuss.hashicorp.com/t/terraform-wants-to-replace-many-resources-because-it-detects-that-null/17845/2

I'm not sure when or how this is bug was introduced in the AWS provider, but it cropped up for me after upgrading from 0.11.14 to 0.12.28.

If you explicitly define all of these null values, Terraform stops seeing this as a change.

   route {
-    cidr_block = "0.0.0.0/0"
-    gateway_id = "igw-ID"
+    cidr_block                = "0.0.0.0/0"
+    gateway_id                = "igw-ID"
+    egress_only_gateway_id    = ""
+    instance_id               = ""
+    ipv6_cidr_block           = ""
+    nat_gateway_id            = ""
+    network_interface_id      = ""
+    transit_gateway_id        = ""
+    vpc_peering_connection_id = ""

Changes my plan from destroying and recreating all of the routes to just adding a new route (anonymized values):

  # aws_route_table.main-vpc-ID will be updated in-place
  ~ resource "aws_route_table" "main-vpc-ID" {
        id               = "rtb-ID"
        owner_id         = "accountid"
        propagating_vgws = []
      ~ route            = [
            {
                cidr_block                = "0.0.0.0/0"
                egress_only_gateway_id    = ""
                gateway_id                = "igw-ID"
                instance_id               = ""
                ipv6_cidr_block           = ""
                nat_gateway_id            = ""
                network_interface_id      = ""
                transit_gateway_id        = ""
                vpc_peering_connection_id = ""
            },
          + {
              + cidr_block                = "10.100.2.0/24"
Related