Ansible vs Terraform: Complete Comparison Guide (2026)
Ansible and Terraform are the two most popular infrastructure-as-code tools in the DevOps ecosystem, but they were built to solve different problems. Terraform provisions cloud resources from a declarative state file; Ansible configures, deploys, and orchestrates software on existing systems. This guide breaks down the differences, shows when to pick each one, and explains how to use them together in a real production pipeline.
TL;DR — Ansible vs Terraform at a glance
- Use Terraform to create cloud resources (VMs, VPCs, load balancers, managed databases, Kubernetes clusters) and track them in state.
- Use Ansible to configure what runs on those resources — packages, users, services, application code, certificates, compliance baselines.
- Use both when you need full lifecycle automation: Terraform builds the platform, Ansible delivers the workload.
Side-by-side feature comparison
| Feature | Ansible | Terraform |
|---|---|---|
| Primary purpose | Configuration management, app deployment, orchestration | Infrastructure provisioning |
| Paradigm | Procedural with declarative modules (idempotent) | Declarative with execution plan |
| Language | YAML (playbooks), Jinja2 (templates) | HCL (HashiCorp Configuration Language) |
| State management | Stateless — re-reads target system each run | State file (local or remote backend like S3, GCS, Terraform Cloud) |
| Agentless | Yes — SSH or WinRM | Yes — provider APIs over HTTPS |
| Idempotency | Per-module (most modules are idempotent) | Built into the plan/apply lifecycle |
| Mutability model | Mutable — converges existing systems | Immutable — replaces resources on most changes |
| Cloud support | AWS, Azure, GCP, OpenStack, VMware via collections | 3,000+ providers in the Terraform Registry |
| Drift detection | Manual (run playbook with --check) | Built-in (terraform plan) |
| Rollback | Re-run a previous playbook revision | Apply a previous state version (with caveats) |
| Learning curve | Gentle — readable YAML, no state to manage | Moderate — HCL, providers, state, modules |
| Best for | Sysadmins, SREs, application teams | Platform engineers, cloud architects |
| License | GPLv3 (open source) | BUSL 1.1 since 2023 (OpenTofu fork is MPL 2.0) |
| Vendor | Red Hat / IBM | HashiCorp / IBM |
Architecture: how each tool actually works
Ansible
You write a playbook — a YAML file that lists tasks to run against aninventory of hosts. The control node opens an SSH (or WinRM) connection, ships small Python scripts called modules to the target, executes them, and collects the result. Modules are idempotent: state: presenton a package installs it only if it isn't already there. There is no state file— every run re-evaluates the target system, which makes Ansible great for ongoing configuration drift correction but less great for tracking large fleets of cloud resources.
Terraform
You write HCL resource definitions, run terraform plan to preview the diff between your code and a stored state file, thenterraform applyto make the cloud match. The state file is the source of truth for what Terraform owns; without it, Terraform doesn't know which resources to update or destroy. State is normally stored in a remote backend (S3, GCS, Terraform Cloud, Consul) with locking to prevent concurrent applies.
Code example: provision and configure an EC2 web server
The textbook example of using both tools together — Terraform creates the VM, Ansible installs nginx.
Terraform: create the EC2 instance
# main.tf
terraform {
required_providers {
aws = { source = "hashicorp/aws", version = "~> 5.0" }
}
backend "s3" {
bucket = "my-terraform-state"
key = "web/terraform.tfstate"
region = "us-east-1"
}
}
provider "aws" {
region = "us-east-1"
}
resource "aws_instance" "web" {
ami = "ami-0c7217cdde317cfec" # Ubuntu 22.04
instance_type = "t3.micro"
key_name = "my-keypair"
tags = { Name = "web-server", Role = "web" }
}
output "public_ip" {
value = aws_instance.web.public_ip
}Ansible: configure nginx on the new instance
# playbook.yml
- name: Configure web server
hosts: web
become: true
tasks:
- name: Install nginx
ansible.builtin.apt:
name: nginx
state: present
update_cache: true
- name: Deploy index page
ansible.builtin.copy:
content: "<h1>Hello from Ansible + Terraform</h1>"
dest: /var/www/html/index.html
- name: Ensure nginx is running and enabled
ansible.builtin.service:
name: nginx
state: started
enabled: trueGlue them together
# 1. Create the box
terraform apply -auto-approve
# 2. Capture the IP into an inventory
echo "[web]" > inventory.ini
echo "$(terraform output -raw public_ip) ansible_user=ubuntu" >> inventory.ini
# 3. Configure it
ansible-playbook -i inventory.ini playbook.ymlWhen to choose Ansible
- You manage a fleet of existing Linux/Windows servers and need ongoing config enforcement.
- You are deploying applications, rotating certificates, patching kernels, or rolling out OS updates.
- You need agentless orchestration across mixed environments (bare metal, VMs, network gear, cloud).
- Your team prefers YAML over a custom DSL and wants a low barrier to entry.
- You need ad-hoc command execution (
ansible all -m shell -a uptime) — Terraform has no equivalent. - You want compliance scans, with collections like
community.general.openscapor CIS-hardening roles.
When to choose Terraform
- You are creating cloud infrastructure from scratch and want a single source of truth.
- You need a clear, reviewable execution plan before any change is applied.
- You manage hundreds of cloud resources and need automatic drift detection.
- You want a rich provider ecosystem covering AWS, Azure, GCP, Kubernetes, Datadog, GitHub, Cloudflare, and 3,000+ others.
- You are building reusable infrastructure modules across teams (Terraform module registry).
- Your environment is immutable — VMs are replaced, not patched in place.
Using Ansible and Terraform together
The mature pattern is provision with Terraform, configure with Ansible. Terraform stands up the VPC, security groups, IAM, EC2 instances, RDS, EKS — anything that is a cloud-API call. Ansible then connects to those instances and handles everything inside the OS: packages, files, users, services, application artifacts, secrets distribution.
Pattern 1 — Terraform writes the inventory, you run Ansible
Use a local_file Terraform resource (or the ansible_* data sources from the community provider) to write an Ansible inventory file from Terraform outputs. Run ansible-playbook as a separate pipeline step.
Pattern 2 — Terraform local-exec triggers Ansible
Add a null_resource with a local-exec provisioner that callsansible-playbook after the instance is healthy. Simple but couples the two tools — most teams prefer Pattern 1.
Pattern 3 — Ansible calls Terraform via the cloud.terraform collection
Red Hat ships cloud.terraform.terraform, a module that lets Ansible runterraform apply as a play. Useful when Ansible Automation Platform is your primary orchestrator and Terraform is a sub-step inside a larger workflow.
Performance and scale
- Ansible parallelism is controlled by the
forkssetting (default 5, production 50–500). For 1,000+ hosts, usestrategy: free,mitogen, or push to Ansible Automation Platform's execution nodes. - Terraform parallelism defaults to 10 concurrent operations per apply. For huge state files, split the codebase into multiple states (per-environment or per-component) and use
terraform_remote_statedata sources to share outputs.
Security model
- Ansible uses your SSH keys / WinRM credentials. Secrets live in
ansible-vaultencrypted files or are pulled from HashiCorp Vault, AWS Secrets Manager, or CyberArk via lookup plugins. - Terraform uses cloud provider credentials (IAM roles, service principals). Sensitive outputs can be marked
sensitive = true. State files contain plaintext secrets unless you use a backend with encryption-at-rest and tight IAM (S3 + KMS + bucket policy).
Pricing and licensing
Both tools have free open-source cores. Red Hat sells Ansible Automation Platform (AAP) for enterprise features (RBAC, audit, execution environments, Lightspeed AI). HashiCorp sells Terraform Cloud / Terraform Enterprisefor remote state, policy-as-code (Sentinel/OPA), and team workflows. In August 2023 HashiCorp moved Terraform from MPL 2.0 to the Business Source License (BUSL); the Linux Foundation then forked it as OpenTofu, which remains MPL 2.0.
Frequently asked questions
Is Ansible better than Terraform?
Neither is strictly "better" — they solve different problems. Terraform is purpose-built for provisioning cloud infrastructure with a declarative state file, while Ansible excels at configuration management, application deployment, and orchestration. Most mature teams use both.
Can Ansible replace Terraform?
Ansible can provision cloud resources through modules likeamazon.aws.ec2_instance or azure.azcollection, but it has no built-in state file, so detecting drift, planning changes, and safely destroying resources is harder than with Terraform. Ansible can replace Terraform for small or simple environments, but Terraform is the safer choice for large, long-lived infrastructure.
Is Terraform agentless like Ansible?
Yes — both are agentless. Terraform talks directly to cloud provider APIs over HTTPS; Ansible connects over SSH or WinRM. Neither requires a long-running daemon on the targets.
Should I learn Ansible or Terraform first?
Learn Ansible first if your day job is server administration, application deployment, or compliance enforcement. Learn Terraform first if you are building cloud infrastructure from scratch on AWS, Azure, GCP, or Kubernetes. In a DevOps/SRE career, you will need both within the first year.
Do Ansible and Terraform work together?
Yes. The standard pattern is to provision infrastructure with Terraform, write the resulting host inventory to a file, and then run an Ansible playbook against those hosts to install packages, configure services, and deploy applications.
Related guides
- Ansible Terraform integration: orchestrate infrastructure and configuration together
- Are Ansible and Terraform the same?
- Can Ansible replace Terraform?
- Using Jenkins to build infrastructure with Terraform and configure with Ansible
- Ansible vs Puppet
- Ansible vs Chef
- Ansible vs SaltStack
- Ansible vs Kubernetes