Valodim / terraform-provider-desec

A terraform provider for desec.io
MIT License
10 stars 7 forks source link

Provider ignores records if values are learned at apply time. #4

Open envy opened 3 years ago

envy commented 3 years ago

When creating a new DNS rrset which records depend on other new resources, terraform fails with:

Error: Provider produced inconsistent final plan

When expanding the plan for desec_rrset.test to include new
values learned so far during apply, provider
"registry.terraform.io/valodim/desec" produced an invalid new value for
.records: was null, but now
cty.SetVal([]cty.Value{cty.StringVal("1.2.3.4")}).

This is a bug in the provider, which should be reported in the provider's own
issue tracker.

Config:

resource "desec_rrset" "test" {
  domain = "domain.tld"
  subname = "test"
  type = "A"
  records = [some.other.new.resource.ip]
  ttl = 3600
}

Terraform shows the following plan:

Terraform will perform the following actions:

  # desec_rrset.test will be created
  + resource "desec_rrset" "test" {
      + created = (known after apply)
      + domain  = "domain.tld"
      + id      = (known after apply)
      + name    = (known after apply)
      + subname = "test"
      + ttl     = 3600
      + type    = "A"
    }

The records array is missing and causing the error, I think it should look something like this: records = [(known after apply)]

When invoking terraform apply after the error again, the other resource already exists and terraform shows this plan:

Terraform will perform the following actions:

  # desec_rrset.test will be created
  + resource "desec_rrset" "test" {
      + created = (known after apply)
      + domain  = "domain.tld"
      + id      = (known after apply)
      + name    = (known after apply)
      + records = [
          + "1.2.3.4",
        ]
      + subname = "test"
      + ttl     = 3600
      + type    = "A"
    }

Applying now works fine.

PeterSR commented 2 years ago

I just experienced the same error when trying to add a CNAME for one record to another using

resource "desec_rrset" "star" {
  domain = desec_domain.<other domain>.name
  subname = "*"
  type = "CNAME"
  records = [desec_rrset.<other record>.name]
  ttl = 3600
}
chr1stus commented 10 months ago

Hi. If my analysis is correct, this is because the new value is of a new ressource and the (legacy) SDK cannot handle this situation: https://github.com/hashicorp/terraform-plugin-sdk/issues/165

Deactivating following function helped me, but I cannot oversee possible pitfalls: https://github.com/Valodim/terraform-provider-desec/blob/33e9eceb18d977fc8bbac234e6f70bf402672858/desec/resource_rrset.go#L59

Hope this helps someone with more insights! -- Chris

stelb commented 2 months ago

can this be fixed please? Just moved from G*d*ddy (API now a feature to be paid extra) to desec and terraform/tofu fails on first run. It should not be very uncommon to add records from dynamic other resources. my code:

resource "desec_rrset" "node_dns" {
  for_each = {
    for s in concat(hcloud_server.talos_cp, hcloud_server.talos_wk) : s.name => s
  }
  domain     = var.dns_zone
  subname    = format("%s.%s", each.value.name, local.rel_domain)
  records    = [each.value.ipv4_address]
  type       = "A"
  ttl        = 3600
  depends_on = [hcloud_server.talos_cp]
}
  # desec_rrset.node_dns["cp01"] will be created
  + resource "desec_rrset" "node_dns" {
      + created = (known after apply)
      + domain  = "mydomain.tld"
      + id      = (known after apply)
      + name    = (known after apply)
      + subname = "cp01.whatever.this"
      + ttl     = 3600
      + type    = "A"
    }
│ Error: Provider produced inconsistent final plan
│ 
│ When expanding the plan for desec_rrset.node_dns["cp03"] to include new values learned so far during apply, provider
│ "registry.opentofu.org/valodim/desec" produced an invalid new value for .records: was null, but now
│ cty.SetVal([]cty.Value{cty.StringVal("1.2.3.4")}).
│ 
│ This is a bug in the provider, which should be reported in the provider's own issue tracker.
╵

second successful run:

  # desec_rrset.node_dns["cp01"] will be created
  + resource "desec_rrset" "node_dns" {
      + created = (known after apply)
      + domain  = "mydomain.tld"
      + id      = (known after apply)
      + name    = (known after apply)
      + records = [
          + "1.2.3.4",
        ]
      + subname = "cp01.whatever.this"
      + ttl     = 3600
      + type    = "A"
    }