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
Thank you user202311 and Ngenator, both approaches work very well.
or
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 theindex()
function to adjust your rule ID calculation.To make things simpler within the answer, I’ve added a
rules
output and removed thetemplatefile
call so everything exists in a single file but you can apply the same logic within the template if needed.main.tf
Running
terraform apply
gives us