Author: Tim Fairweather

At Arctiq, we are often asked questions about various DevOps tools in the industry. Recently, given our experience and focus around Ansible and automation in general, we are often asked to provide an opinion on where Ansible from Red Hat and Terraform from Hashicorp overlap.

This small post serves as a perspective on the subject. An opinion with a small scope on some high-level use cases, but in no way a complete representative example of each tools’ strengths or weaknesses. This is NOT a comparison.

Where do Ansible and Terraform Overlap?

Let’s start with the basics. To me, Ansible is a swiss-army knife. There are very few things you CAN’T make happen with Ansible, some creativity, and some background knowledge on the syntax and capabilities. Ansible has experienced a significant userbase uptake that is impressive to say the least. Why? I attribute its success mostly to a lower learning curve than competitive solutions, and its agentless architecture. Terraform on the other hand, is an infrastructure builder, designed out of the box to interact directly with cloud APIs (providers), to first plan (upon which you can validate), and then apply (upon which you build). Once provisioned according to plan, a state file is created/updated to incorporate your changes and persists for the lifecycle of the plan. When you are done with the infrastructure that has been built, destroying according to the state file and plan is a very simple process.

So in effect both tools can be utilized for provisioning infrastructure. Ansible through its various modules, and Terraform through its various providers.

The Difference Between Ansible and Terraform

The two serve the same market segments, and if anything overlap in the use cases they solve. But really only in provisioning as stated above. So how are they different? Where do I use one vs the other?

Firstly, with Terraform we are ONLY talking about building infrastructure (cloud, VMware, etc). Teams are always going to need further orchestration and configuration management leveraging tools like Ansible. Once Terraform has built the infrastructure, Ansible would kick in to finish off the heavy lifting to get the machines configured and working. This can be a very cohesive workflow, and plays to the strengths of both tools.

On the more advanced front, Terraform requires you to be ready to treat infrastructure truly as code. Your entire plan/blueprint exists as a part of your Terraform plan, with which you then apply to your targetted endpoint (AWS, Azure, Google, VMware) to build machines. This concept is not something everyone is ready for, and in many cases where Ansible can and has shored up the gap (adhoc provisioning requests via surveys/variables etc).

In no way is this a complete list but here is a high-level view of where each tool could play:

Tool Task
Terraform Provisioning / De-provisioning of machines
Ansible Orchestration, possibly including orchestrating the Terraform build
Ansible Configuration and advanced deployment of applications and services
Ansible Network automation
Ansible Security, patching, and compliance automation

If you ARE ready (and you should be) to adopt infrastructure as true code, then there are several benefits to the machine provisioning processes that Terraform offers. Combine this with a completely orchestrated automation workflow with Ansible, and you’ve got a winning combination.

Speaking to further integration between the two, both tools are beginning to offer more advanced ways to work together. Ansible 2.5 is slated to release a Terraform module that natively enables Ansible playbooks to orchestrate Terraform tasks. Read more HERE.

# Example deployment of a Terraform plan using Ansible
- terraform:
    project_path: /path/to/project
    state: present

Embedding Ansible into Terraform plans is also a reality today leveraging either a provisioner statement in your TF plan, or via a null resource to separately execute Ansible playbooks once resources are provisioned and ready.

# Example Ansible Tower job template (playbook) execution using a null_resource in Terraform
resource "null_resource" "run-ansible" {
  depends_on = ["null_resource.update_inventory"]
  triggers {
    instance_ids = "${join(",", aws_instance.webservers.*.id)}"
  provisioner "local-exec" {
    command = "curl -qs -X POST -H 'Content-type: application/json' 'https://ansible-tower/api/v2/job_templates/16/launch/'"

What’s Next?

The reality is the provisioning workflow is much more complex. Not only do we need to focus on building infrastructure, we also need focus on security with technologies like Vault, patching and compliance with Satellite, and service discovery with Consul.

Interested in learning more? We have more blog content coming on the above technologies and don’t forget to take the first step and reach out to the Arctiq team!