Reputation: 879
I am trying to set up my DNS zones and records with in those zones and I can't get the structured collection I am looking for to pass into the tf file that will generate all the zones and records. I have a list of DNS objects and each object will have multiple lists of record objects. I am trying to create lists of just records (a, cname, txt, ...). Im trying merges and flattening and I just not sure how to get what I need. I keep trying different patterns with merge and flatten but keep getting errors in different configurations.
Errors:
Error: Invalid 'for' expression. Extra characters after the end of the 'for' expression.
Error: Missing attribute value. Expected an attribute value, introduced by an equals sign ("=").
Error: Invalid 'for' expression. Key expression is required when building an object.
Error: Missing key/value separator. Expected an equals sign ("=") to mark the beginning of the attribute value.
Variable Definition:
variable "dns_target_child_zones" {
type = list(object({
name = string
a_records = list(object({
name = string
ttl = number
ip_address = string
}))
cname_records = list(object({
name = string
ttl = number
record = string
}))
mx_records = list(object({
name = string
ttl = number
record = list(object({
preference = number
exchange = string
}))
}))
txt_records = list(object({
name = string
ttl = number
record = list(object({
value = string
}))
}))
}))
}
Locals file:
locals {
a_records = flatten ([
])
cname_records = flatten ([
])
mx_records = flatten ([
])
txt_records = flatten ([
])
}
The output structure I am trying to produce so I can do something like count = length(locals.a_records)
[
{
name =
zone_name =
ttl =
records =
},
{
name =
zone_name =
ttl =
records =
}
...
]
Upvotes: 3
Views: 3825
Reputation: 198
Here's an example of the local object you could create for a_records (note: I included the ip_address attribute but you have records which doesn't appear in the a_records variable object):
a_records = flatten([
for v in var.dns_target_child_zones : [
for record in v.a_records : {
name = record.name
zone_name = v.name
ttl = record.ttl
ip_address = record.ip_address
}
]
])
This will product an output like the following:
+ a_records = [
+ {
+ ip_address = "ip1"
+ name = "a1"
+ ttl = 10
+ zone_name = "dns1"
},
+ {
+ ip_address = "ip2"
+ name = "a2"
+ ttl = 10
+ zone_name = "dns1"
},
]
I used a default value and an output to test the expected result. Here's my full test, which you can run terraform plan for to show the output
variable "dns_target_child_zones" {
type = list(object({
name = string
a_records = list(object({
name = string
ttl = number
ip_address = string
}))
cname_records = list(object({
name = string
ttl = number
record = string
}))
mx_records = list(object({
name = string
ttl = number
record = list(object({
preference = number
exchange = string
}))
}))
txt_records = list(object({
name = string
ttl = number
record = list(object({
value = string
}))
}))
}))
default = [{
name = "dns1",
a_records = [{
name = "a1",
ttl = 10
ip_address = "ip1"
},
{
name = "a2",
ttl = 10
ip_address = "ip2"
}
],
cname_records = [{
name = "cname1",
ttl = 10
record = "rec1"
}],
mx_records = [{
name = "mx1",
ttl = 10,
record = [{
preference = 1,
exchange = "exchange1"
}, {
preference = 2,
exchange = "exchange2"
}]
}],
txt_records = [{
name = "txt1",
ttl = 10,
record = [{
value = "val1"
}]
}]
}]
}
locals {
a_records = flatten([
for v in var.dns_target_child_zones: [
for record in v.a_records: {
name = record.name
zone_name = v.name
ttl = record.ttl
ip_address = record.ip_address
}
]
])
}
output "a_records" {
value = local.a_records
}
For further nesting extraction e.g with mx_records then you can add another for loop in your local like the below
mx_records = flatten([
for v in var.dns_target_child_zones : [
for mx in v.mx_records : [
for r in mx.record : {
name = mx.name
zone_name = v.name
ttl = mx.ttl
preference = r.preference
exchange = r.exchange
}
]
]
])
The above local outputs this result
+ mx_records = [
+ {
+ exchange = "exchange1"
+ name = "mx1"
+ preference = 1
+ ttl = 10
+ zone_name = "dns1"
},
+ {
+ exchange = "exchange2"
+ name = "mx1"
+ preference = 2
+ ttl = 10
+ zone_name = "dns1"
},
]
Upvotes: 3