// Stay in touch?
Products
Encore CloudEncore Cloud
Encore.tsEncore.ts
Encore.goEncore.go
PricingPricing
Book a DemoBook a Demo
Use Cases
AI-Powered DevelopmentAI-Powered Development
Event-Driven SystemsEvent-Driven Systems
Distributed SystemsDistributed Systems
Case StudiesCase Studies
ShowcaseShowcase
Resources
DocsDocs
InstallInstall
Example AppsExample Apps
Demo videoDemo video
ArticlesArticles
GitHub ReleasesGitHub Releases
Systems Operational
Company
About UsAbout Us
Swag ShopSwag Shop
ContactContact
JobsJobs
PressPress
TermsTerms
Privacy PolicyPrivacy Policy
Data Processing AgreementData Processing Agreement
Enterprise SLAEnterprise SLA
Encore
© 2026 EncoreAll rights reserved
© 2026 Encore All Rights Reserved
GitHubDiscordYouTube

Terraform vs Ansible: What Each One Is For

One provisions cloud resources, the other configures machines. Most teams end up running both.

07/08/26
9 Min Read
Ivan Cernja
07/08/26

Terraform vs Ansible: What Each One Is For

One provisions cloud resources, the other configures machines. Most teams end up running both.

Ivan Cernja
9 Min Read

Terraform and Ansible get compared constantly, and the comparison is a little misleading because they mostly do different jobs. Terraform stands up infrastructure: it talks to AWS, GCP, Azure, and hundreds of other APIs to create servers, networks, databases, DNS records, and load balancers, then remembers what it created. Ansible configures machines that already exist: it connects over SSH, installs packages, writes config files, and restarts services.

You can force either tool to do the other's job, and people do, but the results are awkward. The more useful framing is to understand what each is built for, see them side by side, and then decide whether you need one, the other, or both. For a lot of teams the answer is both.

Terraform vs Ansible: The Core Differences

TerraformAnsible
Primary jobProvision infrastructureConfigure existing machines
ModelDeclarative (describe end state)Procedural (ordered tasks)
StateKeeps a state fileStateless, checks live at run time
LanguageHCLYAML (playbooks)
How it connectsCloud provider APIsSSH (agentless), WinRM on Windows
Typical outputNew VMs, VPCs, databases, DNSInstalled software, edited files, running services
IdempotencyBuilt into the resource graphPer-module, up to each task
Owned byHashiCorp (now IBM)Red Hat (IBM)

Two words carry most of the difference: provisioning and configuration.

Provisioning is creating the resource in the first place. There was no database, now there is a db.t3.medium running Postgres in us-east-1. Terraform is a provisioning tool.

Configuration management is taking a machine that exists and getting it into the right shape: the right nginx version, the right kernel settings, the right systemd units enabled. Ansible is a configuration management tool.

The other big difference is state. Terraform writes a state file that maps your configuration to the real resources it created. That is how terraform plan can tell you "this change will destroy one instance and create two" before you apply it, and how terraform destroy knows exactly what to tear down. Ansible has no state file. It connects to a machine, checks the current condition of each thing it manages, and makes only the changes needed. Both approaches are idempotent in practice, but they get there differently: Terraform reconciles against recorded state, Ansible re-checks reality every run.

The Same Task in Each Tool

Say you want a web server. In Terraform, you describe the resource you want to exist and let it reconcile.

# main.tf: provision the machine resource "aws_instance" "web" { ami = "ami-0c55b159cbfafe1f0" instance_type = "t3.small" tags = { Name = "web-1" } } resource "aws_security_group" "web" { name = "web-sg" ingress { from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } }

Run terraform plan and it shows you what will change. Run terraform apply and the EC2 instance and security group get created, and both are recorded in state. Change instance_type to t3.medium later, apply again, and Terraform works out that it needs to modify (or replace) the existing instance rather than making a second one. That reconciliation is the whole point of the state file.

Terraform stops at "the server exists." It does not know or care whether nginx is installed on it.

That is where Ansible picks up. An Ansible playbook is a list of tasks that run in order against a target host.

