IOanyT Innovations

Share this article

Infrastructure as Code: Beyond the Buzzword
DEVOPS

Infrastructure as Code: Beyond the Buzzword

'We use Terraform' isn't the same as practicing Infrastructure as Code. Here's the maturity model that separates IaC theater from operational excellence.

IOanyT Engineering Team
16 min read
#infrastructure-as-code #Terraform #DevOps #automation #cloud

A Question That Sounds Definitive But Isn't

"Do you practice Infrastructure as Code?""Yes, we use Terraform."

This exchange happens dozens of times a week in technical due diligence, vendor evaluations, and engineering interviews. The answer sounds definitive, but it tells you almost nothing about the actual state of the team’s infrastructure practice. “We use Terraform” can mean five wildly different things, ranging from “we have a few .tf files we wrote last year” all the way to “every byte of our infrastructure flows through a tested, automated, self-service pipeline.”

Infrastructure as Code is not a tool. It’s a practice, with discrete maturity levels that produce dramatically different operational outcomes. Most teams that report practicing IaC are operating at the bottom of the maturity curve while believing they’re near the top. The gap between perceived and actual maturity is the source of a remarkable amount of operational pain that nobody can quite explain.

The Real Test

Can you recreate your entire production environment from code, with no human intervention, in under an hour? If the answer is no, you're doing IaC theater, not IaC practice. The tooling is the easy part. The discipline is what produces the outcome.

The IaC Maturity Model

Five distinct levels separate what teams actually practice. Each level has characteristic symptoms, capabilities, and operational outcomes. Most importantly, each level enables the level above it—you can’t skip from Level 1 to Level 5 by adopting a new tool.

1

Level 1: Ad-Hoc IaC

Some resources exist in Terraform files, often the ones somebody bothered to codify when they were first set up. Other resources—usually the ones that came later, or the ones that were urgent—were created by clicking through the AWS console and never made it back into code. There's no state management strategy beyond "the `.tf` files live in a git repo."

The team genuinely believes they "have IaC" because they have Terraform. In reality, the code and the infrastructure have been diverging since week one. Manual changes overwrite code changes. The drift is invisible until someone runs `terraform plan` and gets a wall of unexpected diffs.

Outcome: You cannot recreate the environment from code. The code is documentation, not source of truth.

2

Level 2: Partial IaC

Most production resources are now codified. State management is in place—remote state, locking, an organized backend. Some module structure exists, though there's still a lot of copy-paste between similar resources. Plans are reviewed informally, applies happen manually from someone's laptop.

This is where most "we have IaC" teams actually live. The infrastructure mostly works, the code mostly matches, and the team can usually recover from problems. But there's no automated validation, no testing, and a handful of resources that everyone knows are still manual but nobody has gotten around to importing.

Outcome: You could mostly recreate the environment, but it would take days and require significant manual work.

3

Level 3: Consistent IaC

All infrastructure lives in code. Modules are properly factored, with clear interfaces and reusable patterns. Every infrastructure change goes through pull request review, just like application code. Plans are generated automatically in CI; applies still happen manually but only after explicit approval.

This is where IaC starts feeling like real engineering rather than ops scripting. Drift detection runs on a schedule. Code review catches mistakes before they reach production. The infrastructure has a changelog, a review history, and a story you can read.

Outcome: You can recreate the environment from code, reliably, in hours. Changes are reviewed before they happen.

4

Level 4: Tested IaC

Infrastructure code is tested. Tools like Terratest validate that modules produce the resources they claim to. Policy-as-code (OPA, Sentinel, or equivalent) enforces security, compliance, and cost guardrails automatically. Validation runs in CI before any plan is allowed to proceed.

Environments are guaranteed consistent because the same modules build them all, with environment-specific variable overrides. The team has confidence that a change tested in staging will behave identically in production—not because they trust the engineer, but because the system structurally enforces it.

Outcome: Infrastructure changes feel safe. Security and compliance are continuous, not point-in-time.

5

Level 5: Continuous Infrastructure

