Architectural governance for AI-generated Terraform
Terraform is infrastructure as code — not a programming language or an application framework. Its modules, providers, and state turn architectural decisions into operational reality: what runs in production, where, and who can reach it. When an AI coding agent edits a .tf file it is changing infrastructure, and the same drift that erodes application code erodes the infrastructure layer. Mneme governs that intent through repo-native rules, with no bespoke HCL parser or Terraform plugin required.
Why governance matters in Terraform
Terraform configuration can be versioned, reused, and shared. Modules provide architecture-level abstractions over raw resources, and terraform plan previews proposed changes before they are applied. Teams encode real decisions in that structure: which approved modules to use, which providers and versions are allowed, which regions are in scope, how networks are exposed, what must be encrypted, and how state is stored and locked.
An AI coding agent generating Terraform optimizes for a configuration that applies cleanly, not for your infrastructure architecture. It will declare a raw resource instead of the approved module, widen a security group to unblock connectivity, pin to whatever provider version it saw last, or quietly relax the state backend. Each change is operationally consequential the moment it is applied. Mneme keeps the infrastructure decisions in the agent's context and checks the .tf diff before it merges — preserving intent rather than discovering the regression in production.
What Mneme can govern
Mneme governs the infrastructure decisions a team has already made — expressed as repo-native rules in a decision corpus, not as a built-in Terraform policy pack. Common surfaces:
- Approved modules over direct resources — production infrastructure uses vetted modules instead of ad hoc resource declarations.
- Providers and version constraints — provider sources and version pins stay within the approved set.
- Cloud regions — resources stay in sanctioned regions.
- Network exposure — public ingress and prohibited security-group patterns are blocked.
- Tags, naming, and encryption — required tags, naming conventions, and encryption settings hold.
- State backend and locking — backend, locking, and state-encryption configuration is not weakened.
- Environment separation and sensitive resources — environments stay isolated and sensitive resource classes require review.
Six concrete examples of what the governance layer catches in Terraform repositories under AI-assisted development:
Direct resource instead of the approved module
Module disciplineRule. Production infrastructure must use approved modules, not raw resource declarations.
# AI-generated in prod/network.tf resource "aws_vpc" "main" { # module "vpc" { source = "app.terraform.io/acme/vpc/aws" } expected cidr_block = "10.0.0.0/16" }
Public network exposure
Network exposureRule. No 0.0.0.0/0 ingress to admin or database ports. Internet-facing resources require review.
# AI-generated in prod/security.tf resource "aws_security_group_rule" "db" { type = "ingress" from_port = 5432 to_port = 5432 cidr_blocks = ["0.0.0.0/0"] # database open to the internet }
Unpinned provider and unapproved region
Provider & regionRule. Providers are version-pinned. Resources stay in approved regions (us-east-1, eu-west-1).
# AI-generated in providers.tf provider "aws" { region = "ap-southeast-2" # outside the approved region list } # no required_providers version constraint
Missing required tags and naming
Tagging & namingRule. Every resource carries owner, env, and cost-center tags and follows the naming convention.
# AI-generated in prod/storage.tf resource "aws_s3_bucket" "data" { bucket = "my-bucket-123" # non-conforming name, no tags block }
Encryption disabled on a stored resource
EncryptionRule. Storage at rest is encrypted. No resource may opt out of the encryption requirement.
# AI-generated in prod/storage.tf resource "aws_ebs_volume" "cache" { size = 100 encrypted = false # encryption explicitly disabled }
State backend and locking weakened
State & lockingRule. Remote backend with locking and state encryption. No reverting to a local backend.
# AI-generated in backend.tf terraform { backend "local" {} # remote S3 backend with DynamoDB lock + encrypt=true expected }
Example governance decisions
These are illustrative rules an infrastructure team would author in its own decision corpus. Mneme does not ship them as defaults — it enforces the decisions you record.
Production infrastructure must use approved modules rather than direct resource declarations.
A raw resource where a vetted module is required is surfaced as a module-bypass violation.
Publicly exposed resources require explicit review.
Open ingress or an internet-facing resource class is flagged for review before merge.
State backends, locking configuration, and encryption settings must not be weakened.
Reverting to a local backend or disabling locking or encryption is treated as a regression.
How governance fits the workflow
Mneme sits between your infrastructure decisions and the AI coding tools writing Terraform. The loop is the same one Mneme runs for any repository:
-
Decisions and ADRs are recorded
Your infrastructure decisions live as records in
.mneme/project_memory.json— each with a scope, constraints, and anti-patterns. ADRs can be imported into the same corpus. -
Mneme retrieves the relevant intent
On a prompt or a file write, Mneme retrieves the decisions in scope for the change and injects them into the agent's context — governance before generation, not review after the fact.
-
The AI coding agent changes the configuration
Claude Code, Cursor, Copilot, or a custom agent writes or edits
.tfmodules, variables, and provider and backend configuration with that context in hand. -
Mneme checks the proposed change
mneme checkevaluates the.tfdiff against the corpus: a matched constraint surfaces asWARN, an anti-pattern hit asFAIL. Aligned changes pass cleanly. -
CI gates the merge
In
--mode strictaWARNexits 1 and aFAILexits 2, so the regression blocks the PR beforeterraform applyever runs;--mode warnannotates without blocking.
Beyond application code
Architectural governance must extend beyond generated application code into infrastructure as code and operational configuration. Agents do not only write functions and routes — they write the Terraform, pipelines, and configuration that decide what runs in production. The decision corpus is the same; the surface it governs now includes the infrastructure layer where architectural choices become operational reality.
Where it fits in an infrastructure repository
Terraform governance is repository-level governance applied to infrastructure as code: .tf modules, variables, and provider and backend configuration. The decision corpus lives at .mneme/project_memory.json; mneme check --mode strict gates PR diffs in CI alongside terraform plan. This is repo-native enforcement over the configuration diff — Mneme does not run or replace your Terraform tooling.
This extends architectural governance into governance infrastructure for the operational layer. Bring existing decisions in through ADR import, gate merges with GitHub Actions, and see architectural drift for the problem this prevents.
terraform plan, before apply.
Concept
Governance infrastructure →
Why the governing layer is infrastructure in its own right, application and ops alike.
Concept
Enforcement provenance →
Every flag traces back to the decision and constraint that produced it.
Integration
GitHub Actions →
Wire the governance check into the PR gate that already runs your IaC pipeline.