Ansible or Terraform? Both!

Terraform and Ansible are the most popular IT Automation Tools and probably every DevOps engineer is using either of them. But many of them are asking themselves: “I am using Ansible and it serves me well. Why should I bother to learn Terraform?” Or the other way around: “I am familar with Terraform, I do not need other tools!”. This Article will show why this might not be the best approach to look at things.

A decade ago when I started with IT Automation there was no Ansible and there was no Terraform. What we had was the grandmother of modern IT Automation tools: CFEngine. It was a rather tedious task to set it up. We had to configure agents on the clients, authentication, cronjobs, automation servers and so on. Once it was set up it served us well. Think of managing your cloud infrastructure that way today.


There is no clear definition out there on what Ansible and Terraform are and I am not trying to fix that. Here is just a quick look on what Ansible is designed for and what it does very well. It is a collection of idempotent scripts and orchestrates them. It is task oriented. A configuration for Ansible looks like this:

# Pseudo Code for Ansible 
Go to machine1 and run idempotent script1
Go to machine2 and run idempotent script1
Go to machine4 and run idempotent script3
Go to machine1 and run idempotent script2
Go to machine 3 and run idempotent script9
ansible cluster_machine1 machine1 cluster_machine2 machine2 cluster_machine4 machine4 cluster_machine3 machine3 a1 idempotent script 1 b2 idempotent script 1 a1->b2 d1 idempotent script 2 e3 idempotent script 9 d1->e3 c4 idempotent script 3 b2->c4 c4->d1

If script3 depends on script1 Ansible does not know about that. It has no memory of what it has already done in the past. Each invocation will run the same scripts again.


Terraform works differently.

# Pseudo Code for Terraform
Configure resource1 (depends on resource12 and resource2)
Configure resource2 (depends on resource3)
Configure resource3 ()
Configure resource12 (depends on resource3)
terraform resource1 resource1 resource2 resource2 resource2->resource1 resource3 resource3 resource3->resource2 resource12 resource12 resource3->resource12 resource12->resource1

Terraforms strength is its ability to manage dependencies. It builds a tree of dependencies and memorizes what it has already done in a state file. That state file is what makes its outcome idempotent. Let’s say we want to change resource1. Terraform will just do that: change resource1. If you change resource3 instead Terraform knows that is has to change all other resources as well. Think of what happens if you try to include that logic in your Ansible playbooks and your infrastructure grows to hundreds or thousand of resources.

The whole is more than the sum of its parts.

I am not sure if Aristotle predicted modern cloud infrastructures but I am pretty sure he would love Microservices. Modern cloud infrastructures are based on this most basic UNIX principle. KISS: keep it simple, stupid. That means every single component should do what it was designed for and do it well. Real power comes when we are creative and combine them.

Let us take a simple example. We want to provision infrastructure2 and that task depends on infrastructure1. After we are done we want to destroy infrastructure1 to save costs. We can do that by using Ansible as an orchestrator for Terraform.

# Pseudo Code for Ansible
Provision infrastructure1 with Terraform
Provision infrastructure2 with Terraform
Destroy infrastructure1 with Terraform

It is not only the tools that help us to progress. It is our creativity. Be creative!

Btw. are you aware of any DevOps Engineer who provisions cloud infrastructures with CFEngine?