Quick Decision

NeedUse
Provision cloud infrastructure (VMs, VPCs, databases)Terraform
Configure servers (install packages, manage services)Ansible
Deploy applicationsAnsible
Manage Kubernetes resourcesEither (Terraform for cluster, Ansible for apps)
Network device configurationAnsible
One-time ad-hoc tasksAnsible
Track infrastructure stateTerraform

Core Differences

Approach

Terraform: Declarative — "I want 3 EC2 instances"

resource "aws_instance" "web" {
  count         = 3
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t3.micro"
}

Ansible: Procedural (with declarative modules) — "Install nginx, then start it"

- name: Configure web server
  hosts: webservers
  tasks:
    - ansible.builtin.apt:
        name: nginx
        state: present
    - ansible.builtin.service:
        name: nginx
        state: started

State Management

Terraform: Maintains a state file tracking all resources

  • Knows what exists, what changed, what to destroy
  • Can detect drift
  • State must be stored securely (S3, Terraform Cloud)

Ansible: Stateless — no state file

  • Checks current state on each run
  • Idempotent modules ensure desired state
  • No drift detection built-in

Language

Terraform: HCL (HashiCorp Configuration Language) Ansible: YAML + Jinja2

Agent

Terraform: Agentless (API calls to cloud providers) Ansible: Agentless (SSH/WinRM to servers)

Where Each Excels

Terraform Wins

  • Cloud resource provisioning (AWS, Azure, GCP)
  • Infrastructure lifecycle (create, update, destroy)
  • Dependency graphing (parallel resource creation)
  • State tracking (knows what it manages)
  • Plan before apply (terraform plan)

Ansible Wins

  • Server configuration (packages, files, services)
  • Application deployment (zero-downtime rolling updates)
  • Network devices (Cisco, Juniper, Arista)
  • Ad-hoc commands (quick one-liners)
  • Orchestration (multi-tier deployment workflows)
  • No state to manage (simpler operations)
  • Agentless SSH (nothing to install on targets)

Using Them Together (Best Practice)

┌─────────────┐     ┌──────────────┐     ┌─────────────┐
│  Terraform   │────▶│   Ansible    │────▶│    App      │
│  Provision   │     │  Configure   │     │   Deploy    │
│              │     │              │     │             │
│ • VPC/Subnet │     │ • Install    │     │ • Deploy    │
│ • EC2/VMs    │     │   packages   │     │   code      │
│ • RDS/DB     │     │ • Configure  │     │ • Restart   │
│ • S3 Buckets │     │   services   │     │   services  │
│ • IAM Roles  │     │ • Security   │     │ • Health    │
│              │     │   hardening  │     │   checks    │
└─────────────┘     └──────────────┘     └─────────────┘

Example: Terraform creates, Ansible configures

# Terraform — create the server
resource "aws_instance" "web" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t3.micro"
  key_name      = "deploy-key"

  provisioner "local-exec" {
    command = "echo '${self.public_ip}' >> ../ansible/inventory/hosts"
  }
}
# Ansible — configure the server
- hosts: webservers
  become: true
  roles:
    - common
    - nginx
    - app-deploy

Decision Flowchart

Need to create cloud resources?
├── Yes → Terraform
│   └── Also need to configure them?
│       └── Yes → Terraform + Ansible
└── No
    └── Need to configure existing servers?
        ├── Yes → Ansible
        └── Need to deploy applications?
            └── Yes → Ansible

Common Mistakes

Using Terraform for Configuration

# DON'T — Terraform is bad at ongoing config management
resource "aws_instance" "web" {
  user_data = <<-EOF
    #!/bin/bash
    apt-get update
    apt-get install -y nginx
    # This only runs once at creation!
  EOF
}

Using Ansible for Infrastructure

# WORKS but Terraform is better for this
- amazon.aws.ec2_instance:
    name: web-server
    instance_type: t3.micro
    image_id: ami-0c55b159cbfafe1f0
    # No state tracking — can't easily destroy/update

Conclusion

Terraform for provisioning infrastructure. Ansible for configuring it. Use both together for the most robust automation pipeline. Don't force one tool to do the other's job.

For a production-focused walkthrough, see Luca Berton's guide on combining Terraform and Ansible.