Creating ansible inventory for multiple target hosts Creating ansible inventory for multiple target hosts json json

Creating ansible inventory for multiple target hosts


As pointed out by @ydaetskcoR's comment, your inventory is wrong because you need the list of hosts to be an immediate child of the hosts attribute.


Note that the list you end up with is produced by the use of the brackets [], producing tuples, around for in your Terraform template as opposed to the use of the bracket {}, producing objects.

The type of brackets around the for expression decide what type of result it produces. The above example uses [ and ], which produces a tuple. If { and } are used instead, the result is an object, and two result expressions must be provided separated by the => symbol.

https://www.terraform.io/docs/configuration/expressions.html#for-expressions


If your structure, should look like all > server1, server2, server3

Then your inventory should be

all:  hosts:    server1:      ansible_host: 10.0.0.2      ansible_port: 5986    server2:      ansible_host: 10.0.0.3      ansible_port: 5986    server3:      ansible_host: 10.0.0.4      ansible_port: 5986

This is an approach for a Terraform template producing this:

${yamlencode({  "all": {    "hosts": {      for i, ip in vm-ip:        "server${i+1}" => {          "ansible_host": "${ip}",          "ansible_port": 5986        }    }  }})}

Which gives this valid inventory.yaml:

"all":  "hosts":    "server1":      "ansible_host": "10.0.0.2"      "ansible_port": 5986    "server2":      "ansible_host": "10.0.0.3"      "ansible_port": 5986    "server3":      "ansible_host": "10.0.0.4"      "ansible_port": 5986

On the other hand, if you want a structure like all > server > server1, server2, server3

Then you should make server a child of all and use the children entry in your inventory:

all:  children:    server:      hosts:        server1:          ansible_host: 10.0.0.2          ansible_port: 5986        server2:          ansible_host: 10.0.0.3          ansible_port: 5986        server3:          ansible_host: 10.0.0.4          ansible_port: 5986

For this one, the corresponding Terraform template would be

${yamlencode({  "all": {    "children": {      "server": {        "hosts": {          for i, ip in vm-ip:            "server${i+1}" => {              "ansible_host": "${ip}",              "ansible_port": 5986            }        }      }    }  }})}

Which produce this inventory.yaml:

"all":  "children":    "server":      "hosts":        "server1":          "ansible_host": "10.0.0.2"          "ansible_port": 5986        "server2":          "ansible_host": "10.0.0.3"          "ansible_port": 5986        "server3":          "ansible_host": "10.0.0.4"          "ansible_port": 5986

Note: for all the examples above, I am using the terraform file test.tf below:

resource "local_file" "AnsibleInventory" {  content = templatefile("inventory.tpl", {    vm-ip = ["10.0.0.2","10.0.0.3","10.0.0.4"],  })  filename = "inventory.yaml"}