skip to Main Content

I am seeking to create a two json objects for each Terraform templatefile iteration.

Template

${jsonencode({
  rules = flatten([
    [ for index, value in schemas : {
     "rule-type": "selection",
     "rule-id": "${index + 1}",
       "object-locator": {
         "schema-name": "${value}",
         "table-name": "%"
       },
     }
     ],
  ])
})}

Invoke

variable "schemas" {
  default = ["xxx", "yyy", "zzz"]
}

output "json_rules" {
  value = templatefile("${path.module}/rules.json.tpl", {
    schemas = var.schemas
  })
}

Output

{
  "rules": [
    {
      "object-locator": {
        "schema-name": "xxx",
        "table-name": "%"
      },
      "rule-id": 1,
      "rule-type": "selection"
    },
    {
      "object-locator": {
        "schema-name": "yyy",
        "table-name": "%"
      },
      "rule-id": 2,
      "rule-type": "selection"
    },
    {
      "object-locator": {
        "schema-name": "zzz",
        "table-name": "%"
      },
      "rule-id": 3,
      "rule-type": "selection"
    }
  ]
}

Required Output

{
  "rules": [
    {
      "object-locator": {
        "schema-name": "xxx",
        "table-name": "%"
      },
      "rule-id": 1,
      "rule-type": "selection"
    },
    {
        "rule-type": "transformation",
        "rule-id": "2",
        "rule-action": "rename",
        "rule-target": "schema",
        "object-locator": {
            "schema-name": "xxx"
        },
        "value": "xxx"
    },
    {
      "object-locator": {
        "schema-name": "yyy",
        "table-name": "%"
      },
      "rule-id": 3,
      "rule-type": "selection"
    },
    {
        "rule-type": "transformation",
        "rule-id": "4",
        "rule-action": "rename",
        "rule-target": "schema",
        "object-locator": {
            "schema-name": "yyy"
        },
        "value": "yyy"
    },
    {
      "object-locator": {
        "schema-name": "zzz",
        "table-name": "%"
      },
      "rule-id": 5,
      "rule-type": "selection"
    },
    {
        "rule-type": "transformation",
        "rule-id": "6",
        "rule-action": "rename",
        "rule-target": "schema",
        "object-locator": {
            "schema-name": "zzz"
        },
        "value": "zzz"
    },
  ]
}

Any tips or ideas on how this can be achieved would be appreciated.

#Edit 1

By updating the templatefile as seen below it creates the required output, but the index is not working correctly

${jsonencode({
  rules = flatten([
    [ for index, value in schemas : [
    {
        "rule-type": "selection",
        "rule-id": index + 1,
        "object-locator": {
            "schema-name": "${value}",
            "table-name": "%"
       }
     },
    {
       "rule-type": "transformation",
       "rule-id": index + 2
       "rule-action": "rename",
       "rule-target": "schema",
       "object-locator": {
            "schema-name": "${value}"
       }
     }]
     ],
  ])
})}

Revised Output

{
  "rules": [
    {
      "object-locator": {
        "schema-name": "xxx",
        "table-name": "%"
      },
      "rule-id": 1,
      "rule-type": "selection"
    },
    {
      "object-locator": {
        "schema-name": "xxx"
      },
      "rule-action": "rename",
      "rule-id": 2,
      "rule-target": "schema",
      "rule-type": "transformation"
    },
    {
      "object-locator": {
        "schema-name": "yyy",
        "table-name": "%"
      },
      "rule-id": 2,
      "rule-type": "selection"
    },
    {
      "object-locator": {
        "schema-name": "yyy"
      },
      "rule-action": "rename",
      "rule-id": 3,
      "rule-target": "schema",
      "rule-type": "transformation"
    },
    {
      "object-locator": {
        "schema-name": "zzz",
        "table-name": "%"
      },
      "rule-id": 3,
      "rule-type": "selection"
    },
    {
      "object-locator": {
        "schema-name": "zzz"
      },
      "rule-action": "rename",
      "rule-id": 4,
      "rule-target": "schema",
      "rule-type": "transformation"
    }
  ]
}

2

