hyperwiser
hyperwiser

Reputation: 497

Terraform - construct list of strings from map

Related question.

I'm trying to construct a list of prefixes to be added to an S3 bucket as objects. The result should be like this:

Bucket ----> /Partner1 ----> /Client1 ----> /User1
        |               |              |--> /User2
        |               |
        |               |--> /Client2 ----> /User1
        |
        |--> /Partner2 ----> /Client1 ----> /User1

and so on...

I define this variable:

variable "s3_folders_map" {
    type = map
    default = {
      Partner1 = {
        client1 = ["User1", "User2", "User3", "User4", "User5"]
        client2 = ["User1"]
        client3 = ["User1"]
      }
      Partner2 = {
        client1 = ["User1"]
      }
      Partner3 = {
        client1 = ["User1"]
      }
    }
}

and then try to extract a list of prefixes like

/Partner1/Client1/User1
/Partner1/Client1/User2
/Partner1/Client2/User1
...

using this:

locals {
  s3_folders     = flatten([
    for partner, client in var.s3_folders_map: [
      flatten([for user in client: {
        "partner" = partner
        "client" = client
        "user" = user
        }
      ])
    ]
  ])
}

output "s3_folders" {
  value = local.s3_folders
}

This is what I see when I run terraform plan:

  + s3_folders = [
      + {
          + client  = {
              + "client1" = [
                  + "User1",
                  + "User2",
                  + "User3",
                  + "User4",
                  + "User5",
                ]
              + "client2" = [
                  + "User1",
                ]
              + "client3" = [
                  + "User1",
                ]
            }
          + partner = "Partner1"
          + user    = [
              + "User1",
              + "User2",
              + "User3",
              + "User4",
              + "User5",
            ]
        },
      + {
          + client  = {
              + "client1" = [
                  + "User1",
                  + "User2",
                  + "User3",
                  + "User4",
                  + "User5",
                ]
              + "client2" = [
                  + "User1",
                ]
              + "client3" = [
                  + "User1",
                ]
            }
          + partner = "Partner1"
          + user    = [
              + "User1",
            ]
        },
      + {
          + client  = {
              + "client1" = [
                  + "User1",
                  + "User2",
                  + "User3",
                  + "User4",
                  + "User5",
                ]
              + "client2" = [
                  + "User1",
                ]
              + "client3" = [
                  + "User1",
                ]
            }
          + partner = "Partner1"
          + user    = [
              + "User1",
            ]
        },
      + {
          + client  = {
              + "client1" = [
                  + "User1",
                ]
            }
          + partner = "Partner2"
          + user    = [
              + "User1",
            ]
        },
      + {
          + client  = {
              + "client1" = [
                  + "User1",
                ]
            }
          + partner = "Partner3"
          + user    = [
              + "User1",
            ]
        },
    ]

It looks like user is turning out to be a list when there are multiple users, while I want to iterate through that list and extract every single user name. What am I doing wrong here?

Upvotes: 1

Views: 6056

Answers (1)

Marcin
Marcin

Reputation: 238867

You need three for loops:

  s3_folders  = flatten([
    for partner, clients in var.s3_folders_map: [
        for client, users in clients: [
          for user in users: "${partner}/${client}/${user}"
        ]      
    ]
  ])

gives:

s3_folders = [
  "Partner1/client1/User1",
  "Partner1/client1/User2",
  "Partner1/client1/User3",
  "Partner1/client1/User4",
  "Partner1/client1/User5",
  "Partner1/client2/User1",
  "Partner1/client3/User1",
  "Partner2/client1/User1",
  "Partner3/client1/User1",
]

Upvotes: 2

Related Questions