Both Terraform and Ansible are DevOps tools, but how do these DevOps tools differ? In short, Terraform is an open-source, Infrastructure as Code platform, while Ansible is an open-source configuration management tool focused on the configuration of that infrastructure.
It is often a topic of discussion about whether one should use Terraform or Ansible for infrastructure management. Fortunately, there is an answer that lies in the Grey area. This answer seems the same when asked to people who have working experience on both the tools.
This post highlights similarities between Terraform and Ansible, explores the differences and concludes with the best way to manage infrastructure.
At a very high level, given the capabilities of both the products, Terraform and Ansible come across as similar tools. Both of them are capable of provisioning the new cloud infrastructure and configuring the same with required application components.
Both Terraform and Ansible are capable of executing remote commands on the virtual machine that is newly created. This means, both the tools are agentless. There is no need to deploy agents on the machines for operational purposes.
Terraform uses cloud provider APIs to create infrastructure and basic configuration tasks are achieved using SSH. The same goes with Ansible – it uses SSH to perform all the required configuration tasks. The “state” information for both does not require a separate set of infrastructure to manage, thus both the tools are masterless.
The previous section gives an overview of the two tools in their broadest similarities. At a high level, it sounds like both Terraform and Ansible are capable of provisioning and configuration management. However, a deeper dive into them makes us realize the benefits of one over the other in certain areas.
In general, both the tools are great in their own ways. They have an overlap of functions when it comes to infrastructure management. Infrastructure management broadly encompasses 2 aspects – orchestration and configuration management.
Terraform and Ansible have their own ways of managing both – with strong and weak points when it comes to overlaps. Thus, it is important to delve into some details of both the tools to make a “perfect” choice or a combination with boundaries.
Orchestration vs. Configuration Management
Orchestration/provisioning is a process where we create the infrastructure – virtual machines, network components, databases, etc. Whereas, on the other hand, configuration management is a process of automating versioned software component installation, OS configuration tasks, network and firewall configuration, etc.
Both Terraform and Ansible are capable of performing both tasks. However, Terraform offers a comprehensive solution to manage infrastructure. Terraform uses cloud provider APIs to provision and de-provision the infrastructure based on declared resources.
Ansible on the other hand is also capable of provisioning the cloud infrastructure but it is not comprehensive enough. It is mainly geared towards configuration management. Configuration management is a process of keeping the applications and dependencies up to date. This is where Ansible really shines as compared to Terraform.
Both the tools can perform both kinds of activities. However, there are limitations when implementing configuration management using Terraform, and infrastructure automation using Ansible. They are not flexible enough when it comes to complex infrastructure management.
Logically, we can identify orchestration as Day 0 activity and configuration management as Day 1 activity. Terraform works best for Day 0 activities and Ansible for Day 1 and onwards activities.
Declarative vs. Procedural
Terraform is used to write infrastructure as code (IaC). It uses HCL (Hashicorp Configuration Language) which is declarative in nature. It doesn’t matter in which sequence the code is written. The code could also be dispersed in multiple files.
No matter how you write the code, Terraform identifies the dependencies, and provisions infrastructure. Writing or translating existing infrastructure to code is easy in Terraform. Check this post if you would like to know more about importing infrastructure under Terraform management.
Ansible uses YAML syntax to define the procedure to perform on the target infrastructure. Ansible YAML scripts are procedural in nature – meaning when you write the script, it will be executed from top to bottom.
Ansible scripts are called “ansible playbooks”. When you have to perform certain series of tasks, you define the same in the playbook. The tasks will be performed in the sequence they are written. For example, to install an Apache server on the given virtual machine as a root user, you would have to write the user creation step before defining the task for installation.
Mutable vs. Immutable
A configuration is mutable when it is possible to change it without rebooting or replacing the infrastructure. If not, the configuration is considered immutable.
In the case of Terraform, the line between mutability and immutability depends on a few factors. Terraform takes the desired state of infrastructure as input and provisions it. When a change is introduced, Terraform bases its decision on the nature of the change itself.
If it is not possible for the cloud provider to implement the change without rebooting or replacing the infrastructure, then Terraform mutates the infrastructure. It destroys the older infra component and replaces it with a new one with the latest configuration setting. This mutability also depends on various dependencies within the resources, e.g., network components.
Other changes which do not require replacement, Terraform does not replace the infrastructure. For example, changing the instance type on the AWS EC2 instance does not cause resources to be replaced. However, changing the AMI causes the resource to be replaced.
Ansible on the other hand is immutable by default. Ansible attempts to keep the configuration changes consistent as per the latest version of the playbook. Any changes introduced do not cause any “replacement” of the underlying infrastructure. It only repairs or modifies configuration on the given component.
Over time, servers managed by Ansible record the changes to the configuration they have undergone. This may cause other servers to have different configurations if not managed properly. This phenomenon is known as configuration drift.
By default, although capable, Terraform works with a mutable approach, and Ansible works with an immutable approach. Having said that, the two tools are also capable of both approaches with limits.
Terraform manages the entire lifecycle of the resources under its management. It maintains the mapping of infrastructure resources with current configuration in state files. State management plays a very important role in Terraform.
States are used to track changes to the configuration and provision the same. It is also possible to import existing resources under Terraform management by importing the real-world infrastructure in state files.
At any given time, it is possible to query the Terraform state files to understand the infrastructure component and their attributes currently available.
As opposed to this, Ansible does not support any lifecycle management. Since Ansible mainly deals with configuration management and considering it defaults to immutable infrastructure, any changes introduced in the configuration are executed automatically on the target resource.
As we have known till now, Terraform works best with orchestration and Ansible is great at configuration management.
Of course, they have the capabilities to perform each other’s tasks, although in a limited manner. In such a situation, instead of making a firm choice, it is better to leverage both tools for infrastructure management, based on their respective strengths.
The answer to the question “which tool to use?” is – it depends. It depends on how the infrastructure management process is currently shaped. It is important to find the right balance of orchestration and configuration management to assign clear responsibilities to the respective tools.
If you are looking to manage infrastructure as code, Spacelift is the way to go. It supports Git workflows, policy as code, programmatic configuration, context sharing, and many more great features. It currently works with Terraform and Pulumi, with support for Ansible and CloudFormation on the way!