-1

Here is a resource block that uses for_each on a set of string names. Each resource ends up being an environment variable for this provider, including a key and value:

resource "environments_variables_v1" "api_env_var" {
  service_sid     = local.api_sid
  environment_sid = local.api_env_sid
  for_each = {
    for k, v in var.api_env_var_names : k => v
    if var.feature_flag
  }
  key   = upper(each.value)
  value = var.each.value
}

The output should be a key (name changed to uppercase) and a value. The value is coming from secrets in the environment. I have a variable declared for it:

variable "api_env_var_name_1" {
  default     = ""
  type        = string
  description = "1st environment secret."
  sensitive   = true
  nullable    = false
}

My problem is I don't see a way to take an each.value and use it as the key name for a variable. var.each.value above is not the right syntax but I don't see an alternative.

Jeremy Schultz
  • 579
  • 1
  • 6
  • 26
  • Why not use the exported attribute of `environments_variables_v1.api_env_var` instead? It would be cleaner and easier. – Matthew Schuchard Apr 26 '23 at 17:09
  • @MattSchuchard If you mean output values, I'm not very familiar with them (we have not used them in our project) and from what I know, I'm not sure how they can be used in this situation. – Jeremy Schultz Apr 26 '23 at 18:21

1 Answers1

1

In Terraform each input variable is entirely independent, so there is no way to select one dynamically based on a value as you are attempting here.

If you need to look up values by keys, the most appropriate data structure for that is a map, which is a collection of elements where each element has a key and a value, and you can provide a single key to obtain the corresponding value.

It seems from your example that var.api_env_var_names is already declared as having a map type, though you didn't include its declaration in your question so I'll write out what I'm guessing it looks like:

variable "api_env_var_names" {
  type = map(string)
}

It seems that this variable is a map from something to the name of an environment variable. From what you've described, it seems like you then need a separate variable which maps from input variable names to their values, like this:

variable "api_env_var_values" {
  type = map(string)
}

The above isn't particularly clear about what the keys and values in these variables represent, so here are some example definitions of these variables to show how I'm imagining them being used:

  api_env_var_names = {
    something      = "SOMETHING_NAME"
    something_else = "SOMETHING_ELSE_NAME"
  }
  api_env_var_values = {
    SOMETHING_NAME = "foo"
    SOMETHING_ELSE_NAME = "bar"
  }

Now you can use the values from the first one as keys for the second one, like this:

resource "environments_variables_v1" "api_env_var" {
  for_each = {
    for k, v in var.api_env_var_names : k => v
    if var.feature_flag
  }

  service_sid     = local.api_sid
  environment_sid = local.api_env_sid
  key             = upper(each.value)
  value           = var.api_env_var_values[each.value]
}
Martin Atkins
  • 62,420
  • 8
  • 120
  • 138
  • `api_env_var_names` is actually a set/list of strings. I did end up replacing some of my sets with maps so I could use the keys for references like this. – Jeremy Schultz May 01 '23 at 21:02