# webserver.yml: configure the machine - hosts: web become: true tasks: - name: Install nginx apt: name: nginx state: present update_cache: true - name: Write the site config copy: src: files/site.conf dest: /etc/nginx/sites-available/default - name: Enable and start nginx service: name: nginx state: started enabled: true

Run this with ansible-playbook webserver.yml and it SSHes into every host in the web group and runs the three tasks top to bottom. Each task is idempotent: if nginx is already installed, the apt task reports ok instead of changed and moves on. But you wrote the steps as an ordered sequence, and order matters (you install before you configure before you start). That sequencing is what makes Ansible procedural even though individual modules are safe to re-run.

Notice what neither tool did. Terraform never touched the OS. Ansible never created a server; it assumed web hosts already exist and are reachable over SSH.

Using Terraform and Ansible Together

Because they cover different stages, the common production pattern is a handoff. Terraform provisions, Ansible configures.

# Terraform provisions and writes an Ansible inventory resource "aws_instance" "web" { count = 3 ami = "ami-0c55b159cbfafe1f0" instance_type = "t3.small" tags = { Name = "web-${count.index}" } } resource "local_file" "inventory" { content = templatefile("inventory.tmpl", { ips = aws_instance.web[*].public_ip }) filename = "inventory.ini" }

Terraform creates three instances and writes their IPs into an inventory file. Then Ansible reads that inventory and configures all three:

terraform apply ansible-playbook -i inventory.ini webserver.yml

