Infrastructure as code: learning to love CloudFormation
After the cloud migration came the click-ops: a security group here, an RDS tweak there. Then we tried to rebuild staging from memory, and it took two weeks.
After we migrated to AWS, we did what everyone does: we clicked. A security group here, an RDS parameter tweak there, a load balancer rule at 11 PM during an incident. Six months later, our infrastructure was a crime scene with no witnesses — nobody could say why half of it was configured the way it was.
Click-ops debt is still debt
The wake-up call was trying to build a staging environment that matched production. It took two weeks, and it still wasn't identical — we kept discovering settings that existed only in the console and in one engineer's memory. That's when infrastructure as code stopped being a nice-to-have.
Learning to love the template
We chose CloudFormation over third-party tools for a simple reason: no extra state to manage, no extra service to trust. The practices that made it stick:
- Everything in git. Infrastructure changes go through pull requests like application code. The review conversation — "why are we opening this port?" — is the entire point.
- Change sets before every apply. CloudFormation will happily replace a database if you rename the wrong property. The change set preview is the seatbelt; wear it.
- Small stacks over one mega-stack. Network, data, and application layers as separate stacks with exported outputs. A bad application deploy should never be able to touch the VPC.
- Drift detection on a schedule — because someone will always click something during an incident. The goal isn't preventing that; it's noticing it Monday morning.
The console is for looking. Git is for changing.
The payoff came quietly: the staging environment that once took two weeks now takes twenty minutes and a coffee. And when an auditor asked how our infrastructure was configured, we sent them a repository instead of a screenshot tour. That's the moment it felt like growing up.