linode / terraform-provider-linode

Terraform Linode provider
https://www.terraform.io/docs/providers/linode/
Mozilla Public License 2.0
197 stars 94 forks source link

[Bug]: Cannot find `linode_nodebalancer_node` when updating in place #1224

Closed drsooch closed 8 months ago

drsooch commented 8 months ago

Terraform Version

v1.6.1 linux_amd64

Linode Provider Version

1.29.4

Effected Terraform Resources

linode_nodebalancer_node

Terraform Config Files

resource "linode_nodebalancer" "foo" {
  label  = "foo-node-balancer"
  region = local.region
}

resource "linode_nodebalancer_config" "foo" {
  nodebalancer_id = linode_nodebalancer.foo.id

   ...
}

resource "linode_nodebalancer_node" "foo" {
  count = local.instance_count

  label = "${local.name}-node-balancer-node-${count.index}"

  nodebalancer_id = linode_nodebalancer.foo.id
  config_id       = linode_nodebalancer_config.foo.id

  address = "${element(linode_instance.foo.*.private_ip_address, count.index)}:80"
}

resource "linode_instance" "foo" {
  count = local.instance_count

  label           = "${local.name}-instance-${count.index}"
  image           = var.image_id
  region          = local.region
  type            = local.compute_instance_type
  private_ip      = true
}

Debug Output

https://gist.github.com/drsooch/33835a9102ed42e91c0e57472b447166

Panic Output

No response

Expected Behavior

When this terraform is applied and after the linode_instances are created, updating the linode_nodebalancer_node should successfully be updated/found.

Actual Behavior

Terraform fails to apply with a 404 Not Found for the linode_nodebalancer_node. A subsequent apply will complete successfully.

Steps to Reproduce

  1. This terraform has been applied before and there are existing balancers, instances, and nodes
  2. Make a change (for instance the image) to the linode_instances to force them to be re-created
  3. Apply the terraform
  4. Error
zliang-akamai commented 8 months ago

Hi @drsooch, thank you for the bug report! I was able to reproduce this issue, and we will look into it further. We will let you know when there is a fix available.

lgarber-akamai commented 8 months ago

Hello @drsooch !

We have encountered this issue in the past and unfortunately there is not much we can do to address this from a provider perspective. That said, I did find a workaround using the lifecycle.replace_triggered_by meta-argument that should resolve your issue:

resource "linode_nodebalancer" "foo" {
  label  = "foo-node-balancer"
  region = "us-mia"
}

resource "linode_nodebalancer_config" "foo" {
  nodebalancer_id = linode_nodebalancer.foo.id
}

resource "linode_nodebalancer_node" "foo" {
  label = "foobar"

  nodebalancer_id = linode_nodebalancer.foo.id
  config_id       = linode_nodebalancer_config.foo.id
  address = "${linode_instance.foo.private_ip_address}:80"

  lifecycle {
    // Tell Terraform to implicitly recreate the NodeBalancer node when
    // the target instance has been marked for recreation.
    replace_triggered_by = [linode_instance.foo.id]
  }
}

resource "linode_instance" "foo" {
  label           = "foobar"
  region          = "us-mia"
  type            = "g6-nanode-1"
  private_ip      = true
}

I'll put up a pull request to mention this workaround in the resource documentation :slightly_smiling_face:

Technical Explanation

This issue is the result of a piece of functionality in the Linode API that causes NodeBalancer nodes to be implicitly removed when the corresponding instance is removed. Because this implicit deletion happens after the linode_nodebalancer_node resource read function has been called, the provider cannot mark the node resource for recreation during the same apply.

drsooch commented 8 months ago

Awesome will give that a try later today. I assumed that this was less of a bug and more of a mismatch between terraform and linode api!

Thanks feel free to close!