This prompt is built for DevOps and platform engineering teams who need a consistent, auditable risk summary from terraform plan output before approving terraform apply. The primary job-to-be-done is reducing the cognitive load of scanning large infrastructure diffs by transforming raw plan JSON or text into a structured report that categorizes every proposed change by destruction risk, security impact, and blast radius. The ideal user is a human operator in a CI/CD pipeline, ChatOps bot, or manual change-review workflow who must decide whether to approve, reject, or escalate a plan. The prompt is designed to surface the five changes that matter most—such as security group modifications that open public access or database instance replacements that cause data loss—rather than overwhelming the reviewer with fifty low-risk attribute updates.
Prompt
Terraform Plan Risk Assessment Prompt Template

When to Use This Prompt
Understand the ideal job-to-be-done, required context, and operational boundaries for the Terraform Plan Risk Assessment prompt before integrating it into a review workflow.
Use this prompt when the plan output is available as structured JSON from terraform show -json or as a human-readable plan text. It works best when combined with context about the target environment (e.g., [ENVIRONMENT] = production), the affected service tier, and any organizational policies that define what constitutes a high-risk change. The prompt expects a [RISK_LEVEL] parameter to calibrate sensitivity—for example, a plan touching PCI-scoped resources should use a stricter threshold than a development sandbox. Do not use this prompt for real-time incident response where seconds matter; it is a pre-apply review gate, not a runtime diagnostic tool. It is also not a substitute for policy-as-code engines like Open Policy Agent or Sentinel, which provide hard enforcement. Instead, this prompt adds a layer of contextual reasoning that static policy checks miss, such as identifying that a seemingly safe update in-place for an IAM role actually grants unintended cross-account access.
Before integrating this prompt into a production pipeline, ensure you have a human-in-the-loop approval step for any change categorized as destroy or high severity. The prompt's structured output includes a requires_approval boolean field for each finding, but your application harness must enforce that approval gate—the prompt advises, your code decides. Start by running the prompt against a golden dataset of known safe and dangerous plans to calibrate your [RISK_LEVEL] and [CONSTRAINTS] parameters. Common failure modes include false positives on state-only changes (where the plan shows a resource replacement due to a provider upgrade but no actual infrastructure change) and false negatives on multi-resource chains where individual changes appear safe but their combination creates a security gap. The companion eval checks in this playbook address both.
Use Case Fit
Where the Terraform Plan Risk Assessment prompt delivers reliable value and where it introduces unacceptable operational risk.
Good Fit: Pre-Apply Review Gates
Use when: a Terraform plan output must pass automated review before terraform apply in CI/CD pipelines. Guardrail: Wire the prompt into a deployment gate that blocks apply on critical or high-risk findings until a human approves.
Bad Fit: Real-Time Incident Response
Avoid when: you need sub-second infrastructure decisions during an active outage. Risk: LLM latency and potential hallucination make it unsafe for automated remediation without human-in-the-loop. Guardrail: Use this prompt for post-incident review and pre-apply checks only, not for automated rollback decisions.
Required Input: Structured Plan Output
Requirement: a machine-readable Terraform plan in JSON format (terraform show -json). Risk: Feeding raw text or truncated plans causes the model to miss resource changes or misclassify no-op updates as destructive. Guardrail: Validate input schema before prompting and reject plans exceeding the model's context window.
Operational Risk: Destroy False Positives
Risk: The model flags a replace action as destructive when the resource is stateless and recreation is safe. Guardrail: Combine the prompt output with a post-processing rule that suppresses destroy warnings for resources tagged recreate-safe: true or listed in an allowlist of stateless resource types.
Operational Risk: State-Only Change Confusion
Risk: The model misinterprets refresh-only state changes as planned modifications, generating false risk signals. Guardrail: Pre-filter the plan JSON to exclude resources with only no-op or refresh actions before sending to the prompt. Validate that every finding maps to a concrete planned action.
Process Fit: Human Approval for Destroy
Requirement: Any finding categorized as destroy or force-replace must require explicit human approval before apply proceeds. Guardrail: The prompt output schema must include an approval_required boolean field. The CI/CD system must block the pipeline if approval_required is true and no human sign-off is recorded.
Copy-Ready Prompt Template
A reusable Terraform plan risk assessment prompt with square-bracket placeholders that you can paste into your AI system and adapt for your infrastructure review workflow.
This prompt template is designed to ingest a raw terraform plan output and produce a structured risk report. It categorizes every proposed change by destruction risk, security impact, and blast radius. The template uses square-bracket placeholders for variables you must supply—such as the plan output itself, your organization's risk tolerance, and any environment-specific context. Before using this in a production pipeline, ensure you have a human approval gate wired around any destroy: true findings.
textYou are an infrastructure risk analyst reviewing a Terraform plan for a [ENVIRONMENT_NAME] environment. Your task is to produce a structured risk assessment that categorizes every proposed change before `terraform apply` is executed. ## INPUT [Terraform Plan Output] ## CONTEXT - Environment: [ENVIRONMENT_NAME] - Service/Stack: [SERVICE_NAME] - Change Requestor: [REQUESTOR] - Deployment Window: [DEPLOYMENT_WINDOW] - Organizational Risk Tolerance: [RISK_TOLERANCE: low | medium | high] ## CONSTRAINTS - Do not recommend `apply` if any resource marked `destroy: true` lacks an explicit recreation or migration plan. - Flag any security group, IAM policy, or network ACL change as high-severity until proven otherwise. - Treat state-only changes (e.g., refresh-only updates, data source reads) as informational, not actionable. - If a resource is being replaced in-place, assess whether downtime is expected and note the estimated duration. ## OUTPUT_SCHEMA Return a JSON object with the following structure: { "assessment_summary": { "total_changes": <integer>, "additions": <integer>, "modifications": <integer>, "destructions": <integer>, "overall_risk_level": "low" | "medium" | "high" | "critical", "recommendation": "proceed" | "proceed_with_caution" | "block" }, "findings": [ { "resource_address": "<string>", "change_type": "create" | "modify" | "destroy" | "replace", "risk_category": "destruction" | "security" | "availability" | "cost" | "drift" | "informational", "severity": "low" | "medium" | "high" | "critical", "blast_radius": "<string describing affected services or users>", "finding": "<concise description of the risk>", "requires_approval": <boolean>, "mitigation": "<suggested action before apply>" } ], "state_only_changes": [ { "resource_address": "<string>", "note": "<explanation of why this is informational>" } ] } ## RULES 1. Every resource with `destroy: true` or `force replacement` must have `requires_approval: true`. 2. Security group, IAM, and network ACL changes default to `severity: high` unless the change is purely additive and scoped to least privilege. 3. If `overall_risk_level` is `critical`, `recommendation` must be `block`. 4. Do not fabricate resource addresses. Use the exact addresses from the plan output. 5. If the plan output is empty or unparseable, return `{"error": "Invalid or empty plan output", "recommendation": "block"}`.
To adapt this template, replace the square-bracket placeholders with your actual values. The [Terraform Plan Output] should be the full JSON or human-readable output from terraform plan. For [RISK_TOLERANCE], align with your team's deployment policy—production environments typically use low, while development or staging may accept medium. The [ENVIRONMENT_NAME] and [SERVICE_NAME] fields help the model contextualize blast radius. If you are integrating this into a CI/CD pipeline, pipe the plan output directly into the prompt and parse the JSON response for automated gating. Always log the full prompt and response for auditability, especially when a block recommendation is overridden.
Prompt Variables
Inputs the Terraform Plan Risk Assessment prompt needs to work reliably. Each placeholder must be populated before the prompt is sent. Validation notes describe how to check the input quality before execution.
| Placeholder | Purpose | Example | Validation Notes |
|---|---|---|---|
[TERRAFORM_PLAN_OUTPUT] | The full text output of | Plan: 3 to add, 1 to change, 2 to destroy. ... | Must be non-empty. Parse check: contains |
[CHANGE_CONTEXT] | The PR description, Jira ticket, or change request that explains why this plan is being applied | PR #452: Upgrade RDS instance class from db.t3.medium to db.t3.large for read-heavy workload | Must be non-empty. Schema check: contains a human-readable reason. Null allowed only if [EMERGENCY_CHANGE] is true. |
[ENVIRONMENT] | The target environment identifier (e.g., production, staging, dev) | production | Must match a known environment from the deployment registry. Enum check: production, staging, dev, sandbox. Reject unknown values. |
[SERVICE_NAME] | The primary service or stack name affected by this plan | payment-api | Must be non-empty. Parse check: matches a known service from the service catalog. Warn if service is unregistered. |
[PREVIOUS_PLAN_OUTPUT] | The output of the last successful | Plan: 0 to add, 1 to change, 0 to destroy. ... | Null allowed for first-time applies. If provided, must be valid plan text. Parse check: contains |
[APPROVAL_THRESHOLD] | The risk level at which human approval is required before apply | medium | Enum check: low, medium, high, critical. Default: medium. If set to low, all changes require approval. If set to critical, only destroy and security changes require approval. |
[OUTPUT_SCHEMA] | The expected JSON schema for the structured risk report | {"findings": [...], "overall_risk": "...", "requires_approval": true} | Must be a valid JSON Schema or example object. Parse check: valid JSON. Schema check: contains |
[STATE_FILE_HASH] | SHA256 hash of the current terraform.tfstate file, used to verify state consistency | a1b2c3d4e5f6... | Null allowed for plan-only workflows. If provided, must be 64-character hex string. Parse check: matches regex |
Implementation Harness Notes
How to wire the Terraform Plan Risk Assessment prompt into a CI/CD pipeline or review workflow with validation, retries, and human approval gates.
This prompt is designed to sit inside a deployment pipeline or a manual review step before terraform apply is executed. The primary integration point is after terraform plan generates a JSON output file. Your application should read that file, inject it into the [TERRAFORM_PLAN_JSON] placeholder, and send the assembled prompt to the model. The model's structured JSON response becomes the input to your deployment decision logic. Do not treat the model's output as a simple pass/fail signal; instead, parse the risk_level and individual findings to determine the next step in your workflow.
For a production-grade harness, implement a validation layer that checks the model's output against a strict JSON schema before any deployment decision is made. The schema should enforce that risk_level is one of low, medium, high, or critical, and that each finding in the findings array contains a non-empty resource_address, change_type, risk_category, and rationale. If validation fails, implement a single retry with a repair prompt that includes the raw output and the specific schema errors. Log both the initial failure and the retry result for prompt debugging. For model choice, use a model with strong reasoning capabilities and a large context window to handle verbose Terraform plans; a smaller, faster model may miss subtle resource dependency risks.
The most critical part of the harness is the human approval gate. If the model's output contains any finding with change_type equal to destroy or replace, or if the overall risk_level is critical, the pipeline must halt and require an explicit human approval before proceeding. Route these high-risk plans to a review queue with a clear summary of the model's findings, the full plan diff, and a link to the original plan artifact. For lower-risk plans, you can configure the harness to auto-apply, but always log the model's risk assessment as an audit record. A common failure mode is the model flagging state-only changes (like a refresh that updates a data source) as destructive. Mitigate this by cross-referencing the model's findings against a list of known state-only resource types in your validation layer before triggering the human review gate.
Expected Output Contract
Fields, types, and validation rules for the structured risk report returned by the Terraform Plan Risk Assessment prompt. Use this contract to build a post-processing validator before the output reaches a human reviewer or CI/CD gate.
| Field or Element | Type or Format | Required | Validation Rule |
|---|---|---|---|
risk_summary.overall_risk_level | enum: LOW, MEDIUM, HIGH, CRITICAL | Must match exactly one of the four enum values. If the model returns a different string, reject and retry with explicit enum constraint. | |
risk_summary.total_changes | integer | Must be a non-negative integer. Compare against the count of change objects in the input terraform plan JSON. If mismatch exceeds 5%, flag for human review. | |
risk_summary.destroy_count | integer | Must be a non-negative integer. If greater than zero, overall_risk_level must be at least MEDIUM. If zero but a destroy action appears in findings, reject. | |
findings | array of objects | Array must not be empty when total_changes > 0. Each object must contain resource_address, risk_category, severity, finding_description, and requires_approval fields. | |
findings[].resource_address | string | Must match a resource address present in the input terraform plan. Parse the plan's resource_changes[].address list and validate membership. Unmatched addresses trigger a retry. | |
findings[].risk_category | enum: DESTRUCTION, SECURITY, BLAST_RADIUS, STATE_DRIFT, COST, COMPLIANCE, UNKNOWN | Must be one of the listed enum values. DESTRUCTION is required when the change action is 'delete' or 'replace'. SECURITY is required for IAM, security group, or policy resource types. | |
findings[].severity | enum: LOW, MEDIUM, HIGH, CRITICAL | Must be one of the four enum values. If risk_category is DESTRUCTION and the resource type is a database, stateful set, or persistent volume, severity must be at least HIGH. Validate with a resource-type lookup table. | |
findings[].requires_approval | boolean | Must be true when severity is HIGH or CRITICAL, or when risk_category is DESTRUCTION. If false but severity is HIGH, flag as a logic inconsistency and request human review instead of auto-rejecting. |
Common Failure Modes
Terraform plan risk assessment prompts fail in predictable ways. Here are the most common failure modes and how to guard against them before they reach production.
False Positives on State-Only Changes
What to watch: The model flags resources as destroyed or recreated when Terraform is only refreshing state or updating in-place attributes. This happens when the prompt treats all forces replacement metadata as destructive without checking whether the resource ID remains stable. Guardrail: Include explicit instructions to differentiate between update in-place, create, destroy, and destroy-recreate actions. Require the model to cite the specific Terraform action verb before classifying destruction risk.
Missed Cross-Resource Blast Radius
What to watch: The model assesses each resource change in isolation and misses cascading effects—such as a security group rule deletion that breaks application health checks or a subnet modification that orphans dependent resources. Guardrail: Require the output schema to include a blast_radius field that maps each high-risk change to explicitly named dependent resources. Add a validation step that cross-references the plan's dependency graph before finalizing the risk score.
Security Impact Underranking
What to watch: IAM policy expansions, public IP assignments, or open security group rules are classified as medium or low risk because the model focuses on operational disruption rather than security posture changes. Guardrail: Add a dedicated security impact axis in the output schema with explicit criteria: privilege escalation, network exposure, encryption downgrade, and secret handling. Require any finding in these categories to be escalated to high severity regardless of operational impact.
Plan Truncation and Partial Analysis
What to watch: Large Terraform plans exceed context windows, causing the model to analyze only the first N resources and silently skip the rest. The output looks complete but omits critical changes at the end of the plan. Guardrail: Implement a pre-processing step that counts resources in the plan and splits large plans into chunks by resource type or module. Add a completeness check that verifies the total resource count in the analysis matches the plan input.
Destroy Operations Without Explicit Approval Flag
What to watch: The model correctly identifies destroy operations but fails to mark them as requiring human approval, or buries the approval requirement in prose that automated systems cannot parse. Guardrail: Require a structured boolean field requires_human_approval in the output schema. Set it to true whenever any resource action is destroy or destroy-recreate. Build a pipeline gate that blocks terraform apply until this field is resolved by a human reviewer.
Environment Drift Misattribution
What to watch: The model attributes configuration changes to intentional modifications when they are actually drift between the Terraform state and live infrastructure. This causes the risk report to treat reconciliation as a planned change rather than a corrective action. Guardrail: Include a pre-prompt step that runs terraform plan -detailed-exitcode and captures the drift summary. Pass this as context with instructions to label drift-reconciliation changes separately from intentional modifications and adjust risk scoring accordingly.
Evaluation Rubric
Criteria for evaluating the quality and safety of the Terraform Plan Risk Assessment output before it is surfaced to an operator or used to gate an apply pipeline.
| Criterion | Pass Standard | Failure Signal | Test Method |
|---|---|---|---|
Destroy Detection Recall | All resources with | A | Run prompt against a plan fixture with a known |
No-Op Change Precision | Resources with | A plan containing only in-place tag updates is reported with | Run prompt against a plan fixture with only a |
Security Impact Grounding | Every entry in | An IAM role policy attachment change is listed with a | Run prompt against a plan fixture adding an |
Blast Radius Calculation | The | A change to a shared VPC security group rule produces a | Run prompt against a plan fixture modifying a security group ingress rule. Assert |
Human Approval Flagging | The | A plan with a | Run prompt against a plan fixture with an |
Output Schema Validity | The output is valid JSON that parses successfully and matches the expected schema with all required fields present. | The model returns a text explanation before the JSON object, or the JSON is missing the | Pipe the model output to a |
State-Only Change Handling | Changes to | A | Run prompt against a plan fixture where only a remote state output value changes. Assert |
Confidence and Abstention | The output includes a | A plan with a custom provider resource type is confidently classified as | Run prompt against a plan fixture with a |
Enabling Efficiency, Speed & Accuracy
Intelligent Analysis, Decision & Execution
We build AI systems for teams that need search across company data, workflow automation across tools, or AI features inside products and internal software.
Talk to Us
Search across company data
Give teams answers from docs, tickets, runbooks, and product data with sources and permissions.
Useful when people spend too long searching or get different answers from different systems.

