Terraform

Things I had to learn the hard way, should have called it "Terror Form"

Generating Ansible Inventory

This is the easiest way I've found; There are dynamic ansible inventories, but the code is vast and often unmaintained. I'm keeping it simple.

Start off with a file called templates/ansible/inventory.tmpl Tweak this to your own requirements.

[consul_server]
%{ for server in consul_servers ~}
${server.public} ipv4_address_private=${server.private}
%{ endfor ~}
[nomad_server]
%{ for server in nomad_servers ~}
${server.public} ipv4_address_private=${server.private}
%{ endfor ~}
[consul_client]
%{ for server in nomad_servers ~}
${server.public} ipv4_address_private=${server.private}
%{ endfor ~}
%{ for id, server in nomad_clients ~}
${server.public} ipv4_address_private=${server.private}
%{ endfor ~}
[nomad_client]
%{ for server in nomad_clients ~}
${server.public} ipv4_address_private=${server.private} %{ if server.floating != "" }ipv4_address_floating=${server.floating}%{ endif }s
%{ endfor ~}

Then in your Terraform module, you can use the following to generate the template file to a local variable.

locals {
ansible_inventory = templatefile("${path.module}/templates/ansible/inventory.tmpl", {
consul_servers = [
{
public = "127.0.0.1"
private = "10.0.0.0"
}
]
nomad_servers = [
{
public = "127.0.0.1"
private = "10.0.0.0"
}
]
nomad_clients = [
{
public = "127.0.0.1"
private = "10.0.0.0"
floating = "10.0.1.0"
}
]
}

Followed by a local file resource to output it to the Terraform machine.

resource "local_file" "ansible_inventory" {
filename = "${path.module}/build/ansible/inventory"
content = local.ansible_inventory
}

Types

Some things when using the Terraform types.

  1. Strictly typed, so "127.0.0.1" is not equal to 127.0.0.1 Use type conversion functions.