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