Fuji Komalan
Fuji Komalan

Reputation: 2047

flatten terraform list of list using for loop without using flatten function

I know my expected result can be made using flatten built in function( which I have given below). But I want to know is there any way to create them only using nested for loops.

  output "languages" {
  value = flatten([ 
    for user in var.users: [
      for language in user.languages: language
    ]
  ])
}

This is my variable

variable "users" {

  default = {
   
    "sam" = {
      "name" = "sam"
      "age"  = 22
      "languages" = ["python","nodejs","perl","ruby"]
      
    },
    "john" = {
      "name" = "john"
      "age"  = 36
      "languages" = ["python","html","cpp","golang","perl","ruby"] 
    },
    "kevin" = {
      "name" = "kevin"
      "age"  = 30
      "languages" = ["python","nodejs","bash","cpp","ruby"] 
    },
    "devid" = {
      "name" = "devid"
      "age"  = 40
      "languages" = ["python","bash","perl","ruby"] 
    },
    "devon" = {
      "name" = "devon"
      "age"  = 25
      "languages" = ["python"] 
    },
    "jain" = {
      "name" = "jain"
      "age"  = 42
      "languages" = ["python","bash","perl","ruby"] 
    }

  } }

This is mycode

output "languages" {
  value = [ 
    for user in var.users: [
      for language in user.languages: language
    ]
  ]
}

Current Result

languages = [
  [
    "python",
    "bash",
    "perl",
    "ruby",
  ],
  [
    "python",
  ],
  [
    "python",
    "bash",
    "perl",
    "ruby",
  ],
  [
    "python",
    "html",
    "cpp",
    "golang",
    "perl",
    "ruby",
  ],
  [
    "python",
    "nodejs",
    "bash",
    "cpp",
    "ruby",
  ],
  [
    "python",
    "nodejs",
    "perl",
    "ruby",
  ],
]

Excepted Result

languages = [
    "python",
    "bash",
    "perl",
    "ruby",
    "python",
    "python",
    "bash",
    "perl",
    "ruby",
    "python",
    "html",
    "cpp",
    "golang",
    "perl",
    "ruby",
    "python",
    "nodejs",
    "bash",
    "cpp",
    "ruby",
    "python",
    "nodejs",
    "perl",
    "ruby",

]

Upvotes: 0

Views: 529

Answers (2)

Martin Atkins
Martin Atkins

Reputation: 74239

Each for expression always constructs either a new tuple or a new object. There is no way to use two for expressions together to construct a single tuple or object.

The flatten function is the way to achieve this in the Terraform language. Although there are other functions that can potentially achieve a similar result, the flatten function is the one designed for this purpose and the one idiomatic to use, so is the one that other readers of your configuration will probably find most intuitive if they are familiar with Terraform from elsewhere.

Upvotes: 0

Ervin Szilagyi
Ervin Szilagyi

Reputation: 16775

I'm not entirely sure if this is what you want, but without using flatten function you can accomplish something similar with a for loop, concat and with the ellipsis expression:

output "languages" {
  value = concat([for item in var.users : item.languages]...)
}

The output result will be the following:

languages = [
  "python",
  "bash",
  "perl",
  "ruby",
  "python",
  "python",
  "bash",
  "perl",
  "ruby",
  "python",
  "html",
  "cpp",
  "golang",
  "perl",
  "ruby",
  "python",
  "nodejs",
  "bash",
  "cpp",
  "ruby",
  "python",
  "nodejs",
  "perl",
  "ruby",
]

Keep in mind, Terraform mainly relies on using pure functions. Moreover, while you can have local variables, they cannot act as intermediary in case of loops and expressions.

Upvotes: 1

Related Questions