Skip to content

Provider-defined functions fail inside dynamic block for_each filters (works elsewhere) #3236

Description

@BillyWeans

Community note

Tip

👋 Hi there, OpenTofu community! The OpenTofu team prioritizes issues based on upvotes. Please make sure to upvote this issue and describe how it affects you in detail in the comments to show your support.

OpenTofu Version

OpenTofu v1.10.5
on darwin_amd64
+ provider registry.opentofu.org/hashicorp/google v6.17.0

OpenTofu Configuration Files

non-working.tf

# This does NOT work and yields a 'no functions for provider' error. See BUG comment below
terraform {
  required_providers {
    google = { source = "hashicorp/google", version = "6.17.0" }
  }
}

provider "google" {
  project = "MY_PROJECT_ID"
}

resource "google_compute_firewall" "repro" {
  name    = "repro"
  network = "default"

  source_ranges = ["0.0.0.0/0"]

  dynamic "allow" {
    # BUG: provider functions apparently 'disappear' when in-lined in for_each
    for_each = {
      for z in ["us-central1-a"] :
      z => z if provider::google::region_from_zone(z) == "us-central1"
    }
    content {
      protocol = "tcp"
      ports    = ["80"]
    }
  }
}

working.tf

# This works when moving the provider function out of the dynamic for_each
terraform {
  required_providers {
    google = { source = "hashicorp/google", version = "6.17.0" }
  }
}

provider "google" {
  project = "MY_PROJECT_ID"
}

locals {
  # Precompute with the provider function OUTSIDE the dynamic block
  filtered_zones = {
    for z in ["us-central1-a"] :
    z => z if provider::google::region_from_zone(z) == "us-central1"
  }
}

resource "google_compute_firewall" "repro" {
  name    = "repro"
  network = "default"

  # satisfy schema: at least one of source_* must be set
  source_ranges = ["0.0.0.0/0"]

  dynamic "allow" {
    for_each = local.filtered_zones
    content {
      protocol = "tcp"
      ports    = ["80"]
    }
  }
}

Debug Output

https://gist.github.com/BillyWeans/d5465e8f30b7461e7f3eea299ae39864

Expected Behavior

Calling a provider function inside of a dynamic for_each should plan properly as it does with a terraform plan.

Actual Behavior

│ on main.tf line 22, in resource "google_compute_firewall" "repro":
│ 22: z => z if provider::google::region_from_zone(z) == "us-central1"

│ There are no functions in namespace "provider::google::".

Steps to Reproduce

  1. tofu init
  2. tofu plan

Additional Context

No response

References

No response

Metadata

Metadata

Assignees

Labels

acceptedThis issue has been accepted for implementation.bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions