AI-generated Terraform: what evidence belongs in the PR? A green CI result does not prove architectural fit for AI-generated Terraform, according to a practical review checklist published by CloudGeni that calls for plan evidence and post-change verification in pull requests. The checklist argues that reviewers should require the same evidence whether a person or an agent wrote the change, starting with the intended outcome, the root module, target account, region and state boundary, and a link to the Terraform plan recording the commit SHA, run time, workspace, variable inputs and Terraform/provider versions. It warns that saved plans can contain sensitive values and that terraform show -json can expose them in plain text, so only a sanitised summary belongs in the PR. AI-generated Terraform: what evidence belongs in the PR? A green CI result does not prove architectural fit. A practical checklist for reviewing AI-generated Terraform, from plan evidence to post-change verification. Imagine a small Terraform PR for private object storage. A service needs somewhere to put its audit exports. Validation passes, and the configured policy checks report no findings. It looks easy to merge. Then the service owner asks why the resource was added to a new root with a different account, instead of the service's approved module. The checks did their job. They just did not answer that question. This is an illustrative example, but it captures the problem with reviewing AI-generated infrastructure. A green result tells you which checks passed. It does not tell you whether the change fits the system around it. I would ask for the same evidence whether a person or an agent wrote the change. A useful PR makes the decision reviewable. The reviewer should not have to repeat the agent's investigation to work out what they are approving. Start with the intended outcome “Add Terraform for storage” is not enough. For the audit-export example, the PR should state which service writes the exports, which environment needs them, who can read them and how long they must be retained. It should also say what must not change. Existing consumers must keep working. The shared network stays where it is. Retention follows the approved requirement, not a value the agent picked. Link the ticket or architecture decision that establishes those constraints. If the requirement is missing, mark it unresolved. A confident explanation is not a substitute for an agreed requirement. Show where the change belongs Name the root module, target account or subscription, region and state boundary. Identify the owning team. Then explain the module choice. Link the approved module and version, or the existing repository example being followed. Check naming and ownership tags against that example. Explain any exception instead of quietly introducing another pattern. For the storage example, this means showing that the resource belongs in the service's existing module, rather than in an unrelated root with convenient credentials. This is architecture evidence. Terraform can accept both arrangements. Your team may want only one of them. Summarise the actual plan Terraform validate https://developer.hashicorp.com/terraform/cli/commands/validate?ref=blog.cloudgeni.ai checks whether configuration is syntactically valid and internally consistent. It does not validate remote services. That is useful, but it is not a deployment review. Attach a link to the plan https://developer.hashicorp.com/terraform/cli/commands/plan?ref=blog.cloudgeni.ai for the intended environment. Record the commit SHA and run time, together with the workspace, variable inputs and Terraform/provider versions. Keep sensitive variable values out of the PR. Write a short summary using resource addresses. Identify creates and updates. List every delete or replacement separately, including the attribute causing it and the expected service impact. “Two to add, two to destroy” does not explain whether this is an intended replacement or an accidental loss of an existing resource. Call out important values that remain unknown until apply. If the plan cannot establish whether a security-sensitive value is acceptable, explain what will check it later. Do not label uncertainty as a pass. A speculative PR plan can become outdated. Recheck the final plan before apply. If its impact changes, route that changed evidence back through review. Keep raw plan artifacts in access-controlled storage. Saved plans can contain sensitive values, and terraform show -json https://developer.hashicorp.com/terraform/cli/commands/show?ref=blog.cloudgeni.ai can expose them in plain text. Put a sanitised summary in the PR, not a public dump. Separate policy results from architectural judgment Link the security and policy runs, including the ruleset version and what was evaluated: source configuration, the plan, or both. For the storage change, reviewers should be able to find the checks for public exposure and encryption. Show the intended access scope. Include retention requirements where your policies cover them. Document suppressed findings with the exception owner and expiry. Also record checks that did not run. “No findings” and “no scan” should never look the same. A policy pass only covers the rules you have encoded. It cannot approve a module boundary that nobody wrote a rule for. Check consumers outside the diff List the services that use the affected resource and link the evidence used to identify them. Repository references are a starting point. Include consumers in other roots or accounts, and manually configured integrations where relevant. For the audit exports, check the writer's identity and the reporting job that reads them. Tightening access is only useful if the intended writer still works. Terraform's dependencies are not a complete service map. Its depends on documentation https://developer.hashicorp.com/terraform/language/meta-arguments/depends on?ref=blog.cloudgeni.ai covers hidden dependencies that references cannot express. Adding broad dependencies is not a replacement for understanding the consumers. Make operational impact explicit Include the estimated monthly cost change and its assumptions. Storage volume and request rates matter. If you do not have them, say that the estimate is incomplete. Explain any migration or interruption. State who will handle a failed rollout. For a replacement, describe how data is preserved and what recovery requires. Reverting a Git commit is not a recovery plan for deleted data. Choose reviewers for the decision, not just the directory. The module owner can assess conventions. A service owner should confirm consumer behaviour. Bring in security for changed trust boundaries or exceptions. A PR description someone can actually review Start with the decision, not a wall of tool output. For the storage example, the first paragraph could look like this: Illustrative decision summary: Add private storage for audit exports through the service's approved module. Keep the existing shared network unchanged. The service identity writes exports; the reporting identity reads them. Retention must match the linked requirement. Approval is blocked until those access paths are confirmed. Copy the headings below into your PR description. Keep the answers short and link the detailed evidence. “Not applicable” needs a reason; an unresolved answer is not a pass. 1. Why this change? - Outcome: the ticket or decision, acceptance criteria and explicit non-goals. - Placement: root, environment/account, region, state boundary and owning team. - Conventions: module/version, reference example and any deliberate exception. 2. What will the plan do? - Plan evidence: run link, commit SHA, run time, inputs and versions. Do not paste secrets. - Actions: resource addresses for creates and updates. Give every delete or replacement its own explanation. - Unknowns: what the plan cannot establish, and how each important uncertainty will be checked. 3. What could this affect? - Checks: results, ruleset and scope. Show skipped checks and exceptions with an owner and expiry. - Consumers: affected services, the evidence used to find them and assumptions still unresolved. - Impact: estimated monthly cost with assumptions, interruption or migration, and recovery requirements. 4. Who makes the decision? - Review: required owners, the decision each must make and outstanding blockers. - Apply: responsible owner, final-plan recheck and the condition that stops the rollout. - Verification: the test steps, expected observations and person who records the result. If a reviewer has to ask “which account?” or “who still needs this resource?”, the description is not finished. Put the answer next to the decision it supports. Close the loop after apply Define verification before merge. For the storage example, have the owning team test a write using the intended identity, confirm an authorised reader can retrieve it, and check that an unauthorised identity is denied. Confirm the deployed retention and encryption configuration. Link the apply run and record the verification results. Investigate unexpected remaining plan changes rather than assuming an empty diff proves application health. Our drift remediation article https://blog.cloudgeni.ai/configuration-drift-how-to-detect-it-and-auto-fix-it-safely-with-prs/ covers the related question of reconciling deployed state with code. The useful output of an infrastructure agent is a change you can assess. If the PR leaves you guessing about architectural fit, green CI has not finished the job.