Infrastructure changes flow through CI/CD just like application changes. Promotion between environments is automated. Self-service infrastructure provisioning works for application developers, with policy guardrails preventing dangerous configurations. Drift detection automatically remediates or flags discrepancies in real time.

At this level, the distinction between application and infrastructure changes mostly dissolves. Both are code, both are tested, both flow through the same pipelines, both are deployed continuously. Developers don't wait for DevOps; DevOps enables, doesn't gate.

Outcome: Infrastructure changes are as safe and routine as feature deployments. The team ships more, not less, infrastructure work.

The Distribution in Practice

Across hundreds of teams we've worked with or assessed, the maturity distribution skews heavily to the lower end. Most teams genuinely believe they're at Level 4 or 5 because they have the tooling. Actual capability tells a different story.

LevelApproximate % of OrganizationsSelf-Reported Level
Level 1: Ad-Hoc~40%Often reported as Level 3
Level 2: Partial~30%Often reported as Level 4
Level 3: Consistent~20%Reported as Level 4
Level 4: Tested~8%Accurately reported
Level 5: Continuous~2%Accurately reported

Self-assessment tends to overshoot actual capability by one or two levels. The honest test isn't what tools you use; it's what your environment recovery time would be if you had to rebuild it tomorrow.

The Symptoms of Low Maturity

You can diagnose a team’s actual IaC level without looking at their code. The conversational symptoms are reliable. If you hear yourself or your team saying these things regularly, the maturity level is lower than you think.

"Let me check the console"

When troubleshooting requires logging into AWS console to see what's actually deployed, your code doesn't reflect reality. The console becomes the source of truth, and the code becomes documentation that's perpetually out of date.

"Don't touch that resource"

When certain production resources are off-limits to Terraform because "it'll break them," you have state management problems. Critical infrastructure has been modified out-of-band and is now untouchable from code.

"We'll add that later"

When new resources are created manually with the intention to codify them later, "later" almost never arrives. Drift accumulates by default. Each new manual resource is a small permanent erosion of the IaC promise.

"It works in dev but not prod"

When environments behave differently despite "having IaC," the environments aren't actually being built from the same modules. Manual changes or inconsistent variable management have created environment-specific divergence.

"Only Sarah can apply"

When one person is the gatekeeper for infrastructure changes, you have a knowledge silo and a bus-factor problem. Sarah's vacation becomes a production risk. Sarah's resignation becomes an emergency.

"The apply failed, let me fix it"

When applies routinely require manual intervention to succeed—running specific commands, importing resources, editing state—your IaC isn't truly automated. It's a semi-automated process with manual repair steps embedded throughout.

The pattern: these symptoms feel normal because most teams have lived with them for years. They only seem like symptoms when you experience what mature IaC actually feels like—where the console is for read-only inspection, applies are routine and automated, drift is detected and remediated automatically, and any engineer can safely make infrastructure changes through the same review process they use for application code.

What Mature IaC Actually Enables

The point of climbing the maturity curve isn’t tooling sophistication for its own sake. Each level unlocks specific capabilities that change what your business can do operationally. The capability gap between Level 2 and Level 4 is much bigger than the tooling gap suggests.

At Level 1-2

  • DR time: Weeks to months to recreate production. Realistic disaster recovery is a multi-team project, not a routine procedure.
  • Environment parity: Staging and production drift apart. "It works in dev" is a regular phrase.
  • Change safety: Infrastructure changes are scary, batched, and risky. Failures are catastrophic.
  • Self-service: Developers wait for DevOps. Infrastructure is a bottleneck.
  • Compliance: Manual audits before each compliance review. Evidence is point-in-time and labor-intensive.

At Level 4-5

  • DR time: Hours, not weeks. Disaster recovery is a tested, repeatable procedure.
  • Environment parity: Staging is production at smaller scale, guaranteed by code.
  • Change safety: Infrastructure changes are routine, small, and frequent. Failures caught before apply.
  • Self-service: Developers provision what they need within guardrails. DevOps enables, doesn't gate.
  • Compliance: Continuous, queryable, automatic. The infrastructure itself is the audit trail.

