aiven / terraform-provider-aiven

Aiven Terraform Provider
https://registry.terraform.io/providers/aiven/aiven/latest/docs
MIT License
129 stars 70 forks source link

Ignore `aiven_transit_gateway_vpc_attachment` `user_peer_network_cidrs` order #1168

Closed supergillis closed 1 year ago

supergillis commented 1 year ago

What happened?

The aiven_transit_gateway_vpc_attachment resource expects user_peer_network_cidrs values to be ordered. If the values are equal but in a different order, then the resource will be updated. This means that the Aiven provider will try to update the resource every time Terraform plan runs.

Using the Terraform sort function is not possible as Aiven sorts the values of the CIDR range by their numeric value. For example, Aiven sorts CIDRs like this ["10.7.192.0/18", "10.227.140.0/23"] (7 is numerically smaller than 227) but Terraform sort will sort CIDRs like this ["10.227.140.0/23", "10.7.192.0/18"] (string "227" is smaller than string "7").

Complete example:

# var.cidrs is equal to ["10.227.140.0/23", "10.7.192.0/18"]

resource "aiven_transit_gateway_vpc_attachment" "timescale" {
  vpc_id             = aiven_project_vpc.timescale.id
  peer_cloud_account = data.aws_caller_identity.workload.account_id
  peer_region        = data.aws_region.workload.name
  peer_vpc           = aws_ec2_transit_gateway.main.id

  user_peer_network_cidrs = var.cidrs

  timeouts {
    create = "10m"
  }
}

This results in the following Terraform plan:

Terraform will perform the following actions:

  # aiven_transit_gateway_vpc_attachment.timescale will be updated in-place
  ~ resource "aiven_transit_gateway_vpc_attachment" "timescale" {
        id                      = "xxx/xxx/xxx/xxx/eu-west-1"
      ~ user_peer_network_cidrs = [
          - "10.227.140.0/23",
          - "10.7.192.0/18",
          + "10.7.192.0/18",
          + "10.227.140.0/23",
        ]
        # (6 unchanged attributes hidden)

        # (1 unchanged block hidden)
    }

I'm using the following workaround right now:

  padded_cidrs = [
    for cidr in var.cidrs :
    join("/", [
      for part in split("/", cidr) :
      join(".", [for num in split(".", part) : format("%03s", num)])
    ])
  ]
  sorted_padded_cidrs = sort(local.padded_cidrs)
  sorted_cidrs = [
    for padded_cidr in local.sorted_padded_cidrs :
    join("/", [
      for part in split("/", padded_cidr) :
      join(".", [for num in split(".", part) : replace(num, "/^0*([\\d]+)/", "$1")])
    ])
  ]
}

What did you expect to happen?

The aiven_transit_gateway_vpc_attachment resource should not update user_peer_network_cidrsif the set of values equals the actual values. It should ignore the order of the values.

What else do we need to know?

Aiven provider version: 4.3.0

Serpentiel commented 1 year ago

hey, @supergillis! šŸ‘‹

please try to do the following in your manifest: user_peer_network_cidrs = toset(var.cidrs)

let me know if the problem persist, thank you!

supergillis commented 1 year ago

Just tried it and it's the same thing as using sort. The CIDR ranges in Terraform are not sorted the same way as in the Aiven platform and every apply tries to reorder the CIDR ranges.

Serpentiel commented 1 year ago

I see, I'll check what could be done about it, thank you

Serpentiel commented 1 year ago

hey, @supergillis! šŸ‘‹

we've introduced a fix with #1171, but were unable to fully test it out

I'll prepare a Release Candidate release for you so you can test it out and provide feedback, thank you!

Serpentiel commented 1 year ago

@supergillis please check if v4.4.0-rc1 fixes the problem, thank you!

supergillis commented 1 year ago

Seems to work now. Thanks!

Serpentiel commented 1 year ago

you welcome, we will prepare a stable release in the coming days šŸ‘