lxc / terraform-provider-incus

Incus provider for Terraform/OpenTofu
https://linuxcontainers.org/incus
Mozilla Public License 2.0
45 stars 10 forks source link

Bug: incus_network_lb inconsistent result after apply #101

Closed trunet closed 1 month ago

trunet commented 1 month ago

It creates the LB just fine, however, it keeps throwing errors every time.

If I set the description for every backend, it works. The provider should or set description as required, or allow the description to be null.

  # incus_network_lb.this will be created
  + resource "incus_network_lb" "this" {
      + config         = (known after apply)
      + description    = "Vault Root LB"
      + listen_address = "10.[REDACTED]"
      + network        = "ovn-[REDACTED]"

      + backend {
          + name           = "vault-root-01"
          + target_address = "10.[REDACTED]"
          + target_port    = "8200"
        }

      + port {
          + description    = "Port 8200/tcp"
          + listen_port    = "8200"
          + protocol       = "tcp"
          + target_backend = [
              + "vault-root-01",
            ]
        }
    }

Plan: 1 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

incus_network_lb.this: Creating...
╷
│ Error: Provider produced inconsistent result after apply
│

│ When applying changes to incus_network_lb.load_balancer, provider
│ "provider[\"registry.terraform.io/lxc/incus\"]" produced an unexpected new value: .backend: planned set
│ element cty.ObjectVal(map[string]cty.Value{"description":cty.NullVal(cty.String),
│ "name":cty.StringVal("vault-root-01"), "target_address":cty.StringVal("10.[REDACTED]"),
│ "target_port":cty.StringVal("8200")}) does not correlate with any element in actual.
maveonair commented 1 month ago

@trunet It would be great if you could provide me with a minimal Terraform example code that led you to this problem.

trunet commented 1 month ago

Should be pretty straightforward. Just create the LB resource and not set a description.

In my case is part of a large module that handles a lot of stuff (netbox registration, ovn network, incus vm or container, image handling, load balancer, ...)

This is the excerpt from the lb resource:

resource "incus_network_lb" "this" {
  count = var.ovn_network != null && var.lb_ip_address != null && length(var.lb_ports) > 0 ? 1 : 0
  network        = var.ovn_network
  description    = "${title(var.name)} ${var.region} LB"
  listen_address = var.lb_ip_address

  dynamic "backend" {
    for_each = { for idx, instance in incus_instance.this : instance.name => instance }
    content {
      name           = backend.value.name
      description    = "Backend for ${backend.value.name}"
      target_address = backend.value.ipv4_address
      target_port    = var.lb_port != null ? var.lb_port : var.lb_ports[0]
    }
  }

  dynamic "port" {
    for_each = var.lb_ports
    content {
      description    = "Port ${port.value}/tcp"
      protocol       = "tcp"
      listen_port    = port.value
      target_backend = incus_instance.this.*.name
    }
  }
}