You set up a server in the AWS Console. You click through security groups, configure load balancers, set up RDS. Everything works. Two months later, you need an identical staging environment. Can you reproduce it exactly?
Probably not. Because your infrastructure exists only as a series of clicks you've long forgotten. No documentation, no version history, no way to roll back. This is the core problem Infrastructure as Code (IaC) solves.
I've seen this pattern dozens of times with clients: a critical server goes down, and the person who set it up left the company six months ago. Nobody knows exactly how it was configured. Recovery takes days instead of minutes.
Terraform: your infrastructure blueprint
Instead of clicking through the AWS Console, you describe your infrastructure in code:
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t3.micro"
vpc_security_group_ids = [aws_security_group.web.id]
subnet_id = aws_subnet.public.id
tags = {
Name = "production-web"
Environment = "production"
ManagedBy = "terraform"
}
}
resource "aws_security_group" "web" {
name = "web-server-sg"
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
Run terraform plan to see what will change. Run terraform apply and it creates everything. Need to change instance type? Edit the file, apply again. Terraform figures out what changed and updates only what's necessary.
The beauty of this approach: your .tf files become the single source of truth. New team member joins? They read the Terraform code and understand the entire infrastructure in an hour.
Ansible: configuration management
Terraform creates infrastructure — servers, databases, networks. But who installs Docker on that server? Who configures Nginx? Who deploys the application? That's where Ansible comes in.
- name: Configure web server
hosts: web_servers
become: yes
tasks:
- name: Install Docker
apt:
name: docker.io
state: present
- name: Install Nginx
apt:
name: nginx
state: present
- name: Copy Nginx config
template:
src: nginx.conf.j2
dest: /etc/nginx/sites-available/default
notify: restart nginx
- name: Deploy application
docker_container:
name: myapp
image: "ghcr.io/myorg/myapp:latest"
ports:
- "8080:3000"
restart_policy: always
handlers:
- name: restart nginx
service:
name: nginx
state: restarted
Ansible connects via SSH — no agents to install, no daemons to manage. You write what you want the server to look like, and Ansible makes it happen. Run it once or a hundred times — the result is the same (idempotency).
The power combo: Terraform + Ansible + Git
Here's how these tools work together in a real production workflow:
- Terraform provisions cloud resources — EC2 instances, RDS databases, VPCs, S3 buckets, load balancers, DNS records
- Ansible configures those resources — installs software, deploys applications, manages configs, sets up monitoring
-
Git versions everything — every change is tracked, reviewed via pull requests, and reversible with
git revert
This means you can spin up an identical environment in minutes. Disaster recovery goes from "days of panic" to "run two commands."
A real-world example
One of my clients had a setup where everything was configured manually in AWS Console over two years. When their primary server had a disk failure:
- Before IaC: 3 days of downtime, 2 engineers working around the clock, several misconfigurations discovered only after launch, $15,000+ in lost revenue
- After IaC migration: We recreated the entire infrastructure in 47 minutes from Terraform + Ansible code. Zero misconfigurations. The app was back online before most users noticed.
The migration to IaC took 3 weeks. It paid for itself on the first incident.
Real benefits I've seen with clients
- Reproducibility — "works on my environment" is no longer a problem. Staging = Production, always.
- Speed — new environments go from days to minutes.
- Documentation — your Terraform files ARE your documentation. No more outdated Confluence pages.
- Disaster recovery — server died? Terraform recreates it, Ansible reconfigures it. Under an hour.
- Cost control — see exactly what resources you're paying for in a single file.
- Audit trail — every infrastructure change goes through a pull request.
How to start (without breaking everything)
Step 1: Pick one resource. Start with something non-critical — maybe a dev server or an S3 bucket. Define it in Terraform.
Step 2: Use terraform import to bring existing resources under Terraform management without recreating them.
Step 3: Write an Ansible playbook for something you do regularly — like deploying a new version of your app.
Step 4: Put everything in Git. Set up a CI/CD pipeline that runs terraform plan on pull requests.
Step 5: Expand gradually. Each week, bring one more manually managed resource under IaC control.
If your infrastructure is still managed by clicking through cloud consoles, you're one bad day away from a disaster you can't recover from. The good news? You can start fixing this today.
Full article: alexxdevops.com
Book a free consultation: calendly.com/oleksii-bohuslavets/30min
Top comments (0)