Terraform Nested maps to build GCP deep nested folder s tructure

Hello , we have an usecase to devlope a module to create nested GCP folders which should create subfolders, sub_sub_folders …

The structure looks like this :

ORGANIZATION
root_folder1
    |subfolder11
    |subfolder12
        |subfolder121
   |sub_folder13
root_folder2
    |sub_folder21
         |sub_folder211
               |sub_folder2111
root_folder3

And the Map variable:

 variable "folders" {
    type = map
    default = {
     "rootfolder1" = {
  	"subs" = {
  	 "ssubfolder11" = {}
  	 "subfolder12" = {}
      }
     }
     "rootfolder2" = {
      "subs" = {
  	 "subfolder21" = {
        "subs" = {
  	   "subfolder221" = {}
        }
	 }
  	 "subfolder22" = {
  	  "subs" = {
  	   "subfolder221" = {}
        }
  	 }
  	}
     }
    }
  }
  • Like this we have loop over the nested maps in order to create GCP flder resource.

  • I tried flattening root_folder once, sub_folder and then sub_sub_folder. But this requires multiple resource blocks to define the folder structure.

Locals:

locals {
  root_folder_flat = flatten([
    for rf, subs in var.folders : {
      folder = rf
      parent = format("%s/%s", "organizations", var.organization_id)
    }
    ]
  )
  sub_folder_flat = flatten([
      for rf , subs in var.folders : [
            for sf in subs : {
                parent_name = rf
                parent = format("%s/%s","organizations", var.organization_id)
                folder = sf
          }
          
      ]
  ])
  sub_sub_folder_flat = flatten([
      for rf , subs in var.folders : [
          for sf ,subss in subs : [
              for ssf ,subs in subss : {
                  parent_id = format("%s/%s","folders", var.organization_id)
                  parent_name = sf
                  folder = ssf
              }
          ]
      ]
  ])

}

resource block:

resource "google_folder" "root_folders" {
  for_each = {
    for k in local.root_folder_flat : "${k.parent}.${k.folder}" => k 
  }
    display_name = each.value.folder
    parent       =  each.value.parent
}

resource "google_folder" "sub_folders" {
  for_each = {
    for k in local.sub_folder_flat : "${k.parent_name}" => k
  }
  display_name = each.value.folder
  parent       = format("%s/%s", "organization", each.value.parent)
}

One resource block to create root_folders and the other one to create sub_folders… and need to have that many resource blocks to create nested folder structure.

Can someone please guide me, on how to acheive this or any other alternative way.

Thanks :slight_smile:

The Terraform language doesn’t have any way to recursively flatten a complex data structure.

Also, I’m fairly sure that its model of dependencies is relationships between blocks not individual resources generated from for_each or count, so in order to correctly model the dependencies that parent folders should exist before child folders are created, they need to be separate blocks.

To me, this feels like a level of complexity which can’t be addressed fully in the Terraform language, and needs a preprocessing step in which a general programming language such as Python or Go is used to generate Terraform source code defining individual resource blocks for each folder.

1 Like

@maxb Thanks for the quick response, we assumed that this might not be possible with terraform. Let’s see if someone has a workaround or a similar usecase like this nested folders.