Automate internal workflows
Use AI to route work, draft outputs, trigger actions, and keep approvals and logs in place.
Useful when repetitive work moves across multiple tools and teams.

Add AI to products and internal tools
Build assistants, guided actions, or decision support into the software your team or customers already use.
Useful when AI needs to be part of the product, not a separate tool.
Adapt This Prompt
How to adapt\nAdd a strict JSON output schema with required fields, confidence scores, and evidence pointers to specific plan lines. Include retry logic for malformed JSON and a validator that checks every `resource_address` exists in the plan. Add a pre-processing step that strips `no-op` changes before analysis.\n\n```json\n{\n "output_schema": {\n "findings": [{\n "resource_address": "string (must match plan)",\n "change_type": "create | update | destroy | replace",\n "risk_level": "critical | high | medium | low",\n "risk_category": "destruction | security | blast_radius | cost | performance",\n "confidence": 0.0-1.0,\n "evidence_lines": ["line references from plan"],\n "recommendation": "string",\n "requires_approval": true/false\n }]\n },\n "constraints": [\n "Every resource_address must exist in the input plan",\n "Destroy actions on stateful resources must set requires_approval=true",\n "Confidence below 0.7 must include a caveat field"\n ]\n}\n```\n\n### Watch for\n- Silent format drift when model changes JSON key names\n- Missing `evidence_lines` on high-severity findings\n- State-only changes (tags, refresh) flagged as destructive\n- Large plans exceeding context window—chunk by module or resource count

About the author
Prasad Kumkar
CEO & MD, Inference Systems
Prasad Kumkar is the CEO & MD of Inference Systems and writes about AI systems architecture, LLM infrastructure, model serving, evaluation, and production deployment. Over 5+ years, he has worked across computer vision models, L5 autonomous vehicle systems, and LLM research, with a focus on taking complex AI ideas into real-world engineering systems.
His work and writing cover AI systems, large language models, AI agents, multimodal systems, autonomous systems, inference optimization, RAG, evaluation, and production AI engineering.
Partnered with leading AI, data, and software stack.
How We Work
Custom AI workflows for your Business
One-fit-all AI don't work for modern businesses. At Inferensys, we aim to understand your business & custom requirements; which we use to define most efficient agentic workflows, the data, and the tools for your business.
01
Review the use case
We understand the task, the users, and where AI can actually help.
Read more02
Pick the right approach
We define what needs search, automation, or product integration.
Read more03
Build the first useful version
We implement the part that proves the value first.
Read more04
Improve from there
We add the checks and visibility needed to keep it useful.
Read moreThe first call is a practical review of your use case and the right next step.
Talk to Us