Infrastructure as Code: Reviewable and Reproducible Environments
📑 On this page
- A concrete example: recreating an environment
- Declarative definitions
- Imperative automation
- Plans
- Apply
- State
- Drift
- Modules
- Versioning modules
- Variables and environments
- Secrets
- Destructive changes
- Imports
- Policy as code
- Testing
- Provider versions
- CI/CD for infrastructure
- Rollback
- Knowledge check
- The one idea to remember
Clicking through a cloud console can create working infrastructure quickly.
Months later, nobody may know every setting, why it exists, or how to reproduce it after failure. Infrastructure as code records intended resources and configuration in reviewed files applied through automation.
Infrastructure as code treats infrastructure change as versioned, testable, and repeatable software change.
It improves visibility, but the real infrastructure remains stateful and potentially destructive.
A concrete example: recreating an environment
A definition describes:
- network and subnets,
- load balancer,
- application service,
- database,
- identity roles,
- monitoring,
- and backups.
The same reviewed modules create development and recovery environments with different approved parameters.
The definitions preserve the design beyond one person's console history.
Declarative definitions
Declarative IaC describes desired state:
three application instances
private database
HTTPS load balancerThe tool compares desired and actual state and calculates changes.
The user specifies the result more than the exact sequence of API calls.
Imperative automation
Imperative tools specify steps:
- create network,
- create subnet,
- create instance,
- attach disk.
They can express complex procedures but need careful idempotency and state checks.
Many systems combine declarative resources with imperative scripts for bootstrapping.
Plans
A plan previews intended operations:
- create,
- update,
- replace,
- or delete.
Reviewers should inspect:
- destructive actions,
- identity changes,
- public exposure,
- region moves,
- and unexpected replacement.
A plan is evidence for a particular code and current state; it can become stale if either changes.
Apply
Apply executes the approved change.
Use:
- authenticated automation,
- locking,
- environment-specific roles,
- captured logs,
- and versioned tool providers.
Partial failure can leave some resources changed and others pending, so rerun and recovery behavior matter.
State
Many IaC tools maintain state that maps definitions to real resource identifiers and attributes.
State can contain sensitive values and is critical coordination data. Protect it with:
- encryption,
- access control,
- locking,
- versioning,
- and backup.
Editing state manually should be a controlled exceptional procedure.
Drift
Drift occurs when actual infrastructure differs from declared state.
Causes include:
- console edits,
- incident changes,
- provider defaults,
- external automation,
- or manual deletion.
Detection should compare regularly. Resolve drift by importing the intentional change into code or restoring declared state.
Modules
Modules package reusable infrastructure patterns.
A service module may include:
- network rules,
- identity,
- logging,
- health checks,
- and standard tags.
Good modules provide safe defaults and useful extension points without hiding every provider behavior.
Versioning modules
Consumers should pin module versions and upgrade intentionally.
A change to one shared module can affect dozens of environments. Release notes, compatibility, tests, and staged rollout are needed just as for application libraries.
Copying modules everywhere avoids central change but creates maintenance forks.
Variables and environments
One codebase can use parameters for:
- region,
- capacity,
- domain,
- retention,
- and service tier.
Do not create so many conditional branches that production becomes a different hidden program. Keep meaningful environment differences explicit and reviewed.
Secrets
Do not place plaintext secrets in definitions, source history, plans, or state unnecessarily.
Use secret references and runtime identity. Some tools still record sensitive outputs in state even when display is hidden, so understand storage behavior.
Marking a value "sensitive" may redact output without encrypting the state file itself.
Destructive changes
Changing one property can force resource replacement.
For a database or network, that may cause outage or data loss. Use:
- deletion protection,
- lifecycle rules,
- backups,
- migration plans,
- and explicit approval.
Never treat a green syntax check as proof that apply is safe.
Imports
Existing manually created resources can often be imported into IaC state.
Import maps the resource; it does not automatically produce a perfect readable definition. Compare every attribute and avoid accidental replacement.
Migration to IaC should be staged and verified.
Policy as code
Automated policy can reject plans that violate guardrails:
- public database,
- unencrypted storage,
- missing tags,
- overly broad IAM,
- or resources outside approved regions.
Policies need tests, ownership, exceptions, and rollout to avoid blocking legitimate recovery.
Testing
IaC testing can include:
- formatting and validation,
- static security analysis,
- policy checks,
- plan review,
- module unit tests,
- temporary environment creation,
- and post-deployment probes.
Only an applied environment can prove provider interaction and runtime behavior.
Provider versions
Provider plugins translate definitions into cloud APIs.
Pin versions. An upgrade can change defaults, resource behavior, or state migration. Review release notes and test plans before broad adoption.
Toolchain reproducibility matters to infrastructure too.
CI/CD for infrastructure
A safe workflow:
- propose code change,
- run validation and policy,
- generate plan,
- review,
- approve,
- apply with a controlled identity,
- verify runtime behavior,
- store evidence.
Production should not rely on one laptop as the authoritative execution environment.
Rollback
Reverting code and applying again does not always restore the previous world.
A deleted database cannot be recreated with its old data unless backup exists. Provider APIs may make changes irreversible.
Plan forward migration, restoration, or replacement according to resource semantics.
Knowledge check
- How do declarative and imperative infrastructure automation differ?
- Why can an approved plan become stale?
- What information does IaC state coordinate?
- Why can a harmless-looking property change be destructive?
- Why is reverting IaC code not always a true rollback?
The one idea to remember
Infrastructure as code records desired environments in versioned definitions and applies them through reviewed automation. Reliability depends on protected state, drift control, pinned tooling, policy, destructive-change safeguards, and runtime verification.