Infrastructure as Code (IaC) has revolutionized how we deploy and manage IT infrastructure. Instead of manually configuring servers and services or using custom scripts, IaC allows teams to define infrastructure requirements in code, making deployments reproducible, consistent, and version-controlled. At the forefront of this revolution are Ansible and Terraform, two powerful tools that have become fundamental to modern DevOps practices.
Ansible emerged as a simple yet powerful automation tool for configuration management and application deployment. It uses a procedural approach with human-readable YAML syntax to define the desired state of systems. Terraform, on the other hand, was built specifically for infrastructure provisioning using a declarative approach, focusing on maintaining state across multiple cloud providers.
This article aims to help you understand both technologies, their differences, use cases, and how they can complement each other in a modern infrastructure pipeline. We'll explore their architectures, benefits, limitations, and practical scenarios where they shine individually or work together.
Understanding Ansible
Ansible is an open-source automation platform that enables infrastructure as code, application deployment, configuration management, and task automation. It follows a push-based model where a control node executes tasks on managed nodes without requiring any agents to be installed on those systems.
Unlike some other configuration management tools, Ansible uses SSH for communication with remote systems, making it agentless and lightweight. This design allows Ansible to automate both legacy and modern infrastructure without adding overhead to managed systems.
Ansible sits at the intersection of configuration management and orchestration:
Configuration management: Ansible ensures systems are in a desired state by installing packages, configuring services, and managing files
Orchestration: Ansible can coordinate complex multi-step processes across multiple systems, such as application deployments or infrastructure updates
Key Ansible components
1. Playbooks
Playbooks are Ansible's configuration, deployment, and orchestration language. They describe a policy you want your remote systems to enforce or a set of steps in a general IT process. Playbooks are written in YAML format, making them easy to read and write.
Here's an example of a simple playbook that installs and starts the Nginx web server:
To run this playbook:
This command will execute the playbook against all hosts in the "webservers" group defined in your inventory.
2. Roles
Roles in Ansible provide a way to organize playbooks and all related files (such as variables, handlers, and tasks) to make them more reusable and modular. Roles have a specific directory structure:
You can reference and use roles in a playbook like this:
3. Modules
Modules are the units of work in Ansible. Each module is designed to handle a specific task, such as managing packages, users, files, or services. Ansible comes with over 3,000 built-in modules, and you can also write custom modules if needed.
Common modules include:
apt/yum: For package managementservice: For managing servicescopy/template: For file managementuser: For user managementcommand/shell: For executing commands or scripts
Example of using modules in an ad-hoc command:
This command uses the apt module to ensure Nginx is installed on all servers
in the "webservers" group.
4. Inventory files
Inventory files define the hosts and groups of hosts upon which commands,
modules, and tasks in a playbook operate. The default inventory file is located
at /etc/ansible/hosts, but you can specify a different inventory file at the
command line.
Here's an example inventory file:
This inventory defines two groups (webservers and dbservers), a group that
includes both groups (dc), and sets variables that apply to the dc group.
Benefits of Ansible
Agentless architecture: Ansible only requires SSH and Python on the managed nodes, eliminating the need to install and maintain agents. This makes it particularly suitable for environments where installing additional software is challenging or prohibited.
Human-readable YAML syntax: Playbooks are written in YAML, which is easy to learn and understand, even for those without extensive programming experience. This low barrier to entry makes Ansible accessible to a wide range of IT professionals.
Extensive module library: With thousands of built-in modules, Ansible can automate virtually any IT task, from managing cloud resources to configuring network devices.
Idempotency: Ansible modules are designed to be idempotent, meaning they can be run multiple times without changing the result beyond the initial application. If a system is already in the desired state, Ansible won't make unnecessary changes.
Limitations of Ansible
Primarily procedural approach: Ansible follows a primarily procedural approach, executing tasks in sequence. This can make complex state management more challenging compared to declarative tools.
Limited state management: Ansible doesn't maintain a state file of managed resources (unlike Terraform). It determines the current state by directly querying systems, which can sometimes lead to drift if changes are made outside of Ansible.
Performance with large infrastructures: As Ansible executes tasks sequentially by default, managing large numbers of hosts can become time-consuming without using strategies like parallelization.
Understanding Terraform
Terraform is an open-source infrastructure as code tool created by HashiCorp. It allows users to define and provision infrastructure resources using a declarative configuration language called HashiCorp Configuration Language (HCL). Terraform can manage resources across various cloud providers (AWS, Azure, GCP) and services (Kubernetes, GitHub, Fastly) through a plugin architecture with providers.
Unlike Ansible, which focuses on configuration management, Terraform specializes in infrastructure provisioning—creating, modifying, and destroying infrastructure resources like virtual machines, networks, and storage.
Terraform architecture
Terraform's architecture consists of several key components:
Core: The Terraform core reads configuration files, builds the resource graph, and executes plans to reach the desired state.
Providers: Plugins that implement resource types for specific platforms or services. Examples include the AWS provider, Azure provider, and Google Cloud provider.
State files: Terraform stores the state of the managed infrastructure in a state file. This state file maps real-world resources to your configuration, keeps track of metadata, and improves performance for large infrastructures.
Resource graph: Terraform builds a dependency graph of resources based on your configuration, allowing it to determine the correct order for creating, updating, or destroying resources.
Key Terraform concepts
1. Resources and data sources
Resources are infrastructure objects that Terraform manages, such as virtual machines, DNS records, or cloud storage buckets. Data sources allow Terraform to use information defined outside of Terraform, imported from existing infrastructure or other sources.
2. Variables and outputs
Variables allow parameterizing your configurations, making them more reusable. Outputs provide a way to extract information about your infrastructure that can be used elsewhere or displayed to users.
3. Modules
Modules are containers for multiple resources that are used together. They allow you to create reusable components and promote code organization.
4. Terraform workflow
Terraform follows a core workflow with these main commands:
This workflow provides a clear process for managing infrastructure changes, with explicit steps for validation before applying changes.
Benefits of Terraform
Declarative approach: Terraform uses a declarative language where you specify the desired end state rather than the steps to get there. Terraform figures out how to achieve that state.
State management: Terraform's state file tracks all managed resources, enabling it to detect drift and understand relationships between resources, even across different providers.
If someone manually changes a resource, this command will show the differences between the actual state and the desired state.
Provider ecosystem: With hundreds of providers covering major cloud platforms, services, and systems, Terraform can manage nearly any infrastructure resource.
Plan and apply workflow: The separation between planning changes and applying them gives teams the opportunity to review and approve changes before implementation, improving safety and collaboration.
Challenges with Terraform
Learning curve for HCL: HashiCorp Configuration Language can be challenging for beginners, especially when dealing with complex expressions and functions.
State management complexity: The state file is critical to Terraform's operation but can become a point of contention in team environments. Remote state storage and locking mechanisms help address this but add complexity.
Limited configuration management capabilities: While Terraform excels at provisioning infrastructure, it has limited capabilities for configuring the operating system and applications running on that infrastructure.
How Ansible and Terraform work together
The complementary relationship
Terraform and Ansible have complementary strengths and can work together effectively in a modern infrastructure pipeline:
- Terraform excels at provisioning the underlying infrastructure: VMs, networks, load balancers, and other cloud resources
- Ansible excels at configuring that infrastructure: installing packages, configuring services, deploying applications
This division of responsibilities creates a clear separation of concerns in your IaC implementation:
- Use Terraform to create the infrastructure resources
- Use Ansible to configure those resources and deploy applications
![Diagram showing Terraform and Ansible workflow]
Integration strategies
There are several ways to integrate Terraform and Ansible:
Using Terraform outputs with Ansible
Terraform can output information about provisioned resources (like IP addresses), which Ansible can use to target those resources.
You can then generate an Ansible inventory from these outputs:
Ansible as a Terraform provisioner
Terraform can use provisioners to execute scripts or commands on resources after
they're created. You can use the local-exec provisioner to run Ansible against
newly created resources:
Separate but coordinated workflows
In more complex environments, you might maintain separate Terraform and Ansible codebases but coordinate their execution through a CI/CD pipeline:
- Terraform creates/updates infrastructure
- Terraform outputs are processed to create Ansible inventory
- Ansible runs to configure the infrastructure
- Tests verify the environment is properly set up
Practical workflow example
Let's look at a practical example of using Terraform and Ansible together:
Define infrastructure with Terraform
Create dynamic inventory for Ansible
Configure servers with Ansible
Execute the workflow
This workflow demonstrates how Terraform and Ansible can work together to provide a complete solution: Terraform handles the infrastructure provisioning, while Ansible manages the configuration and application deployment.
When to use Ansible or Terraform
Use cases for Ansible alone
Ansible is often sufficient by itself in several scenarios:
Configuration management of existing infrastructure: When you already have infrastructure in place and need to maintain consistent configurations across servers, Ansible excels at ensuring systems are in the desired state.
Application deployment: Ansible's playbooks provide a straightforward way to automate application deployments, including copying files, setting up services, and performing necessary pre and post-deployment tasks.
Ad-hoc commands and operations: Ansible's command-line interface makes it simple to run one-off commands across multiple servers, which is useful for maintenance tasks or troubleshooting.
- Legacy infrastructure management: For environments with legacy systems that may not be easily managed through cloud APIs, Ansible's agentless approach provides a way to automate management without installing additional software.
Use cases for Terraform
Terraform is the better choice in these scenarios:
Cloud infrastructure provisioning: When creating resources across cloud providers, Terraform's provider ecosystem and declarative approach make it easy to define and manage complex infrastructure.
Multi-cloud deployments: When working across multiple cloud providers, Terraform provides a consistent workflow and language for managing resources, regardless of the provider.
Infrastructure versioning: Terraform's state management and versioning capabilities allow you to track changes to your infrastructure over time and roll back if necessary.
- Resource dependency management: When you have complex dependencies between infrastructure resources, Terraform's resource graph ensures proper creation and deletion order.
Decision framework for beginners
When deciding between Ansible and Terraform (or using both), consider these factors:
Project requirements and constraints:
- Are you primarily provisioning new infrastructure or configuring existing systems?
- Do you need to manage resources across multiple cloud providers?
- How important is state tracking and drift detection?
Team expertise:
- What tools is your team already familiar with?
- Do you have more expertise in YAML/Python (Ansible) or HCL (Terraform)?
- How much time can you invest in learning new tools?
Existing infrastructure:
- Are you managing greenfield deployments or working with existing infrastructure?
- How much of your infrastructure is cloud-based vs. on-premises?
Cloud vs on-premises considerations:
- For cloud-heavy environments, Terraform's provider ecosystem offers significant advantages
- For on-premises or hybrid environments, Ansible's flexibility may be more valuable
A practical approach for many teams is:
- Start with Terraform for infrastructure provisioning (especially cloud resources)
- Use Ansible for configuration management and application deployment
- Develop integration points between the two as needed
Final thoughts
Ansible and Terraform represent different approaches to infrastructure automation that complement each other well.
Terraform's declarative model and state management make it ideal for provisioning cloud infrastructure, while Ansible's procedural approach and extensive module library excel at configuration management and application deployment.
For most organizations, the question isn't whether to use Ansible or Terraform, but how to use them together effectively.
The decision between these tools should be guided by your specific requirements, team expertise, and the nature of your infrastructure.
Thanks for reading!