Terraform to create Ansible-Inverntory

D. Heinrich
2 min readJan 17, 2019

--

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"
}

Terraform Provider

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

resource "local_file" "ansible_inventory"

Iterate over every instance:

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).

Formatting:

%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

Limitations

  • 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!

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

D. Heinrich
D. Heinrich

Written by D. Heinrich

Working as a Head of Infrastructure at Flower Labs.

No responses yet

Write a response