I have Terraform scripts which create infrastructure resources and provisions them through the use of Ansible. One of the last steps in configuring the resources is the execution of a local Ansible playbook. The playbook has its own set of variables and now there are multiple locations for variables to be maintained. Additionally, using roles implies we need to set variables for the roles to do their job in our particular case.
The Ansible documentation states we can specify extra variable through the --extra-vars parameter. Although it takes a string of key-value pairs, this approach can become unwieldy when the number of variables increases. One way around this is to use a file:
ansible-playbook release.yml --extra-vars "@some_file.json"
The above populates Ansible variables through the file "some_file.json
". The "at" symbol (@) tells Ansible the argument is the name of a file to be read.
This now brings us to create that file in Terraform. This is where Terraform templates address our problem.
We can create a file with loads of variables specified for the terraform job and even include some dynamic Terraform variables like IP addresses of hosts we created.
{
"admin_email": "${email}",
"document_root": "${directory}",
"domain_name": "${domain}",
"host_name": "${host_name}",
"relay_host": "${relay_host}",
"relay_login": "${relay_user}",
"relay_password": "${relay_pass}"
}
Note the above is a JSON file; nothing complicated. The Terraform variables will be interpolated when we create the file. Inside our Terraform file we only need to create a data section:
data "template_file" "test" {
template = "${file("./ansible-vars.json.tpl")}"
// populate the template variables with these values
vars {
email = "${var.admin_email}"
domain = "${var.domain_name}"
directory = "${var.document_root}"
host_name = "${var.name}"
relay_host = "${var.relay_host}"
relay_user = "${var.relay_login}"
relay_pass = "${var.relay_passwd}"
}
}
The above section will create a file named "ansible-vars.json
" which will contain the values of our Terraform variables.
Now it is possible to call your ansible playbook with the file with the variables instead of numerous "--extra-vars
" arguments:
provisioner "local-exec" {
command = "ansible-playbook -u ${var.ssh_user} -i '${google_compute_instance.host.network_interface.0.access_config.0.assigned_nat_ip},' --private-key ${var.ssh_pri_key_file} -T 300 playbook.yml --extra-vars @ansible-vars.json"
}
The above was taken from a Terraform script which created a compute instance in the Google Cloud Platform and called an Ansible playbook "playbook.yml
" to perform configuration management.