terraform
terraform copied to clipboard
[ BUG ] Dynamic attribute block attempts to add an empty block when using map(string)
Terraform Version
1.7.5
Terraform Configuration Files
locals {
bypass_pull_request_allowances = {
users = var.pull_request_bypassers # list of strings
apps = var.gh_app_ids # list of strings
}
}
resource "github_branch_protection_v3" "master_with_reviews" {
repository = "example"
branch = "main"
enforce_admins = false
required_pull_request_reviews {
require_code_owner_reviews = true
required_approving_review_count = var.number_of_approvers
dynamic "bypass_pull_request_allowances" {
for_each = (length(var.pull_request_bypassers) > 0 || length(var.gh_app_ids) > 0) ? [1] : []
content {
users = local.bypass_pull_request_allowances.users
apps = local.bypass_pull_request_allowances.apps
}
}
}
}
Debug Output
# module.example_module.github_branch_protection_v3.master_with_reviews[0] will be updated in-place
~ resource "github_branch_protection_v3" "master_with_reviews" {
id = "example:main"
# (6 unchanged attributes hidden)
~ required_pull_request_reviews {
# (7 unchanged attributes hidden)
+ bypass_pull_request_allowances {}
}
# (1 unchanged block hidden)
}
Expected Behavior
Terraform should not try to add an empty block if the foreach is set to empty.
Actual Behavior
Empty block is added.
Steps to Reproduce
Run terraform plan
with the above config.
Additional Context
This was brought up before here: #24496
I bring this up as this is not a purely cosmetic thing in the github providers case (which errors out if you try to add an empty block) so I believe this should be fixed for those instances where a provider doesn't allow an empty block.
References
- #24496
Hi @dreinhardt-terminus! Thanks for reporting this.
I would expect the behavior similar to what you observed here if either var.pull_request_bypassers
or var.gh_app_ids
had a value that can't be determined during the apply step, because then the result of your conditional would be an unknown list of number and therefore Terraform can't predict how many bypass_pull_request_allowances
would be generated.
Providers using the legacy plugin SDK (which includes this GitHub provider) can't understand the idea of the number of blocks being unknown, because the legacy SDK predates that being made possible in Terraform v0.12, and so Terraform Core describes that situation to a provider by sending one block whose arguments are all set to unknown values.
However, I'm not sure if that's what's happening here, because I can't see your values for var.pull_request_bypassers
and var.gh_app_ids
. Can you temporarily add output values returning those values verbatim, and then share the values that Terraform plans for them? For example:
output "pull_request_bypassers" {
value = var.pull_request_bypassers
}
output "gh_app_ids" {
value = var.gh_app_ids
}
If those output values both show up as having known values during planning (that is, if they are reported as anything other than (known after apply)
) then that would disprove my idea above, in which case we can try something else to look for the real explanation for this behavior.
Thanks!