I am trying to figure out a way to skip the iteration of an inner for
loop if a particular attribute does not exist - in this case variables
. However, I am beginning to wonder if I am expecting too much from a declarative language.
This is my input:
locals {
environments = {
dev : {
name: "development"
project : "gcp-project-1"
protected : false
variables : [
{
key: "GCP_PROJECT"
value: "gcp-project-1"
environment_scope: "development"
protected: true
},
{
key: "ANOTHER_VAR"
value: "some-value"
environment_scope: "development"
protected: true
}
]
}
prod : {
name : "production"
project : "gcp-project-2"
protected : true
variables : [
{
key: "GCP_PROJECT"
value: "gcp-project-2"
environment_scope: "production"
protected: true
}
]
}
}
}
environments
is consumed here, which basically iterates through variables
to convert and store it in a data structure that is easier to work with later on:
locals {
variables = flatten([
for k, env in local.environments : [
for var, var in env.variables : { <--- Is there a way to skip an iteration if env.variables does not exist?
key: var.key
value: var.value
}
]
])
}
This loop will output something similar to this:
variables = [
{
key = "KEY"
value = "VALUE"
}
]
Which ultimately is used here:
resource "gitlab_project_variable" "variable" {
for_each = {
for i, v in local.variables : v.terraform_id => v
}
key = each.value.key
value = each.value.value
}
CodePudding user response:
You can use lookup:
locals {
variables = flatten([
for k, env in local.environments : [
for var, var in lookup(env, "variables", {}) : {
key: var.key
value: var.value
}
]
])
}
CodePudding user response:
I would typically recommend setting object attributes to null
when you aren't using them so that the object type remains consistent in all cases, and then you can use comparison with null
as the filter:
locals {
variables = flatten([
for k, env in local.environments : [
for var, var in env.variables : {
key: var.key
value: var.value
}
]
if env.variables != null
])
}
You could also set the inapplicable ones to be an empty list and then your expression would work without any extra conditions at all.
If you really do want to use inconsistent object types for your environment objects then it's not so clean to handle but you can still get something similar to the above by using the can
function to detect when accessing the variables
attribute would fail:
locals {
variables = flatten([
for k, env in local.environments : [
for var, var in env.variables : {
key: var.key
value: var.value
}
]
if can(env.variables)
])
}