Tuesday, 11 December 2018 17:23

Pass Terraform Variables to an Ansible Playbook Through a File

Written by
Rate this item
(5 votes)

Using Terraform and Ansible together is a great way to provision both infrastructure and computing resources. Managing variables in both tools can become unwieldy. Here is how to simplify variable management between the two tools.

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.

Last modified on Wednesday, 12 December 2018 11:18
Steve Cote

Steve has been a systems architect for the telecommunications and electric utility industries creating circuit provisioning systems and smart grid solutions. He is a hands-on architect working with teams to deliver large complex projects. More recently, Steve has been consulting agile teams from Fortune 15 organizations, start-ups, and everything in-between to be more productive with DevOps and agile practices.

Leave a comment

Make sure you enter all the required information, indicated by an asterisk (*). HTML code is not allowed.