How to Parse Terraform Plan Output in Python

Parse mock Terraform plan output text into structured add, change, and destroy lists using Python.

Easy Python 3.9+ Aug 9, 2026 Automation & scripting 11 views 0 copies

Python code

31 lines
Python 3.9+
import json
from typing import Dict, List

def parse_terraform_plan_output(plan_output_text: str) -> Dict[str, List[str]]:
    """
    Parses a mock Terraform plan output text into a structured dictionary.
    """
    parsed: Dict[str, List[str]] = {"add": [], "change": [], "destroy": []}

    for line in plan_output_text.splitlines():
        line = line.strip()
        if line.startswith("+ "):
            parsed["add"].append(line[2:].strip())
        elif line.startswith("~ "):
            parsed["change"].append(line[2:].strip())
        elif line.startswith("- "):
            parsed["destroy"].append(line[2:].strip())

    return parsed

if __name__ == "__main__":
    mock_plan = """
    + aws_instance.web
    ~ aws_security_group.sg (updated in-place)
    - aws_db_instance.db
    + aws_s3_bucket.bucket
    ~ aws_subnet.subnet (updated in-place)
    Not a change line
    """
    result = parse_terraform_plan_output(mock_plan)
    print(json.dumps(result, indent=2))

Output

stdout
{
  "add": [
    "aws_instance.web",
    "aws_s3_bucket.bucket"
  ],
  "change": [
    "aws_security_group.sg (updated in-place)",
    "aws_subnet.subnet (updated in-place)"
  ],
  "destroy": [
    "aws_db_instance.db"
  ]
}

How it works

The function splits the plan output into lines and strips whitespace for consistent parsing. Each line is checked for Terraform's action prefixes (+, ~, -) to categorize resources into add, change, or destroy lists. The line[2:] slice removes the prefix and an extra space, leaving the resource name. The result is a dictionary with three lists that can be easily inspected or passed to automation logic.

Common mistakes

  • Forgetting to strip lines before checking prefixes, causing false negatives
  • Assuming the prefix has no trailing space, missing the [2:] slice position
  • Including non-resource lines that start with these symbols in logs
  • Handling only filtered plan output instead of the full `terraform plan` text

Variations

  1. Use regex to capture both resource type and name separately
  2. Read from `terraform show -json` output for more structured data instead

Real-world use cases

  • Pre-approval scripts that skip destructive changes in CI pipelines.
  • Automated drift detection comparing planned vs applied infrastructure state.
  • Alerting systems that summarize permission-scoped plan outputs for audit logs.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Automation & scripting

Related tutorials and quizzes for this topic.