Terraform: Declaring a structured/typed local or variable

285 views Asked by At

I am implementing a Cloudflare Terraform script and I am having issues deduplicating a block for zone_settings:

resource "cloudflare_zone_settings_override" "my-domain-settings-1" {
  zone_id = cloudflare_zone.my_domain1.id
  settings {
    # very_long_list_of_settings
  }
}

resource "cloudflare_zone_settings_override" "my-domain-settings-2" {
  zone_id = cloudflare_zone.my_domain2.id
  settings {
    # very_long_list_of_settings
  }
}

The settings block has ~60 lines as is completely equal. I tried to implement this via foreach:

variable domains {
  default = [
    # ERROR: Variables may not be used here.
    cloudflare_zone.my_domain1,
    cloudflare_zone.my_domain2,
  ]
}

resource "cloudflare_zone_settings_override" "partners-zone-settings" {
  name = var.domains[count.index].name
  zone_id = var.domains[count.index].id
  settings {
    # very_long_list_of_settings
  }
}

(full code: https://gist.github.com/knyttl/ee10aa7d63adda866fe39151a9e015d9)

But this is failing with Variables may not be used here. within the variables block.

So I tried with locals:

locals {
  zone_settings {
    # very_long_list_of_settings
    # ERROR: cannot have nested blocks
  }
}

resource "cloudflare_zone_settings_override" "my-domain-settings-1" {
  zone_id = cloudflare_zone.divadlouhasicu_cz.id
  # ERROR: An argument named "settings" is not expected here. Did you mean to define a block of type "settings"?
  settings = var.zone_settings
}

resource "cloudflare_zone_settings_override" "my-domain-settings-2" {
  zone_id = cloudflare_zone.divadlouhasicu_net.id
  # ERROR: An argument named "settings" is not expected here. Did you mean to define a block of type "settings"?
  settings = var.zone_settings
}

(full code: https://gist.github.com/knyttl/76ff39f3baf68df19dfbd05a37eb0ea5)

But this ends with errors in the two comments above.

Is there even a way to do this?

1

There are 1 answers

6
welcomeboredom On

čau Vojto,

in case you're Terraform 12 or higher you can use for_each construct. In lower version there is no way.

https://www.hashicorp.com/blog/hashicorp-terraform-0-12-preview-for-and-for-each

Code would look something like this (I didn't test this so some modification will be needed almost for sure):

variable domains {
  default = [
    # ERROR: Variables may not be used here.
    cloudflare_zone.my_domain1,
    cloudflare_zone.my_domain2,
  ]
}

resource "cloudflare_zone_settings_override" "my-domain-settings-1" {
  for_each = var.domains

  zone_id = each.value
  settings {
    # very_long_list_of_settings
  }
}