Infrastructure as Code: Terraform vs Pulumi
Clicking buttons in the AWS Console is technical debt. How to manage your Headless infrastructure using code, state files, and Git.
You set up your AWS S3 bucket manually. You enabled CORS manually. 6 months later, you need to launch a staging environment. Can you remember exactly which boxes you ticked? No. Infrastructure as Code (IaC) solves this. We define our servers, databases, and DNS records in text files. We commit them to Git. We apply them deterministically.
The Declarative Model (Terraform)
Terraform is the industry standard. It uses HCL (HashiCorp Configuration Language). You describe the End State. Terraform figures out how to get there.
# main.tf
provider "aws" {
region = "us-east-1"
}
resource "aws_s3_bucket" "assets" {
bucket = "maison-code-assets-prod"
acl = "public-read"
cors_rule {
allowed_headers = ["*"]
allowed_methods = ["GET"]
allowed_origins = ["https://maisoncode.paris"]
}
}
Running terraform apply creates the bucket.
If I change allowed_methods to ["GET", "HEAD"] and run apply again, Terraform updates the bucket API. It enables CI/CD for infrastructure.
The Imperative Model (Pulumi)
Terraform is great, but HCL is a dedicated language. Pulumi lets you write infrastructure in TypeScript. This gives you loops, functions, and distinct logic.
// index.ts
import * as aws from "@pulumi/aws";
const bucket = new aws.s3.Bucket("assets", {
acl: "public-read",
corsRules: [{
allowedHeaders: ["*"],
allowedMethods: ["GET"],
allowedOrigins: ["https://maisoncode.paris"],
}],
});
export const bucketName = bucket.id;
Managing State
IaC tools store the “State” of the world in a file (terraform.tfstate).
This file maps your code to the Real World (the AWS Resource ID).
Danger: Never store state locally. If your laptop breaks, you lose access to the infra.
Store state in a remote backend (S3 Bucket with Locking or Terraform Cloud).
Drift Detection
“Drift” happens when a junior dev logs into the AWS Console and manually deletes a firewall rule to “fix a bug.”
The Code says firewall is ON. Reality says firewall is OFF.
We run a daily terraform plan cron job.
If it detects changes (Drift), it alerts us on Slack.
“Warning: Infrastructure Drift detected on Security Group sg-123.”
Immutable Infrastructure
In the old days, we SSH’d into servers to update PHP. In the IaC world, we treat servers as Cattle, not Pets. To update the app, we destroy the old server and spin up a new one with the new image. This ensures no “Configuration Drift” or hidden artifacts accumulate over years.
Multi-Cloud Strategy
Shopify is on Google Cloud. Your images are on AWS S3. Your Edge functions are on Cloudflare. IaC manages them all in one file. You can pass the output of one (AWS CloudFront URL) as the input to another (Cloudflare DNS Record).
9. Secret Management: No Passwords in Git
You need to pass the Database Password to the Lambda function.
NEVER write it in main.tf.
NEVER commit .env.
Solution: AWS Secrets Manager + Terraform Data Sources.
- Create secret in AWS Console (or via CLI).
- Terraform references it:
data.aws_secretsmanager_secret_version.db_pass.secret_string. - Terraform injects it as an Environment Variable into the Lambda at deployment time. The secret exists only in RAM during deployment. It never touches the disk.
10. Policy as Code (Sentinel / OPA)
How do you prevent a Junior Dev from spinning up a $5,000/month GPU instance?
Policy as Code.
We use Open Policy Agent (OPA) to scan the Terraform Plan before apply.
deny if instance_type not in ["t3.micro", "t3.small"].
If the code violates the policy, the CI pipeline fails.
This is “Guardrails, not Gatekeepers”.
11. Blue-Green Deployment Infrastructure
IaC allows us to spin up a Duplicate Environment.
- Live is “Green” (v1).
- Terraform spins up “Blue” (v2).
- We run E2E tests on Blue.
- Terraform updates the Load Balancer (ALB) to point to Blue.
- If alerts fire, Terraform reverts the ALB to Green instantly.
- Once stable, Terraform destroys Green. This provides Safety that manual deployments never can.
12. Database Credential Rotation
Compliance says “Rotate passwords every 30 days”.
Humans hate this.
Terraform loves it.
We configure aws_secretsmanager_secret_rotation.
It spins up a Lambda that:
- Login to RDS.
- Create User B.
- Update Secret.
- Update App.
- Delete User A. Zero downtime. Zero human involvement.
14. Disaster Recovery (DR) as Code
What if us-east-1 goes down? (It happens).
With IaC, DR is a script.
terraform apply -var="region=us-west-2".
In 15 minutes, your entire infrastructure (Load Balancers, EC2, Databases) is replicated on the other side of the country.
We verify this quarterly by running “Game Days”.
We verify that we can spin up the stack from scratch in an empty AWS account.
If you click buttons in the console, DR is impossible. You will be down for days.
With IaC, you are down for minutes.
Why Maison Code Discusses This
At Maison Code, we believe that Infrastructure is Product. We don’t hire “Sysadmins”. We hire DevOps Engineers. We build self-healing, auto-scaling, immutable infrastructure. We hand you the keys (the Git Repo), not a black box. We empower your team to deploy 10 times a day without fear of breaking the network. Because velocity requires safety.
16. Conclusion
Infrastructure as Code is the difference between a “Hobby Project” and an “Enterprise Platform”. It turns “Ops” into software engineering. It gives you auditability, speed, and safety. Stop clicking standard buttons. Start writing code.
Tired of manual server setup?
We migrate manual infrastructure to robust, auditable Terraform/Pulumi pipelines.