The compounding effect matters. Each capability isn’t just a one-time win—it changes the cadence of everything downstream. Faster DR enables more aggressive infrastructure experimentation. Self-service unblocks developer velocity. Continuous compliance makes regulated markets accessible. The maturity curve isn’t optional infrastructure polish; it’s the floor on what your business can do operationally.

The Path Up the Curve

Climbing the maturity curve is a sequenced effort. Each level has prerequisites the level above can’t work without. Most teams try to skip steps and end up either reverting or operating at false maturity—claiming Level 4 capabilities while structurally stuck at Level 2.

From Level 1 to Level 2

Codify all remaining manual resources. Implement remote state with locking. Establish basic module patterns so similar resources stop being copy-pasted. Define a state management strategy that all engineers follow.

Effort: Medium. Mostly mechanical work, plus some discipline. Impact: High—gets you to the baseline of meaningful IaC.

From Level 2 to Level 3

Import all remaining manually-created resources, even the inconvenient ones. Establish mandatory code review for infrastructure changes. Automate plan generation in CI. Add drift detection on a schedule. Define module patterns and stop tolerating copy-paste.

Effort: Medium. Impact: High—this is where IaC starts feeling like engineering instead of ops scripting.

From Level 3 to Level 4

Add infrastructure testing (Terratest or equivalent). Implement policy-as-code for security, compliance, and cost guardrails. Standardize and document module patterns. Automate validation checks before any plan is allowed to proceed.

Effort: High. Impact: Medium—gets you confidence and continuous compliance, but most teams underweight how much this matters until they need it.

From Level 4 to Level 5

Build full CI/CD for infrastructure changes. Implement self-service provisioning with guardrails. Add automated drift remediation. Generate documentation from code. Treat infrastructure changes the same as application changes operationally.

Effort: High. Impact: Medium—a velocity multiplier, but only valuable once the foundations are solid.

Strategic Priority

Most organizations should focus on reaching Level 3 before pursuing Level 4 or 5. The gap between Level 2 and Level 3 produces more operational improvement than any later transition. Trying to bolt testing or self-service onto a Level 1-2 foundation usually fails because the foundation can't support the weight.

A Five-Question Self-Assessment

The honest answers to these five questions tell you your team’s actual maturity level. Not what you wish it were. Not what your tooling suggests. What it actually is, today.

  1. What percentage of your infrastructure is actually in code? Be honest. Include the resources everyone knows are manual but nobody talks about.
  2. When was the last manual console change to production? If the answer is "this week" or "I don't know," you're at Level 1 or 2.
  3. How long would full disaster recovery take, if you had to rebuild from scratch right now? If you can't answer in concrete hours, you've never tested it. The real number is probably weeks.
  4. Who can apply infrastructure changes to production? If the answer is one or two people, you have a bus-factor problem. If the answer is "anyone, through the pipeline," you're at Level 4-5.
  5. What happens when a production apply fails halfway through? If the answer involves manual cleanup, state file editing, or paging the on-call DevOps engineer, you're not as automated as you think.

The reality check from this assessment is usually uncomfortable. Most teams discover they’re a level or two below where they thought. That’s fine. The point isn’t to beat yourself up—it’s to know where you actually are so you can plan an honest path forward.

Take Action

Assess Your Maturity

Run the five-question assessment with your team. Honest answers reveal where you actually are.

Our DevOps services

View Our Standard

Our delivery standard includes the IaC requirements we ship to on every project. Forkable, free.

Open repository

Talk to Us

If you're stuck at Level 1-2 and want a path to 3-4, we can help diagnose and execute the climb.

Contact IOanyT

Found this useful? Share it.

If you know a CTO or DevOps lead who thinks "we use Terraform" is a complete answer, this might prompt a useful conversation.

Need Help With Your Project?

Our team has deep expertise in delivering production-ready solutions. Whether you need consulting, hands-on development, or architecture review, we're here to help.