Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

prefer iterator error over for_each #656

Merged
merged 1 commit into from Feb 14, 2024

Conversation

DanielMSchmidt
Copy link
Contributor

@DanielMSchmidt DanielMSchmidt commented Feb 14, 2024

If the iterator is misconfigured (e.g. a string instead of a reference) it leads to
follow up issues in the validation of for_each which in turn leads to misleading
error messages. See hashicorp/terraform#34132 for an example.

Example

terraform {
  required_version = ">= 1.5.0"

  required_providers {
    cloudflare = {
      source  = "cloudflare/cloudflare"
      version = "~> 4.0"
    }
  }
}

data "cloudflare_zone" "example" {
  name = "example.org"
}

locals {
  example1_ip_ranges = [
    "1.2.3.4/32",
    "1.2.3.4/32",
  ]

  example2_ip_ranges = [
    "1.2.3.4/32",
    "1.2.3.4/32",
  ]
}

resource "cloudflare_zone_lockdown" "example" {
  zone_id = data.cloudflare_zone.example.zone_id

  urls = ["https://*.example.org"]

  dynamic "configurations" {
    for_each = concat(local.example1_ip_ranges, local.example2_ip_ranges)
    iterator = "client" # <-- invalid

    content {
      target = "ip_range"
      value  = client.value
    }
  }
}

Before

╷
│ Error: Insufficient configurations blocks
│ 
│   on zonelockdown.tf line 13, in resource "cloudflare_zone_lockdown" "example":
│   13: resource "cloudflare_zone_lockdown" "example" {
│ 
│ At least 1 "configurations" blocks are required.
╵
╷
│ Error: Unknown variable
│ 
│   on zonelockdown.tf line 19, in resource "cloudflare_zone_lockdown" "example":
│   19:     for_each = concat(local.example1_ip_ranges, local.example2_ip_ranges)
│ 
│ There is no variable named "local".
╵
╷
│ Error: Unknown variable
│ 
│   on zonelockdown.tf line 19, in resource "cloudflare_zone_lockdown" "example":
│   19:     for_each = concat(local.example1_ip_ranges, local.example2_ip_ranges)
│ 
│ There is no variable named "local".

After

╷
│ Error: Insufficient configurations blocks
│
│   on main.tf line 28, in resource "cloudflare_zone_lockdown" "example":
│   28: resource "cloudflare_zone_lockdown" "example" {
│
│ At least 1 "configurations" blocks are required.
╵
╷
│ Error: Invalid expression
│
│   on main.tf line 35, in resource "cloudflare_zone_lockdown" "example":
│   35:     iterator = "client"
│
│ A single static variable reference is required: only attribute access and indexing with constant keys. No calculations, function calls, template expressions, etc are
│ allowed here.
╵

If the iterator is misconfigured (e.g. a string instead of a reference) it leads to
follow up issues in the validation of for_each which in turn leads to misleading
error messages. See hashicorp/terraform#34132 for an example.
Copy link
Member

@liamcervante liamcervante left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where are the error strings in your description coming from? Is that Terraform doing some additional post processing over the diagnostics returned by HCL?

@DanielMSchmidt
Copy link
Contributor Author

Is that Terraform doing some additional post processing over the diagnostics returned by HCL?

No, they are added here:

eachVal, eachDiags := eachAttr.Expr.Value(b.forEachCtx)

@DanielMSchmidt DanielMSchmidt merged commit 772d004 into main Feb 14, 2024
7 checks passed
@DanielMSchmidt DanielMSchmidt deleted the improve-dynamic-block-error-message branch February 14, 2024 13:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants