Search code examples
terraformgitlab-citerraform-provider-azure

Terraform environment variable as object of map of objects


I iterate over the following map of objects:

variable "spokes" {
  description = "(Required) Map for target spokes and their respective attributes."
  type = map(object({
    name                   = string
    environment            = string
    law_id                 = string
    vm_subnet_id           = string
    vm_size                = string
    gitlab_runner_token    = string
    secure_subnet_id       = string
    privatelink_vault_zone = string
    custom_tags            = map(string)
  }))
}

But due to the sensitivity of the gitlab_runner_token string, I'd like to obtain it via an environment variable.

How could this be accomplished? i.e:

export TF_VAR_spokes["spokename1"].gitlab_runner_token="SuPeRsEcReTtOkEn"

Edit 1: the question regards to how to pass a single map attribute as an environment variable, not how to deal with sensitive variables saved in a var file. This code will be executed from Gitlab CI/CD, so saved tokens in a static file inside the repo are definitely a no-go.

Edit 2: state files are stored somewhere else and under different authorization and security settings. So, having clear-text sensitive values there isn't really a major concern for me. Having them saved in the repo files is (a concern), hence having the token as a CI/CD (environment) variable.

Edit 3: Passing a populated var file via Gitlab CI/CD would also work, but it is a bit cumbersome for the developer to keep such an extensive file up to date outside of the repository context. So, I'm keeping this option as a last resort. Same thing applies to passing the entire map as an input (environment) variable.


Solution

  • You will need to set up a separate variable as a map:

    variable "gitlab_runner_tokens" {
      description = "Sensitive GitLab runner tokens for each spoke."
      type        = map(string)
    }
    

    Then remove gitlab_runner_token from the spokes map.

    And merge the two maps as follows:

    locals {
      combined_spokes = {
        for k, v in var.spokes : k => merge(v, { gitlab_runner_token = var.gitlab_runner_tokens[k] })
      }
    }
    

    Now you can export it as TF_VAR_ environment variables:

    export TF_VAR_gitlab_runner_tokens='{"spokename1": "SuPeRsEcReTtOkEn", "spokename2": "AnOtHeRsEcReTtOkEn"}'