⚙️ Configuration as Code

Puppet · Ansible · Terraform
— What's the difference and when to use what? —

FinistDevs · 2026

Arnaud Prémel-Cabic

Tech Lead @ OVHCloud

arnaud.premel-cabic@ovhcloud.com

"It works on my server."

Or: why doesn't it work here, when it works everywhere else?

You have a server. It works.

Great.

You have 10 servers.

Still manageable… but every small change means 10 SSH sessions, 10 vim edits, 10 chances to make a mistake.

Now you have 100 servers.

Some 2 years old. Some a couple of months. Some freshly provisioned.
None of them are exactly alike.

Each one is unique. Unreproducible. Undocumented.

Welcome to Snowflake Hell.

This is fine

Configuration drift is silent… until it isn't.

Prod breaks on a Tuesday. You can't reproduce the bug locally. You can't scale reliably. You can't onboard a new server without fear.

What if your infrastructure was just… code?

Yes, even your AI assistant can write it. But you still need to understand what it deploys.

Configuration as Code

Managing infrastructure through machine-readable files, stored in version control.

Reproducible  ·  Versionable  ·  Auditable

Meet the three musketeers of infrastructure.

Puppet  ·  Ansible  ·  Terraform — each fights a different battle.

🏗️ Terraform

Start here. Before you configure a server, you need to have one.

HCL: HashiCorp Configuration Language.

Declarative, human-readable — and pure JSON works too.
terraform plan previews  ·  terraform apply creates  ·  terraform destroy removes.

Terraform remembers what it built.

The .tfstate file maps code to real-world resources. Store it remotely.
Depending on what you manage, it can contain plaintext sensitive values — credentials, tokens, secrets.
Handle it with care. Don't feed it to your LLM.

One tool. Every API.

1000+ providers: AWS, GCP, Azure, Cloudflare, GitHub, Kubernetes…
Not just cloud — manage GitHub teams, Datadog monitors, PagerDuty schedules, DNS records.
If it has an API, there's a Terraform provider for it.

# main.tf


terraform {
  required_providers {
    aws = { source = "hashicorp/aws", version = "~> 5.0" }
  }
}

provider "aws" { region = "eu-west-3" }

resource "aws_instance" "web" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t3.micro"
  tags = { Name = "finistdevs-web" }
}

output "public_ip" {
  value = aws_instance.web.public_ip
}
    

In 2023, HashiCorp changed Terraform's license.

BSL instead of MPL — no longer truly open-source.
The community responded: OpenTofu, by the OpenTF Foundation, is the open-source fork.
Drop-in replacement. Fully compatible. Community-driven.

Terraform at scale needs a platform.

Terraform Enterprise / HCP Terraform — HashiCorp's commercial offering: remote state, RBAC, audit logs
Spacelift — GitOps-first CI/CD for Terraform (and OpenTofu)
Atlantis — open-source: plan & apply triggered by pull requests
env0, Scalr — SaaS alternatives with policy & cost management

Ansible

Your servers are provisioned. Now make them do something.

Push, not pull. SSH, not agents.

YAML playbooks run tasks in order, across any number of hosts.
No daemon. No certificate authority. Just Python + SSH.
Idempotent modules ensure the same playbook can run safely again and again.

# playbook/webserver.yml


- name: Configure web server
  hosts: webservers
  become: true

  tasks:
    - name: Install nginx
      ansible.builtin.package:
        name: nginx
        state: present

    - name: Deploy nginx config
      ansible.builtin.template:
        src: nginx.conf.j2
        dest: /etc/nginx/nginx.conf
      notify: Restart nginx

  handlers:
    - name: Restart nginx
      ansible.builtin.service:
        name: nginx
        state: restarted
    

The community does the heavy lifting.

Ansible Galaxy — 10,000+ ready-made roles and collections.
Don't write a playbook to install Docker from scratch. Someone already did.
Just ansible-galaxy install geerlingguy.docker.

Ansible at scale: open-source vs enterprise.

AWX — open-source web UI, API, and scheduler for Ansible
Ansible Automation Platform (Red Hat) — enterprise version of AWX, with support & integrations
Semaphore — lightweight open-source alternative to AWX
The core Ansible engine remains Apache 2.0 — truly open-source.