-
Notifications
You must be signed in to change notification settings - Fork 9.6k
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
Incorrect counting of map keys #21047
Comments
Hi @masterjg ! It would help if we could see a bit more of your configuration - I'm curious about the modules referenced in the user_access = {
module.jenkins.resource_data["username"] = [
"s3:*"
]
module.developer.resource_data["username"] = [
"s3:GetObject",
"s3:ListBucket",
]
} I'd like to know if either of those modules use I was unable to reproduce this issue using hard-coded usernames, which is what led me to question the other modules: module "db_backups" {
user_access = {
user_a = [
"s3:*"
]
user_b = [
"s3:GetObject",
"s3:ListBucket",
]
}
} |
Yes of course... output "resource_data" {
value = {
username = aws_iam_user.user.name
}
}
resource "aws_iam_user" "user" {
name = var.name
}
variable "name" {
type = string
} |
BTW If I hardcode them like you do then everything works as expected. But for some reason terraform doesnt work with outputs from other modules here... |
This symptom suggests that the If both of those usernames are unknown during plan then Terraform can't tell whether they'll have distinct values once they are known (during apply) and so it can't tell if there will be one or two elements in that map. Conservatively then, it returns an unknown value from the I think this could be worked around by making that a list instead of a map and putting the username in the value, since then the number of elements won't depend on what those names turn out to be at apply time: module "db_backups" {
...
user_access = [
{
username = module.jenkins.resource_data["username"]
access = [
"s3:*"
]
},
{
username = module.developer.resource_data["username"]
access = [
"s3:GetObject",
"s3:ListBucket",
]
},
]
} locals {
users = var.user_access.*.username
}
data "aws_iam_user" "bucket" {
count = length(local.users)
user_name = local.users[count.index]
} During plan in this case, |
var.name is always known (it isn't output from another module). For example I can set variables to jenkins and developer module "jenkins" {
...
name = "jenkins"
}
module "developer" {
...
name = "developer"
} So I think terraform should know that there are only two of them? |
Thanks for the extra context, @masterjg! In that case, I think the question here is: why does Terraform consider these names to be unknown when they are ultimately derived from a constant value? There's a lot of indirection here, so I think to puzzle this out will require us to find a small, complete reproduction case and then follow the data flow to understand which expression evaluation is producing an unknown value first. It seems like one of the evaluation steps along the way is being too conservative, causing an unknown value where one isn't warranted. |
Here you go :) |
Thanks for the reproduction case, @masterjg! It was very helpful in tracing what's going on here. This error is being produced during the refresh walk, which during initial create happens with a totally empty state. When Terraform constructs the graph for a refresh walk, it doesn't include any resource nodes unless they are already present in the state, under the presumption that there's therefore nothing to refresh, and so our refresh graph for this configuration is quite minimal: The crucial detail here is that neither Once a resource has been processed during the plan phase, there is an entry in the state for the resource as a whole and for each of its potentially-multiple instances (if The problem here is that during the refresh phase, where we have no record of these in the state, the expression evaluator doesn't know whether This is another problem in the family described by #17034, and can be fixed properly in the long term by moving the data source reads into the plan phase rather than doing them during the refresh phase, as that issue proposes. That's too big a change to make before the v0.12.0 release though, so tomorrow (since my work day is over now) I'm going to evaluate the following approach to see if it's practical as a short-term fix for this: If |
Ok thanks for the update, @apparentlymart ! Hopefully this will be fixed one way or another soon enough and find its way to the next beta or dev snapshot :) |
I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further. |
Terraform Version
Terraform Configuration Files
Debug Output
Crash Output
Expected Behavior
Terraform should easily detect that there are actually TWO users.
Actual Behavior
The "count" value depends on resource attributes that cannot be determined
until apply, so Terraform cannot predict how many instances will be created.
To work around this, use the -target argument to first apply only the
resources that the count depends on.
Steps to Reproduce
terraform init
terraform apply
Additional Context
References
The text was updated successfully, but these errors were encountered: