Home > database >  Terraform, create map where list elements are values
Terraform, create map where list elements are values

Time:09-06

I am trying to parse this variable in terraform. The main goal is to create map of "group" = "member" type. Did i set type in variable correct? Required output provided below.

variable "iam" "this"{
  type = map(map(list(string)))
  default = {
    "admins" = {
      "user" = [
        "[email protected]",
        "[email protected]"
      ]
      "service_principal" = [
        "dpaf2-dev-sa"
      ]
    }
    "dev"   = {
      "user" = [
        "[email protected]",
        "[email protected]"
      ]
      "service_principal" = []
    }
    "ops"   = {
      "user" = [
        "[email protected]",
      ]
      "service_principal" = [
        "dpaf2-dev-sa",
        "dpaf2-iacda-app-id",
      ]
    }
  }
}

Required output:

{
"admins" = "[email protected]"
"admins" = "[email protected]"
"admins" = "dpaf2-dev-sa"
"dev"    = "[email protected]"
"dev"    = "[email protected]"
"ops"    = "[email protected]"
"ops"    = "dpaf2-dev-sa"
"ops"    = "dpaf2-iacda-app-id"
}

CodePudding user response:

Start with this and manipulate it to suit your exact needs. There are many ways to structure resources using maps, arrays and nesting.

locals {
  service_principal = {
    admin = ["dpaf2-dev-sa"]
    dev   = []
    ops = [
      "dpaf2-dev-sa",
      "dpaf2-iacda-app-id",
    ]
  }
  users = {
    admin = [
      "[email protected]",
      "[email protected]"
    ]
    dev = [
      "[email protected]"
    ]
    ops = [
      "[email protected]"
    ]
  }
  result = flatten([for role in keys(local.users) : [for user in local.users[role] :
  { role = role, user = user, principals = local.service_principal[role] }]])
}

resource "null_resource" "users" {
  count = length(local.result)
  provisioner "local-exec" {
    command = "echo user: $USER has role: $ROLE and principals: $SERVICE_PRINCIPAL >> ouput.txt"

    environment = {
      USER              = local.result[count.index].user
      ROLE              = local.result[count.index].role
      SERVICE_PRINCIPAL = join(", ", local.result[count.index].principals)
    }
  }
}

If you run:

  1. terraform init
  2. terraform plan
  3. terraform apply --auto-approve

Then check your directory for a file named output.txt which will contain

user:[email protected] has role:admin and principals: dpaf2-dev-sa
user:[email protected] has role:dev and principals:
user:[email protected] has role:ops and principals: dpaf2-dev-sa, dpaf2-iacda-app-id
user:[email protected] has role:admin and principals: dpaf2-dev-sa

I know the text file isn't your desired output but the loop is just a demonstration of how you can iterate over the local variable.

Again, many ways to sort and slice it. I avoided your desired output because maps cannot have duplicate keys so it'll never work.

If you want to see the result in isolation you can do:

  1. terraform console
  2. local.result

And it will appear in the terminal. To exit the console type exit.

  • Related