Search code examples
objectterraformstructure

how to transform the structure of a object


I have one complicated object in terraform, the structure as below what I need to do is transform this structure into another one(I have posted the desired structure) then create the resource with foreach in terraform

StorageSettings{
    storage{
        fileshare{
            directories{}
        }
    }
}

actual code here


locals {

  StorageSettings = {

    CoreBackup = {

      fileshare = {

        shareA = {
          name                 = "myshare"
          storage_account_name = "sa1corebackup"
          quota                = 100

          directories = {

            dirA = {
              name                 = "app"
              share_name           = "myshare"
              storage_account_name = "sa1corebackup"


            }
          }
        }
        shareB = {
          name                 = "myshare2"
          storage_account_name = "sa1corebackup"
          quota                = 150
        }
      }
    }

    MGMTackup = {

      fileshare = {
        ShareA = {
          name                 = "myshare"
          storage_account_name = "mgmtbackup"
          quota                = 200
          enabled_protocol     = "SMB"
          acl = {
            id = "MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI"

            access_policy = {
              permissions = "rwdl"
              start       = "2019-07-02T09:38:21.0000000Z"
              expiry      = "2019-07-02T10:38:21.0000000Z"
            }
          }

          directories = {

            dirA = {

              name                 = "app"
              share_name           = "myshare"
              storage_account_name = "mgmtbackup"

            }

            dirB = {
              name                 = "backup"
              share_name           = "myshare"
              storage_account_name = "mgmtbackup"
            }

          }

        }

        ShareB = {
          name                 = "myshare2"
          storage_account_name = "mgmtbackup"
          quota                = 100
          enabled_protocol     = "SMB"

          acl = {
            id = "MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI"

            access_policy = {
              permissions = "rwdl"
              start       = "2019-07-02T09:38:21.0000000Z"
              expiry      = "2019-07-02T10:38:21.0000000Z"
            }
          }

          directories = {

            dirA = {
              name                 = "app"
              share_name           = "myshare"
              storage_account_name = "mgmtbackup"


            }

            dirB = {
              name                 = "backup"
              share_name           = "myshare"
              storage_account_name = "mgmtbackup"
            }
          }
        }
      }
    }
  }
}




My question is how to transform the structure to the below one?

storage+fileshare{
    directories{
    }
}

I tried the below code

  filesharesettings = { for p, v in local.StorageSettings : p => v.fileshare if try(v.fileshare, null) != null }

  directorysettings = {
    for Storage, FileShareSettings in local.filesharesettings : Storage =>
    { for FileShare, FileShareSetting in FileShareSettings : "${Storage} ${FileShare}" => FileShareSetting.directories if lookup(FileShareSetting, "directories", "") != "" }
  }

but only get the result like this

storage{
  storage+fileshare{
    directories{
    }
  }
}

current output as below, please note it's not my expect output, I tried to convert the structure with some code(already posted), and below is the output, my expect output structure is this

storage+fileshare{
    directories{
    }
}
Changes to Outputs:
  + dd = {
      + CoreBackup = {
          + CoreBackup shareA = {
              + dirA = {
                  + name                 = "app"
                  + share_name           = "myshare"
                  + storage_account_name = "sa1corebackup"
                }
            }
        }
      + MGMTackup  = {
          + MGMTackup ShareA = {
              + dirA = {
                  + name                 = "app"
                  + share_name           = "myshare"
                  + storage_account_name = "mgmtbackup"
                }
              + dirB = {
                  + name                 = "backup"
                  + share_name           = "myshare"
                  + storage_account_name = "mgmtbackup"
                }
            }
          + MGMTackup ShareB = {
              + dirA = {
                  + name                 = "app"
                  + share_name           = "myshare"
                  + storage_account_name = "mgmtbackup"
                }
              + dirB = {
                  + name                 = "backup"
                  + share_name           = "myshare"
                  + storage_account_name = "mgmtbackup"
                }
            }
        }
    }


Could anyone kindly help me out here?


Solution

  • Your data source is rather complex, but I think you can do that using three for loops:

      directorysettings = merge(
            flatten([for storage_name, fileshares in local.StorageSettings:
               {for share_name, share in fileshares["fileshare"]:
                   "${storage_name}+${share_name}" => {
                     for directory_name, directory in share["directories"]:
                       directory_name => directory
                   } if lookup(share, "directories", "") != ""
               }
            ])...) 
    

    which gives directorysettings:

    {
      "CoreBackup+shareA" = {
        "dirA" = {
          "name" = "app"
          "share_name" = "myshare"
          "storage_account_name" = "sa1corebackup"
        }
      }
      "MGMTackup+ShareA" = {
        "dirA" = {
          "name" = "app"
          "share_name" = "myshare"
          "storage_account_name" = "mgmtbackup"
        }
        "dirB" = {
          "name" = "backup"
          "share_name" = "myshare"
          "storage_account_name" = "mgmtbackup"
        }
      }
      "MGMTackup+ShareB" = {
        "dirA" = {
          "name" = "app"
          "share_name" = "myshare"
          "storage_account_name" = "mgmtbackup"
        }
        "dirB" = {
          "name" = "backup"
          "share_name" = "myshare"
          "storage_account_name" = "mgmtbackup"
        }
      }
    }