For a project I’m working on, I needed to define a list of ports, and set some properties on some of them. In the Ansible world, you’d use statements like:
{% if data.somekey is defined %}something {{ data.somekey }}{% endif %}
or
{{ data.somekey | default('') }}
In a pinch, you can also do this:
{{ (data | default({}) ).somekey | default('') }}
With Terraform, I was finding it much harder to work out how to find whether a value as part of a map (the Terraform term for a Dictionary in Ansible terms, or an Associative Array in PHP terms), until I stumbled over the Lookup function. Here’s how that looks for just a simple Terraform file:
output "test" {
value = templatefile(
"template.tmpl",
{
ports = {
"eth0": {"ip": "192.168.1.1/24", "name": "public"},
"eth1": {"ip": "172.16.1.1/24", "name": "protected"},
"eth2": {"ip": "10.1.1.1/24", "name": "management", "management": true},
"eth3": {}
},
management = "1"
}
)
}
And the template that goes with that?
%{ for port, data in ports ~}
Interface: ${port}%{ if lookup(data, "name", "") != ""}
Alias: ${ lookup(data, "name", "") }%{ endif }
Services: ping%{ if lookup(data, "management", false) == true } ssh https%{ endif }
IP: ${ lookup(data, "ip", "Not Defined") }
%{ endfor }
This results in the following output:
C:\tf>terraform.exe apply -auto-approve
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
test = Interface: eth0
Alias: public
Services: ping
IP: 192.168.1.1/24
Interface: eth1
Alias: protected
Services: ping
IP: 172.16.1.1/24
Interface: eth2
Alias: management
Services: ping ssh https
IP: 10.1.1.1/24
Interface: eth3
Services: ping
IP: Not Defined
Naturally, using this in your own user-data or Custom Data field will probably make more sense than just writing it to “output” 😁
Featured image is “Stockholms Stadsbibliotek” by “dilettantiquity” on Flickr and is released under a CC-BY-SA license.