Terraform to create Ansible-Inverntory

When working with a combination of Terraform and Ansible I came across terraform-inventory which does not fit for my purposes to have a ansible-hostgroup per module call with X=3 EC2 instances.

So I came up with my own solution.
The following will create a local_file on the machine which runs terraform apply . In this case under ansible/ansible_inventory .

You can than use it to run your playbooks agains those ansible-hostgroups .

Terraform needs to output (in my case) the ec2-names ec2_name_output which comes from my Terraform-module and the ec2-eip or ec2-pip (private-IP) when you dont have DNS pointing to those instances in place.

When you have those outputs simply do a content with a formated list:

resource "local_file" "ansible_inventory" {
count = "${length(module.elasticsearch.ec2_name_output)}"
content = "[${module.elasticsearch.ec2_purpose}]\n${join("\n",
formatlist(
"%s ansible_host=%s",
module.elasticsearch.ec2_name_output,
module.elasticsearch.ec2_eip_output
)
)}\n\n[${module.elasticsearch.ecs_purpose_output}:vars]\nansible_user=MrAnderson\n\n\n[${module.logstash.ecs_purpose_output}]\n${join("\n",
formatlist(
"%s ansible_host=%s",
module.logstash.ec2_name_output,
module.logstash.ec2_eip_output
)
)}\n\n[${module.logstash.ecs_purpose_output}:vars]\nansible_user=MrAnderson\n\n\n[${module.kibana.ecs_purpose_output}]\n${join("\n",
formatlist(
"%s ansible_host=%s",
module.kibana.ec2_name_output,
module.kibana.ec2_eip_output
)
)}\n\n[${module.kibana.ecs_purpose_output}:vars]\nansible_user=MrAnderson"
filename = "ansible/ansible_inventory"
}

We are using the terraform provider local_file which will create a file with the content we specifiy below

resource "local_file" "ansible_inventory"
count = "${length(module.elasticsearch.ec2_name_output)}"

This will give you the length of all ec2-names so we can than iterate through every entry in our variable list(s).

%s is the placeholder for the following variables and can be used for as many variables you want to have.

%s ansible_host=%s will be followed by the variables which should replace the placeholders.

This results in:

[elasticsearch]
elasticsearch-01 ansible_host=1.2.3.4
elasticsearch-02 ansible_host=2.3.4.5
elasticsearch-03 ansible_host=3.4.5.6
[elasticsearch:vars]
ansible_user=MrAnderson
[logstash]
logstash-01 ansible_host=4.5.6.7
logstash-02 ansible_host=5.6.7.8
logstash-03 ansible_host=6.7.8.9
[logstash:vars]
ansible_user=MrAnderson
[kibana]
kibana-01 ansible_host=7.8.9.10
kibana-02 ansible_host=8.9.10.11
kibana-03 ansible_host=9.10.11.12
[kibana:vars]
ansible_user=MrAnderson

Now you can run your playbook against your instances.

ansible-playbook -i ansible/ansible_inventory playbook.yml

  • In the shown example you have to make sure that all your modules are creating the same amount of instances…
    Any suggestions how to get rid of this are very welcome.

Cheers!

Working as a IT-Operations engineer at NeXenio, a spin-off by Hasso-Plattner-Institute for products around a digitial workspace.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store