There are tighter integrations (Ansible's amazon.aws dynamic inventory can query AWS directly, and tools like Terragrunt or CI pipelines chain the two steps), but the shape is always the same. Terraform owns "what exists," Ansible owns "how it is set up." Neither tool tries to do the other's job well, so you keep the boundary clean.

This is why the "vs" framing undersells it. For a fleet of long-lived VMs, you very often want both.

When to Choose Ansible

Ansible gets unfairly dismissed by people who live in a fully managed-cloud world. It earns its keep in real situations:

  • Configuring servers you did not provision with Terraform. Bare-metal, on-prem, a VM someone spun up by hand, a Raspberry Pi fleet. Ansible needs only SSH.
  • Ongoing OS-level management. Patching, user and SSH key management, kernel tuning, log rotation, certificate rollout. This is not a one-time provisioning event, it is continuous, and Ansible re-checks state every run.
  • Application deployment and orchestration. Rolling restarts across a cluster, pulling a new release onto each node in sequence, running database migrations in a controlled order. Ansible's serial keyword and ordered tasks fit this well.
  • Agentless environments. No daemon to install on managed hosts. If a box has SSH and Python, Ansible can manage it, which matters in locked-down or legacy environments.
  • Ad hoc operations. ansible web -a "systemctl restart nginx" across a hundred hosts, right now, without writing a playbook.

Terraform does none of these well. Its provisioners exist but the docs themselves call them a last resort, and it has no model for ongoing OS drift.

When to Choose Terraform

Equally, Ansible is a poor fit for provisioning cloud resources at scale, and Terraform is built for exactly that:

  • Standing up cloud infrastructure. VPCs, subnets, security groups, managed databases, load balancers, DNS, IAM. Terraform's provider ecosystem covers these across every major cloud with a consistent model.
  • Knowing what exists and what will change. terraform plan gives you a reviewable diff before anything happens. The state file makes teardown exact.
  • Managing the full dependency graph. Terraform figures out that the security group must exist before the instance, and parallelizes what it can. You describe the end state, not the order.
  • Multi-cloud and multi-service breadth. One tool and one language across AWS, GCP, Azure, Cloudflare, Datadog, and hundreds more providers.

Ansible can call cloud modules to create resources, but it has no state file, so it cannot cleanly tell you "these three things will be destroyed" or reliably tear down exactly what it made. Provisioning is not what it is for.

How to Choose Between Them

Reach for Terraform when the task is creating and destroying cloud infrastructure, you want a plan/apply review step, and you need an exact record of what exists so you can change or tear it down safely.

Reach for Ansible when the machines already exist and you need to configure them, deploy applications, patch and manage them over time, or run one-off commands across a fleet, especially over SSH to hosts you did not provision through an API.

Reach for both when you run long-lived VMs in the cloud. Terraform builds them, Ansible sets them up and keeps them in shape. This is the mainstream pattern and it works because the boundary is clean.

There is a category where neither is the obvious answer: a modern application backend where most of the "infrastructure" is application-level (a Postgres database, a Pub/Sub topic, a cron job, an object storage bucket) and there is no long-lived VM to configure at all. If you are on managed cloud services and containers, you may have very little for Ansible to do, and your Terraform is mostly wiring managed resources to application code that lives in a different repo and knows nothing about them.

That gap is what Encore, the open-source backend framework, addresses: you declare those resources directly in your TypeScript or Go code and Encore Cloud provisions the real services in your own AWS or GCP account, no separate HCL and no separate state file to keep in sync. It does not replace Ansible's server configuration job or Terraform's role in large VM and networking estates, and teams that need custom VPC topologies or resources outside its primitives still reach for Terraform or Pulumi. It is worth a look only if your backend is application-shaped rather than fleet-shaped.

import { SQLDatabase } from "encore.dev/storage/sqldb"; import { CronJob } from "encore.dev/cron"; // The database and the schedule are declared in the app code that uses them. const db = new SQLDatabase("orders", { migrations: "./migrations" }); new CronJob("reconcile", { every: "1h", endpoint: reconcile });

Because the infrastructure lives in the application code, an AI agent reading the repo sees the database, the cron job, and the endpoints in one place. There is no separate HCL repo it has to cross-reference and keep in sync. Encore also ships an MCP server and encore llm-rules init, which give agents the schema, traces, and architecture as context, so agent output follows the same conventions and stays deployable.

Deploy with Encore

Declare Postgres and a cron job in TypeScript and deploy to your own AWS or GCP account, with no separate state file to manage.

Deploy

Summary

Terraform provisions infrastructure and tracks it in state. Ansible configures machines that already exist and re-checks them every run. They sit at different stages of the same lifecycle, which is why so many teams run both. Pick based on the task in front of you. If you are creating cloud resources, that is Terraform. If you are setting up or maintaining machines that already exist, that is Ansible. If you run a fleet of long-lived VMs, you will usually want both working in sequence.

Related Resources

  • What infrastructure as code means
  • Terraform alternatives
  • Terraform in 2026
  • Cloud infrastructure automation tools
  • Encore quick start

Frequently asked questions

What is the main difference between Terraform and Ansible?

Terraform provisions infrastructure (it creates and destroys cloud resources like servers, databases, and networks) and tracks what exists in a state file. Ansible configures and manages machines that already exist (installing packages, editing files, restarting services). One builds the infrastructure, the other sets it up.

Can you use Terraform and Ansible together?

Yes, and many teams do. A common pattern is Terraform provisions the VMs and networking, then hands the server IPs to Ansible, which installs software and applies configuration. They cover different stages of the same lifecycle.

Is Ansible declarative or procedural?

Ansible is mostly procedural: a playbook is an ordered list of tasks that run top to bottom. Individual modules are idempotent (running them twice is safe), but you still write the steps in sequence. Terraform is declarative: you describe the end state and it works out the changes.

Does Ansible have state like Terraform?

No. Ansible does not keep a state file. It checks the current condition of each machine at run time and applies whatever changes are needed. Terraform keeps a state file that maps your config to real resources, which is how it knows what to update or delete.

Should I learn Terraform or Ansible first?

If your job is standing up cloud infrastructure (VMs, VPCs, managed databases), start with Terraform. If your job is configuring existing servers (app deployment, package management, OS setup), start with Ansible. Many infrastructure roles use both.

Can Terraform configure a server the way Ansible does?

Not well. Terraform can run a provisioner or a startup script, but that is discouraged for anything beyond bootstrapping. It has no concept of ongoing configuration drift on the OS. That is Ansible's job.

Contents
Terraform vs Ansible: The Core Differences
The Same Task in Each Tool
Using Terraform and Ansible Together
When to Choose Ansible
When to Choose Terraform
How to Choose Between Them
Summary
Related Resources
Encore

The backend platform for humans and agents

Build backends in Go or TypeScript and run them on your own AWS or GCP, with the guardrails your team and AI agents need to ship safely.

Ready to build your next backend?

Encore is the Open Source framework for building robust type-safe distributed systems with declarative infrastructure.