Mukesh Santhanam
Mukesh Santhanam

Reputation: 303

Terraform Generate Nested data

I have the following input in terraform, but couldn't able to generate to desired output.

I dont see any option in tf to filter by resource_app_id in for loop.

Stuck on this for past couple of days . Any help is appreciated!!!

input_data = [
  {
    "resource_app_id" = "62ec2d38-2d53-4204-989b-053a65534873"
    "id" = "b43b06f7-92d1-0a98-bcc5-b6d13557fafd"
    "Type"  = "Role"
  },
  {
    "resource_app_id" = "62ec2d38-2d53-4204-989b-053a65534873"
    "id" = "019aa34d-20ce-f301-586c-c5a1cbe410cf"
    "type"  = "Role"
  },
  {
    "resource_app_id" = "193b6dcb-1323-4f56-8dc5-eed6f9a2789e"
    "id" = "c72de1fc-b40d-4bfc-a08a-79a23c486cc7"    
    "type"  = "Role"
  },
]

Desired output


requiredResourceAccess": [
        {
            "resourceAppId": "62ec2d38-2d53-4204-989b-053a65534873",
            "resourceAccess": [
                {
                    "id": "b43b06f7-92d1-0a98-bcc5-b6d13557fafd",
                    "type": "Role"
                },
                {
                    "id": "019aa34d-20ce-f301-586c-c5a1cbe410cf",
                    "type": "Role"
                }
            ]
        },
        {
            "resourceAppId": "193b6dcb-1323-4f56-8dc5-eed6f9a2789e",
            "resourceAccess": [
                {
                    "id": "c72de1fc-b40d-4bfc-a08a-79a23c486cc7",
                    "type": "Role"
                } 
            ]
        }

Upvotes: 2

Views: 78

Answers (1)

Helder Sepulveda
Helder Sepulveda

Reputation: 17594

Yes we can do that with for loops and some of the functions that terraform provides:
( distinct, flatten, if )

variable "input_data" {
  default = [
    {
      "resource_app_id" : "62ec2d38-2d53-4204-989b-053a65534873",
      "id" : "b43b06f7-92d1-0a98-bcc5-b6d13557fafd",  "type" : "Role",
    },
    {
      "resource_app_id" : "62ec2d38-2d53-4204-989b-053a65534873",
      "id" : "019aa34d-20ce-f301-586c-c5a1cbe410cf",  "type" : "Role",
    },
    {
      "resource_app_id" : "193b6dcb-1323-4f56-8dc5-eed6f9a2789e",
      "id" : "c72de1fc-b40d-4bfc-a08a-79a23c486cc7",  "type" : "Role",
    },
  ]
}

locals {
  distinct_resources = distinct(flatten([
    for key, value in var.input_data : [
      value.resource_app_id
    ]
  ]))

  output_data = flatten([
    for key, value in local.distinct_resources : {
      "resourceAppId" = value,
      "resourceAccess" : distinct([
        for k, v in var.input_data : {
          "id" : v.id, "type" : v.type
        } if v.resource_app_id == value
      ])
    }
  ])
}

output "requiredResourceAccess" {
  value = local.output_data
}

I compressed a little bit the input var so the code would fit better in the screen

with that we can run a plan and we would get:

Terraform will perform the following actions:

Plan: 0 to add, 0 to change, 0 to destroy.

Changes to Outputs:
  + requiredResourceAccess = [
      + {
          + resourceAccess = [
              + {
                  + id   = "b43b06f7-92d1-0a98-bcc5-b6d13557fafd"
                  + type = "Role"
                },
              + {
                  + id   = "019aa34d-20ce-f301-586c-c5a1cbe410cf"
                  + type = "Role"
                },
            ]
          + resourceAppId  = "62ec2d38-2d53-4204-989b-053a65534873"
        },
      + {
          + resourceAccess = [
              + {
                  + id   = "c72de1fc-b40d-4bfc-a08a-79a23c486cc7"
                  + type = "Role"
                },
            ]
          + resourceAppId  = "193b6dcb-1323-4f56-8dc5-eed6f9a2789e"
        },
    ]

------------------------------------------------------------------------

Tested with "terraform_version": "0.14.5"


Also I want to point out that your initial input has type with different case:

input_data = [
  { ...
    "Type"  = "Role"
  },
  { ...
    "type"  = "Role"
  },

I'm assuming that was a typo and all should be on the same case, if not that will cause errors.

Upvotes: 2

Related Questions