Terraform v0.12.20
+ provider.azuread v0.7.0
+ provider.azurerm v1.41.0
+ provider.kubernetes v1.10.0
+ provider.null v2.1.2
resource "aws_api_gateway_usage_plan" "these" {
for_each = var.apig_plans
name = "${local.namespace}-${each.key}-plan"
api_stages {
api_id = aws_api_gateway_rest_api.rest_api[0].id
stage = aws_api_gateway_rest_api.rest_api[0].name
}
dynamic "quota_settings" {
for_each = [for v in [each.value["quota"]] : v if v != {}]
content {
limit = quota_settings.value["limit"]
offset = quota_settings.value["offset"]
period = quota_settings.value["period"]
}
}
dynamic "throttle_settings" {
for_each = [for v in [each.value["throttle"]] : v if v != {}]
content {
burst_limit = throttle_settings.value["burst_limit"]
rate_limit = throttle_settings.value["rate_limit"]
}
}
}
No error appears and no dynamic block are applied.
The empty list in for_each, still tries to execute content with an empty object:
on .terraform/modules/zappa/zappa/api-keys.tf line 15, in resource "aws_api_gateway_usage_plan" "these":
15: limit = quota_settings.value["limit"]
|----------------
| quota_settings.value is object with no attributes
The given key does not identify an element in this collection value.
Originally reported in a comment on another issue.
@pselle @aarcro FYI
Yes, I'm seeing this issue as well
Hi @Bessonov! Sorry for this odd behavior and thanks for reporting it
Could you please share the definition of var.apig_plans? I'd ideally like to see both the variable block that is declaring it and the value you're assigning to it, because I suspect this is a type mismatch causing the != operator to return false e.g. because it's trying to compare a map value with an object value.
If my theory about the cause is correct, then I think the following should work as an alternative approach:
for_each = [for v in [each.value["quota"]] : v if length(v) > 0]
The == and != operators require that the types of the two arguments match, because there's no implied type conversion for those operators as there is with most other operators, functions, etc. For that reason, comparing to {} would only work if the value being compared were of type object({}): the empty object type. If the value being compared is instead a _map_ then an explicit conversion would be needed to force the types to match, like map(v) == map({}), but when the goal is to test whether the value is empty I think it'd read more clearly to use length(v) == 0 or length(v) > 0 to explicitly capture that intent.
@ktham can you provide an example?
@apparentlymart sorry, in meantime I've changed my configuration.
I am going to close this issue due to inactivity.
If there is still a question, I recommend the the community forum, where there are far more people available to help. If there is a bug or you would like to make a feature request, please open a new issue and fill out the template.
Thanks!
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.