Terraform vs. Ansible: What Each One Actually Does

When I started learning infrastructure as code, I kept mixing up Terraform and Ansible. They’re both written as code, and they both deal with servers. Building my own lab is what finally made the difference click.

The short version

Terraform builds the house. Ansible furnishes it.

TerraformAnsible
Main jobCreates infrastructure (provisioning)Sets up what’s inside it (configuration)
In my labNetwork, firewall, public IPs, 2 VMsMySQL, Apache, PHP, WordPress
How you write itHCL: you describe the end resultYAML: a list of tasks
How it knows what existsA state fileChecks each server every run

Terraform: building the infrastructure

Here’s a small piece of my Terraform. It describes the firewall rule that only allows SSH from my home IP address:

security_rule {
  name                   = "allow-ssh-from-admin"
  priority               = 100
  direction              = "Inbound"
  access                 = "Allow"
  protocol               = "Tcp"
  destination_port_range = "22"
  source_address_prefix  = var.admin_cidr
}

The workflow is always the same: terraform init, then terraform plan to preview the changes, then terraform apply to make them. The plan step is the safety check, because it shows exactly what will change before anything happens.

Ansible: configuring the servers

Once the servers exist, Ansible connects to them over SSH and sets them up. Here’s the task that installs Apache and PHP on my web server:

- name: Install Apache and PHP
  ansible.builtin.apt:
    name:
      - apache2
      - php
      - php-mysql
      - libapache2-mod-php
    state: present

Ansible is agentless, so nothing has to be installed on the servers first. It just needs SSH access.

How they hand off to each other

This is my favorite part. When Terraform finishes, it writes Ansible’s inventory file, the list of servers and their IP addresses. So Ansible always knows the real addresses, and I never have to copy them by hand.

[web]
web ansible_host=<web server IP>

[db]
db ansible_host=<database server IP>

What I learned

If I rebuilt my original LAMP project today, Terraform would create the server, and Ansible would install Apache, MySQL, and PHP and create each client’s user and permissions. What took me hours by hand would be two commands.