A team builds a “secure” Terraform module for network access.
- No public exposure
- Tight CIDR ranges
- Looks clean in review
It gets reused everywhere.
Six months later, someone adds a temporary rule:
- “just for testing”
- wider CIDR
- meant to be removed
It never is.
Now that same module is deployed across environments.
What was a small exception becomes the new baseline.
Nothing broke in CI.
No scanner flagged it as critical.
But the network just got weaker everywhere.
That’s IaC.
The Problem Isn’t Misconfiguration
It’s replication.
In traditional networks:
A bad config affects one device
You troubleshoot, fix, move on
In IaC:
- A bad pattern becomes a module
- A module becomes a standard
- A standard becomes everywhere
You don’t just make mistakes.
You institutionalize them.
Why the Usual Security Model Fails
Most teams bolt security onto the pipeline:
- Scan configs
- Enforce policies
- Run compliance checks
Looks solid.
Breaks in practice.
1. Scanners Catch Known Problems, Not Bad Decisions
They’ll flag:
- open ports
- outdated images
They won’t flag:
- flat network design
- over-trusting internal traffic
- unnecessary connectivity
Those are architectural issues. Tools don’t understand intent.
2. Policies Get Bypassed Under Pressure
You add OPA or cloud policies.
Then:
- A deploy gets blocked
- A deadline is looming
- Someone adds an exception
Or worse:
- forks the module
- removes the restriction
Now you have two realities:
- “secure standard”
- “what actually runs in prod”
Guess which one matters.
3. Automation Expands Blast Radius
Automation is neutral.
If your inputs are weak:
- It spreads weak configs faster
- It applies them consistently
- It removes friction that used to slow mistakes down
IaC doesn’t create risk.
It removes the natural brakes.
4. Drift Quietly Undermines Everything
Even if your pipeline is perfect:
- Manual changes happen
- Cloud services mutate behavior
- Scaling introduces new paths
Your “declared state” and “real state” diverge.
Most teams don’t notice until something breaks.
Security assumptions become outdated.
No one updates the code.
Now your IaC is just documentation of a system that no longer exists.
The Real Shift: Control the Possible States
Security in IaC isn’t about scanning or checking.
It’s about limiting what can exist.
If a dangerous configuration is possible, it will happen.
Eventually.
What This Looks Like in Practice
1. Kill Flexibility Where It Matters
Stop building “universal” modules.
Bad example:
- Any port
- Any CIDR
- Optional restrictions
Good example:
- Only approved ports
- Only internal ranges
- No override without redesign
Less flexible. Way safer.
2. Make Safe the Default, Not an Option
If the easiest path isn’t secure, engineers won’t take it.
Defaults should:
- deny exposure
- enforce segmentation
- require explicit opt-in for risk
Security should feel like the path of least resistance.
3. Treat Policy as a Hard Boundary
Not guidance.
Not warnings.
Hard stops.
If a config violates a rule:
- it doesn’t deploy
- no exceptions inline
- changes require redesign, not bypass
Anything else becomes negotiable under pressure.
4. Reconcile State Continuously
This is where most teams fail.
You need:
- drift detection
- periodic reconciliation
- visibility into real vs declared state
Without this, your IaC is lying to you.
What Changes for Engineers
You lose some freedom.
That’s the point.
- Fewer ways to build things
- Fewer “quick fixes”
- More intentional design upfront
In return:
- fewer surprises
- smaller blast radius
- systems that behave predictably
You stop relying on discipline.
You start relying on design.
Operational Takeaway
IaC doesn’t improve security.
It amplifies whatever you already have.
If your design is weak, IaC will spread that weakness everywhere.
If your controls are optional, they will be ignored when it matters most.
Security in IaC is not about tools.
It’s about constraints.
If unsafe configurations are possible, they are inevitable.
