DEV Community

StarkMan
StarkMan

Posted on

Static analysis of infrastructure code finds what the plan already shows

Static analysis of infrastructure code finds what the plan already shows

Infrastructure as code turned provisioning into a reviewable artefact, and an entire category of scanners grew up around reading Terraform, CloudFormation and Kubernetes manifests before they are applied. The scanners work. What they cannot do is see the values that only exist at plan time.

What static analysis reads

A static scanner parses configuration and matches it against rules. A security group that opens port 22 to 0.0.0.0/0 is a finding. A bucket policy that grants public read is a finding. An IAM policy with a wildcard action is a finding.
These rules catch real problems, and they catch them early. The limitation is that the scanner reads the source, not the result.

Where the gap sits

Variables and locals carry values that are resolved later. A security group that references var.allowed_cidr looks correct in the source and is only as good as whatever the pipeline passes in. A count or for_each expression can produce a resource set that no static read predicts.
Module composition is a second gap. A module that is safe in isolation becomes a problem when a caller passes different arguments. The scanner sees the module body and the caller separately, and the risk sits in the combination.
Dynamic blocks and provider-computed attributes are a third. Values the provider fills in, such as an allocated CIDR or a default policy, do not appear in the source at all.

Use the plan

Terraform's own workflow offers the missing view. terraform plan produces an execution plan, and terraform show -json renders it as machine-readable JSON that includes resolved values, defaults, and known-after-apply markers. Policy engines that consume that JSON see the values the static scanner could not.
That view has its own limits. A value that is unknown until apply is represented as unknown, and no policy can judge a number that does not exist yet. Credentials and remote state must be available to the plan step, which changes the trust model of the pipeline.

Practical sequence

Run lint-level checks on every change, because they are cheap and they catch obvious mistakes before review. Run plan-based policy checks where the pipeline can produce a plan, and treat an unknown value as a reason to require manual approval rather than as a pass.
Record which rules run at which stage, so that an approval decision can be traced to the evidence behind it. A pre-commit hook, a CI plan check and a deployment gate are three different controls with three different failure modes.
Do not treat a clean scan as proof of a safe deployment. It means the source matched the rules the team wrote, which is a narrower claim.

References

Top comments (0)