Terraform vs Ansible

Terraform and Ansible are often compared as if they were alternatives, but they were designed for different jobs. Terraform provisions infrastructure: it creates and changes cloud resources — networks, databases, load balancers, virtual machines — through provider APIs and records them in state. Ansible configures systems: it connects to machines over SSH or WinRM and runs ordered tasks — install packages, write files, restart services — and it is equally good at orchestrating one-off operational procedures.

Short verdict: use Terraform (or OpenTofu) to create and manage cloud resources, and Ansible to configure what runs inside servers or to automate operational procedures. Where workloads run in containers or managed services, much of Ansible's traditional role disappears into images and platform configuration — but for VMs, network devices, and runbooks, the two complement each other well.

TL;DR

Quick Example

Terraform creates a VM and exports its address; Ansible installs and configures NGINX on it.

Run both again and nothing changes: Terraform's plan is empty, and Ansible reports every task as ok rather than changed.

Core Concepts

Head-to-Head

Why State Matters

Terraform's state means it knows exactly which resources it created, so deleting a resource from the configuration deletes it in the cloud. Ansible has no memory between runs: it converges systems towards what the playbook describes, but it will not clean up a package or file that an old version of the playbook installed. That is fine for configuration, and dangerous for infrastructure lifecycles.

Idempotency in Practice

Most Ansible modules check current state and change only what is needed, so a well-written playbook is safe to run repeatedly. Raw shell and command tasks are not idempotent by default; guard them with creates, removes, or changed_when. Terraform resources are idempotent through the plan, but provisioners and local-exec hooks are escape hatches with the same caveats.

Using Both Together

Image baking is usually the most robust: configuration happens once at build time, instances start identical, and changes ship as new images rather than edits to running servers.

The Decision Framework

Best Practices

Give Each Tool One Job

Terraform owns resources; Ansible owns configuration inside them. When both try to manage the same thing — a security group, a DNS record — they overwrite each other.

Prefer Immutable Infrastructure

Configuring servers in place leads to drift over months of manual fixes. Build images or containers, and replace instances instead of patching them where your platform allows.

Generate Inventory From the Source of Truth

Use Terraform outputs or Ansible's dynamic inventory plugins for your cloud, rather than hand-maintained host lists that drift from reality.

Test Both

Run terraform plan checks and policy tests in CI, and test Ansible roles with Molecule against disposable instances or containers.

Common Mistakes

Provisioning Cloud Resources With Ansible

Configuring Servers With Terraform Provisioners

Non-Idempotent Shell Tasks

FAQ

Should I use Terraform or Ansible?

Usually both, for different jobs: Terraform to create and manage cloud infrastructure, Ansible to configure servers and automate operational tasks. If everything runs in containers on managed platforms, you may need little Ansible at all.

Can Ansible replace Terraform?

Ansible has cloud modules and can create resources, but without a state file it does not track what it created or remove resources you delete from the playbook. For infrastructure lifecycle management, Terraform or OpenTofu is the better fit.

Can Terraform configure servers?

Only in limited ways, through provisioners or cloud-init user data. HashiCorp itself recommends provisioners as a last resort. Use images, cloud-init for small bootstrap steps, or a configuration management tool for anything substantial.

Is Ansible agentless?

Yes. It connects over SSH or WinRM and runs modules on the target, typically requiring only Python on Linux hosts. There is no daemon to install or upgrade.

What does idempotent mean here?

Running the same code again produces no further changes when the system already matches it. Terraform achieves this by planning against state; Ansible by modules that check before changing.

Related Topics

References