Answers


  1. Chosen as BEST ANSWER

    Thank you user202311 and Ngenator, both approaches work very well.

    rule-id : index(var.schemas, value) + i + 1
    

    or

    rule-id : i * 2 + 1
    

  2. The main problem is that you’re trying to create the rule numbers based off of just the index. Since var.schemas is a tuple, you can use the index() function to adjust your rule ID calculation.

    To make things simpler within the answer, I’ve added a rules output and removed the templatefile call so everything exists in a single file but you can apply the same logic within the template if needed.

    $ terraform --version
    Terraform v1.10.3
    on linux_amd64
    

    main.tf

    variable "schemas" {
      default = ["xxx", "yyy", "zzz"]
    }
    
    locals {
      rules = flatten([for i, value in var.schemas : [
        {
          rule-type : "selection",
          rule-id : index(var.schemas, value) + i + 1,
          object-locator : {
            schema-name : "${value}",
            table-name : "%"
          }
        },
        {
          rule-type : "transformation",
          rule-id : index(var.schemas, value) + i + 2
          rule-action : "rename",
          rule-target : "schema",
          object-locator : {
            schema-name : "${value}"
          }
        }]
      ])
    
      json_rules = jsonencode({
        rules = local.rules
      })
    }
    
    output "rules" {
      value = local.rules
    }
    
    output "json_rules" {
      value = local.json_rules
    }
    

    Running terraform apply gives us

    
    Changes to Outputs:
      + json_rules = jsonencode(
            {
              + rules = [
                  + {
                      + object-locator = {
                          + schema-name = "xxx"
                          + table-name  = "%"
                        }
                      + rule-id        = 1
                      + rule-type      = "selection"
                    },
                  + {
                      + object-locator = {
                          + schema-name = "xxx"
                        }
                      + rule-action    = "rename"
                      + rule-id        = 2
                      + rule-target    = "schema"
                      + rule-type      = "transformation"
                    },
                  + {
                      + object-locator = {
                          + schema-name = "yyy"
                          + table-name  = "%"
                        }
                      + rule-id        = 3
                      + rule-type      = "selection"
                    },
                  + {
                      + object-locator = {
                          + schema-name = "yyy"
                        }
                      + rule-action    = "rename"
                      + rule-id        = 4
                      + rule-target    = "schema"
                      + rule-type      = "transformation"
                    },
                  + {
                      + object-locator = {
                          + schema-name = "zzz"
                          + table-name  = "%"
                        }
                      + rule-id        = 5
                      + rule-type      = "selection"
                    },
                  + {
                      + object-locator = {
                          + schema-name = "zzz"
                        }
                      + rule-action    = "rename"
                      + rule-id        = 6
                      + rule-target    = "schema"
                      + rule-type      = "transformation"
                    },
                ]
            }
        )
      + rules      = [
          + {
              + object-locator = {
                  + schema-name = "xxx"
                  + table-name  = "%"
                }
              + rule-id        = 1
              + rule-type      = "selection"
            },
          + {
              + object-locator = {
                  + schema-name = "xxx"
                }
              + rule-action    = "rename"
              + rule-id        = 2
              + rule-target    = "schema"
              + rule-type      = "transformation"
            },
          + {
              + object-locator = {
                  + schema-name = "yyy"
                  + table-name  = "%"
                }
              + rule-id        = 3
              + rule-type      = "selection"
            },
          + {
              + object-locator = {
                  + schema-name = "yyy"
                }
              + rule-action    = "rename"
              + rule-id        = 4
              + rule-target    = "schema"
              + rule-type      = "transformation"
            },
          + {
              + object-locator = {
                  + schema-name = "zzz"
                  + table-name  = "%"
                }
              + rule-id        = 5
              + rule-type      = "selection"
            },
          + {
              + object-locator = {
                  + schema-name = "zzz"
                }
              + rule-action    = "rename"
              + rule-id        = 6
              + rule-target    = "schema"
              + rule-type      = "transformation"
            },
        ]
    
    You can apply this plan to save these new output values to the Terraform state, without changing any real infrastructure.
    
    Do you want to perform these actions?
      Terraform will perform the actions described above.
      Only 'yes' will be accepted to approve.
    
      Enter a value: yes
    
    
    Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
    
    Outputs:
    
    json_rules = "{"rules":[{"object-locator":{"schema-name":"xxx","table-name":"%"},"rule-id":1,"rule-type":"selection"},{"object-locator":{"schema-name":"xxx"},"rule-action":"rename","rule-id":2,"rule-target":"schema","rule-type":"transformation"},{"object-locator":{"schema-name":"yyy","table-name":"%"},"rule-id":3,"rule-type":"selection"},{"object-locator":{"schema-name":"yyy"},"rule-action":"rename","rule-id":4,"rule-target":"schema","rule-type":"transformation"},{"object-locator":{"schema-name":"zzz","table-name":"%"},"rule-id":5,"rule-type":"selection"},{"object-locator":{"schema-name":"zzz"},"rule-action":"rename","rule-id":6,"rule-target":"schema","rule-type":"transformation"}]}"
    rules = [
      {
        "object-locator" = {
          "schema-name" = "xxx"
          "table-name" = "%"
        }
        "rule-id" = 1
        "rule-type" = "selection"
      },
      {
        "object-locator" = {
          "schema-name" = "xxx"
        }
        "rule-action" = "rename"
        "rule-id" = 2
        "rule-target" = "schema"
        "rule-type" = "transformation"
      },
      {
        "object-locator" = {
          "schema-name" = "yyy"
          "table-name" = "%"
        }
        "rule-id" = 3
        "rule-type" = "selection"
      },
      {
        "object-locator" = {
          "schema-name" = "yyy"
        }
        "rule-action" = "rename"
        "rule-id" = 4
        "rule-target" = "schema"
        "rule-type" = "transformation"
      },
      {
        "object-locator" = {
          "schema-name" = "zzz"
          "table-name" = "%"
        }
        "rule-id" = 5
        "rule-type" = "selection"
      },
      {
        "object-locator" = {
          "schema-name" = "zzz"
        }
        "rule-action" = "rename"
        "rule-id" = 6
        "rule-target" = "schema"
        "rule-type" = "transformation"
      },
    ]
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search