Terraform for Application Engineers: Why You Should Own Your Infrastructure

Search for a command to run...

No comments yet. Be the first to comment.
Most Terraform content is written for DevOps and platform teams. This series is for application engineers who build the services and should own the infrastructure that runs them. Each post covers one real decision — module design, state management, secrets, CI/CD, GCP provisioning — with the context that only comes from being close to the application code. No ops background required
I became an engineering lead without a transition plan. One week I was an individual contributor shipping features. The next I was responsible for four engineers, client deadlines, sprint planning, co

S01E04 of FastAPI in Production

Last year we moved a production platform off AWS and onto GCP. Full migration — compute, database, storage, CDN, CI/CD, the works. The product was live, clients were active, and we had no meaningful d

S01E03 of FastAPI in Production

At 11pm on a Tuesday, a Cloud Run service stopped accepting traffic. No deployment had happened. No code had changed. The service was running — Cloud Run showed healthy instances — but requests were timing out at the load balancer.
It took two hours to find the problem. Someone had manually updated a firewall rule in the GCP Console three days earlier to test something locally. The change had never been reverted. It had been sitting there silently breaking a specific traffic path until load shifted to expose it.
Nobody on the team knew the rule existed. It wasn't in code. It wasn't in version control. It wasn't in any PR or deployment log. It was a click in a console that lived only in one person's memory — and that person was asleep.
This is what infrastructure without ownership looks like.
There's a common assumption in engineering teams — especially small ones — that infrastructure is someone else's problem. Developers write the application. Someone else (an ops engineer, a DevOps team, a more senior engineer) handles the cloud config.
This assumption has a cost that's invisible until it isn't.
When infrastructure lives outside the application team's ownership, nobody knows what's actually running. Resources get created manually and never documented. Configuration drifts from what was intended. When something breaks at 11pm, the engineers who are on-call don't have the context to debug it because they never owned the thing that broke.
At a small team of four or five engineers — where there is no separate ops function — this problem is worse. If the lead engineer is the only one who knows how the infrastructure is configured, the team has a single point of failure that isn't visible in any architecture diagram.
Ownership doesn't mean everyone needs to be an infrastructure expert. It means the infrastructure is legible to the people who depend on it.
Owning your infrastructure doesn't mean clicking around in the GCP or AWS Console. It means the infrastructure is defined as code, version-controlled alongside the application, reviewable in a PR, and reproducible from scratch.
When infrastructure is code:
It's auditable. The firewall rule incident above couldn't happen with Terraform. Any change to infrastructure goes through a PR. The PR shows exactly what changes, who approved it, and why. The history is in Git, not in someone's memory.
It's reproducible. Spinning up a staging environment means running terraform apply against a different variable file. It doesn't mean spending two days manually recreating what you think production looks like.
It's shared context. A new engineer who joins the team can read the Terraform code and understand exactly what's running — what services exist, how they're connected, what the scaling config is. They don't need to ask.
It fails loudly. terraform plan shows you what will change before anything changes. The console doesn't.
Infrastructure-as-code tools like Terraform are often positioned as a DevOps or platform engineering concern. That framing is part of the problem.
Application engineers are the ones who understand what the application needs — how it scales, what it connects to, what its failure modes are. A DevOps engineer who writes Terraform for a service they don't understand will provision something technically correct but architecturally wrong. They'll set a max instance count that's too low. They'll miss a dependency. They'll configure a health check that doesn't reflect what the service actually needs to be healthy.
The engineer who built the Cloud Run service is the right person to write the Terraform for it. Not because DevOps engineers aren't capable, but because application context and infrastructure config belong together.
On PulseCart — the event-driven pipeline built across this blog — every Terraform resource was written by the same engineers who wrote the FastAPI services and the Pub/Sub consumers. The Cloud Run autoscaling config reflected what we knew about traffic patterns. The dead-letter topic retry policy reflected what we knew about consumer failure modes. The infrastructure made sense because the people who wrote it understood what it was for.
Fair. Terraform has a learning curve. The HCL syntax is unfamiliar at first. State management has rough edges. Debugging a plan that's doing something unexpected takes practice.
But the alternative isn't "no infrastructure cost." The alternative is debugging production incidents caused by config nobody understands, rebuilding environments from memory when something goes wrong, and onboarding new engineers into a system that exists only in the console and in the heads of whoever set it up.
The time you spend learning Terraform is paid back the first time you spin up a staging environment in 20 minutes instead of two days. It's paid back the second time you can point at a PR and say "that's the change that caused it." It's paid back every time you hand a new engineer a codebase that includes the infrastructure and they don't need to ask where anything is.
You don't need to Terraform everything at once. Pick one service — the one you understand best — and write the infrastructure for it. Get it into version control. Run terraform plan before you apply anything. See what it feels like to have a change history for your infrastructure the way you have one for your code.
The firewall rule that broke our service at 11pm would have been a three-line PR. Someone would have asked why it was needed. It would have been reverted when the test was done, or at minimum documented when it wasn't.
That's the whole argument. Infrastructure in code is infrastructure you can reason about.