Examples

Real tfplan2md output from actual Terraform plans. See what your reports will look like.

Report Templates

tfplan2md includes built-in templates for different use cases. Choose the right level of detail for your workflow.

Summary Template

--template summary

Compact overview showing only action counts and resource type breakdown. Perfect for notifications where the full report isn't needed.

Best For:
  • Drift detection notifications (Teams, Slack)
  • Scheduled pipeline summaries
  • Quick overviews before viewing full report
Summary Template Output

Terraform Plan Summary

Terraform Version: 1.14.0

Generated: 2025-12-20T14:30:00Z

Summary

Action Count Resource Types
βž• Add 12 1 azurerm_firewall_network_rule_collection
1 azurerm_key_vault
1 azurerm_key_vault_secret
2 azurerm_log_analytics_workspace
1 azurerm_resource_group
2 azurerm_role_assignment
1 azurerm_storage_account
1 azurerm_subnet
2 azurerm_virtual_network
πŸ”„ Change 6 1 azurerm_firewall_network_rule_collection
1 azurerm_key_vault
1 azurerm_key_vault_secret
2 azurerm_storage_account
1 azurerm_virtual_network
♻️ Replace 2 1 azurerm_network_security_group
1 azurerm_subnet
❌ Destroy 3 1 azurerm_role_assignment
1 azurerm_storage_account
1 azurerm_virtual_network
Total 23
# Terraform Plan Summary

**Terraform Version:** 1.14.0

**Generated:** 2025-12-20T14:30:00Z

## Summary

| Action | Count | Resource Types |
|--------|-------|----------------|
| βž• Add | 12 | 1 azurerm_firewall_network_rule_collection<br/>1 azurerm_key_vault<br/>1 azurerm_key_vault_secret<br/>2 azurerm_log_analytics_workspace<br/>1 azurerm_resource_group<br/>2 azurerm_role_assignment<br/>1 azurerm_storage_account<br/>1 azurerm_subnet<br/>2 azurerm_virtual_network |
| πŸ”„ Change | 6 | 1 azurerm_firewall_network_rule_collection<br/>1 azurerm_key_vault<br/>1 azurerm_key_vault_secret<br/>2 azurerm_storage_account<br/>1 azurerm_virtual_network |
| ♻️ Replace | 2 | 1 azurerm_network_security_group<br/>1 azurerm_subnet |
| ❌ Destroy | 3 | 1 azurerm_role_assignment<br/>1 azurerm_storage_account<br/>1 azurerm_virtual_network |
| **Total** | **23** | |

Default Template

default

Full report with summary, resource changes, and attribute details. Shows exactly what will change.

Best For:
  • Standard PR reviews
  • Security audits
  • Change verification
Default Template Output (excerpt)

Terraform Plan Report

Terraform Version: 1.14.0

Summary

Action Count Resource Types
βž• Add 12 ...
πŸ”„ Change 6 ...
Total 23

Resource Changes

πŸ“¦ Module: root

βž• azurerm_resource_group core β€” πŸ†” rg-tfplan2md-demo 🌍 eastus
Attribute Value
location 🌍 eastus
name πŸ†” rg-tfplan2md-demo

🏷️ Tags: environment: demo owner: tfplan2md

πŸ”„ azurerm_storage_account data β€” πŸ†” sttfplan2mddata in πŸ“ rg-tfplan2md-demo 🌍 eastus | 2πŸ”§ account_replication_type, tags.cost_center
Attribute Before After
account_replication_type LRS GRS
tags.cost_center - 1234
# Terraform Plan Report

**Terraform Version:** 1.14.0

## Summary

| Action | Count | Resource Types |
|--------|-------|----------------|
| βž• Add | 12 | ... |
| πŸ”„ Change | 6 | ... |
| **Total** | **23** | |

## Resource Changes

### πŸ“¦ Module: root

<details style="margin-bottom:12px; border:1px solid rgb(var(--palette-neutral-10, 153, 153, 153)); padding:12px">
<summary>βž• azurerm_resource_group <b><code>core</code></b> β€” <code>πŸ†” rg-tfplan2md-demo</code> <code>🌍 eastus</code></summary>
<br/>

| Attribute | Value |
|-----------|-------|
| location | `🌍 eastus` |
| name | `πŸ†” rg-tfplan2md-demo` |

**🏷️ Tags:** `environment: demo` `owner: tfplan2md`

</details>

<details style="margin-bottom:12px; border:1px solid rgb(var(--palette-neutral-10, 153, 153, 153)); padding:12px">
<summary>πŸ”„ azurerm_storage_account <b><code>data</code></b> β€” <code>πŸ†” sttfplan2mddata</code> in <code>πŸ“ rg-tfplan2md-demo</code> <code>🌍 eastus</code> | 2πŸ”§ account_replication_type, tags.cost_center</summary>
<br/>

| Attribute | Before | After |
|-----------|--------|-------|
| account_replication_type | `LRS` | `GRS` |
| tags.cost_center | - | `1234` |

</details>

Feature Examples

See how tfplan2md transforms complex Terraform changes into readable reports.

Firewall Rule Semantic Diffing

Learn more β†’

Array index changes are replaced with a semantic diff showing which rules were added, modified, or removed.

Firewall Network Rule Collection Update
πŸ”„ azurerm_firewall_network_rule_collection network_rules β€” πŸ†” demo-network-rules in πŸ“ rg-firewall-demo | 9πŸ”§ priority, rule[0].destination_addresses[0], rule[0].destination_ports[0], +6 more

πŸ”„ azurerm_firewall_network_rule_collection.network_rules

Collection: demo-network-rules | Priority: 150 | Action: βœ… Allow

Rule Changes

Change Rule Name Protocols Source Addresses Destination Addresses Destination Ports Description
βž• allow-dns πŸ”— TCP, πŸ“¨ UDP 🌐 10.1.0.0/24 🌐 168.63.129.16 πŸ”Œ 53
πŸ”„ allow-http πŸ”— TCP - 🌐 10.1.0.0/24
+ 🌐 10.0.0.0/8
- 🌐 0.0.0.0/0
+ ✳️
πŸ”Œ 80
❌ allow-ssh-old πŸ”— TCP 🌐 10.0.0.0/16 🌐 10.1.0.0/24 πŸ”Œ 22
⏺️ allow-https πŸ”— TCP 🌐 10.1.0.0/24 🌐 0.0.0.0/0 πŸ”Œ 443
<details open style="margin-bottom:12px; border:1px solid rgb(var(--palette-neutral-10, 153, 153, 153)); padding:12px;">
<summary>πŸ”„ azurerm_firewall_network_rule_collection <b><code>network_rules</code></b> β€” <code>πŸ†” demo-network-rules</code> in <code>πŸ“ rg-firewall-demo</code> | 9πŸ”§ priority, rule[0].destination_addresses[0], rule[0].destination_ports[0], +6 more</summary>
<br>

### πŸ”„ azurerm_firewall_network_rule_collection.network_rules

**Collection:** `demo-network-rules` | **Priority:** `150` | **Action:** `βœ… Allow`

#### Rule Changes

| Change | Rule Name | Protocols | Source Addresses | Destination Addresses | Destination Ports | Description |
| -------- | ----------- | ----------- | ------------------ | ---------------------- | ------------------- | ------------- |
| βž• | `allow-dns` | `πŸ”— TCP`, `πŸ“¨ UDP` | `🌐 10.1.0.0/24` | `🌐 168.63.129.16` | `πŸ”Œ 53` | `` |
| πŸ”„ | `allow-http` | πŸ”— TCP | <code style="display:block; white-space:normal; padding:0; margin:0;"><span style="background-color: #fff5f5; border-left: 3px solid #d73a49; color: #24292e; display: inline-block; padding-left: 8px; margin-left: 0;">- 🌐 10.<span style="background-color: #ffc0c0; color: #24292e;">1</span>.0.0/<span style="background-color: #ffc0c0; color: #24292e;">24</span></span><br><span style="background-color: #f0fff4; border-left: 3px solid #28a745; color: #24292e; display: inline-block; padding-left: 8px; margin-left: 0;">+ 🌐 10.<span style="background-color: #acf2bd; color: #24292e;">0</span>.0.0/<span style="background-color: #acf2bd; color: #24292e;">8</span></span></code> | <code style="display:block; white-space:normal; padding:0; margin:0;"><span style="background-color: #fff5f5; border-left: 3px solid #d73a49; color: #24292e; display: inline-block; padding-left: 8px; margin-left: 0;">- <span style="background-color: #ffc0c0; color: #24292e;">🌐 0.0.0.0/0</span></span><br><span style="background-color: #f0fff4; border-left: 3px solid #28a745; color: #24292e; display: inline-block; padding-left: 8px; margin-left: 0;">+ <span style="background-color: #acf2bd; color: #24292e;">✳️</span></span></code> | πŸ”Œ 80 |  |
| ❌ | `allow-ssh-old` | `πŸ”— TCP` | `🌐 10.0.0.0/16` | `🌐 10.1.0.0/24` | `πŸ”Œ 22` | `` |
| ⏺️ | `allow-https` | `πŸ”— TCP` | `🌐 10.1.0.0/24` | `🌐 0.0.0.0/0` | `πŸ”Œ 443` | `` |

</details>

Module Grouping

Learn more β†’

Resources are automatically organized by Terraform module for better readability in multi-module configurations.

Multi-Module Report Structure

Resource Changes

πŸ“¦ Module: root

βž• azurerm_resource_group core β€” πŸ†” rg-tfplan2md-demo 🌍 eastus
Attribute Value
location 🌍 eastus
name πŸ†” rg-tfplan2md-demo

🏷️ Tags: environment: demo owner: tfplan2md

βž• azurerm_storage_account logs β€” πŸ†” sttfplan2mdlogs in πŸ“ rg-tfplan2md-demo 🌍 eastus
Attribute Value
account_replication_type LRS
account_tier Standard
allow_blob_public_access ❌ false
location 🌍 eastus
min_tls_version TLS1_2
name πŸ†” sttfplan2mdlogs
resource_group_name πŸ“ rg-tfplan2md-demo

🏷️ Tags: cost_center: ops environment: demo


πŸ“¦ Module: module.network

βž• azurerm_virtual_network hub β€” πŸ†” vnet-hub in πŸ“ rg-tfplan2md-demo 🌍 eastus 🌐 10.0.0.0/16
Attribute Value
address_space[0] 🌐 10.0.0.0/16
location 🌍 eastus
name πŸ†” vnet-hub
resource_group_name πŸ“ rg-tfplan2md-demo

🏷️ Tags: environment: demo


πŸ“¦ Module: module.security

βž• azurerm_role_assignment rg_reader β€” πŸ‘€ Jane Doe (User) β†’ πŸ›‘οΈ Reader on rg-tfplan2md-demo
Attribute Value
scope πŸ“ rg-tfplan2md-demo in subscription 12345678-1234-1234-1234-123456789012
role_definition_id πŸ›‘οΈ Reader (acdd72a7-3385-48ef-bd42-f606fba81ae7)
principal_id πŸ‘€ Jane Doe (User) [00000000-0000-0000-0000-000000000001]
principal_type πŸ‘€ User
role_definition_name πŸ›‘οΈ Reader

πŸ“¦ Module: module.network.module.monitoring

βž• azurerm_log_analytics_workspace network β€” πŸ†” law-network-monitoring in πŸ“ rg-tfplan2md-demo 🌍 eastus
Attribute Value
location 🌍 eastus
name πŸ†” law-network-monitoring
resource_group_name πŸ“ rg-tfplan2md-demo
retention_in_days 30
sku PerGB2018

🏷️ Tags: environment: demo module: monitoring

## Resource Changes

### πŸ“¦ Module: root

<details style="margin-bottom:12px; border:1px solid rgb(var(--palette-neutral-10, 153, 153, 153)); padding:12px;">
<summary>βž• azurerm_resource_group <b><code>core</code></b> β€” <code>πŸ†” rg-tfplan2md-demo</code> <code>🌍 eastus</code></summary>
<br>

| Attribute | Value |
| ----------- | ------- |
| location | `🌍 eastus` |
| name | `πŸ†” rg-tfplan2md-demo` |

**🏷️ Tags:** `environment: demo` `owner: tfplan2md`

</details>

<details style="margin-bottom:12px; border:1px solid rgb(var(--palette-neutral-10, 153, 153, 153)); padding:12px;">
<summary>βž• azurerm_storage_account <b><code>logs</code></b> β€” <code>πŸ†” sttfplan2mdlogs</code> in <code>πŸ“ rg-tfplan2md-demo</code> <code>🌍 eastus</code></summary>
<br>

| Attribute | Value |
| ----------- | ------- |
| account_replication_type | `LRS` |
| account_tier | `Standard` |
| allow_blob_public_access | `❌ false` |
| location | `🌍 eastus` |
| min_tls_version | `TLS1_2` |
| name | `πŸ†” sttfplan2mdlogs` |
| resource_group_name | `πŸ“ rg-tfplan2md-demo` |

**🏷️ Tags:** `cost_center: ops` `environment: demo`

</details>

---

### πŸ“¦ Module: `module.network`

<details style="margin-bottom:12px; border:1px solid rgb(var(--palette-neutral-10, 153, 153, 153)); padding:12px;">
<summary>βž• azurerm_virtual_network <b><code>hub</code></b> β€” <code>πŸ†” vnet-hub</code> in <code>πŸ“ rg-tfplan2md-demo</code> <code>🌍 eastus</code> <code>🌐 10.0.0.0/16</code></summary>
<br>

| Attribute | Value |
| ----------- | ------- |
| address_space[0] | `🌐 10.0.0.0/16` |
| location | `🌍 eastus` |
| name | `πŸ†” vnet-hub` |
| resource_group_name | `πŸ“ rg-tfplan2md-demo` |

**🏷️ Tags:** `environment: demo`

</details>

---

### πŸ“¦ Module: `module.security`

<details style="margin-bottom:12px; border:1px solid rgb(var(--palette-neutral-10, 153, 153, 153)); padding:12px;">
<summary>βž• azurerm_role_assignment <b><code>rg_reader</code></b> β€” <code>πŸ‘€ Jane Doe (User)</code> β†’ <code>πŸ›‘οΈ Reader</code> on <code>rg-tfplan2md-demo</code></summary>
<br>

| Attribute | Value |
| ----------- | ------- |
| scope | `πŸ“ rg-tfplan2md-demo` in subscription `12345678-1234-1234-1234-123456789012` |
| role_definition_id | `πŸ›‘οΈ Reader` (`acdd72a7-3385-48ef-bd42-f606fba81ae7`) |
| principal_id | `πŸ‘€ Jane Doe (User)` [`00000000-0000-0000-0000-000000000001`] |
| principal_type | `πŸ‘€ User` |
| role_definition_name | `πŸ›‘οΈ Reader` |

</details>

---

### πŸ“¦ Module: `module.network.module.monitoring`

<details style="margin-bottom:12px; border:1px solid rgb(var(--palette-neutral-10, 153, 153, 153)); padding:12px;">
<summary>βž• azurerm_log_analytics_workspace <b><code>network</code></b> β€” <code>πŸ†” law-network-monitoring</code> in <code>πŸ“ rg-tfplan2md-demo</code> <code>🌍 eastus</code></summary>
<br>

| Attribute | Value |
| ----------- | ------- |
| location | `🌍 eastus` |
| name | `πŸ†” law-network-monitoring` |
| resource_group_name | `πŸ“ rg-tfplan2md-demo` |
| retention_in_days | `30` |
| sku | `PerGB2018` |

**🏷️ Tags:** `environment: demo` `module: monitoring`

</details>

Azure Role Assignment Display

Learn more β†’

Role assignments show human-readable names with principal mapping instead of cryptic GUIDs.

Role Assignment Creation
βž• azurerm_role_assignment rg_reader β€” πŸ‘€ Jane Doe (User) β†’ πŸ›‘οΈ Reader on rg-tfplan2md-demo
Attribute Value
scope πŸ“ rg-tfplan2md-demo in subscription 12345678-1234-1234-1234-123456789012
role_definition_id πŸ›‘οΈ Reader (acdd72a7-3385-48ef-bd42-f606fba81ae7)
principal_id πŸ‘€ Jane Doe (User) [00000000-0000-0000-0000-000000000001]
principal_type πŸ‘€ User
role_definition_name πŸ›‘οΈ Reader
<details style="margin-bottom:12px; border:1px solid rgb(var(--palette-neutral-10, 153, 153, 153)); padding:12px;">
<summary>βž• azurerm_role_assignment <b><code>rg_reader</code></b> β€” <code>πŸ‘€ Jane Doe (User)</code> β†’ <code>πŸ›‘οΈ Reader</code> on <code>rg-tfplan2md-demo</code></summary>
<br>

| Attribute | Value |
| ----------- | ------- |
| scope | `πŸ“ rg-tfplan2md-demo` in subscription `12345678-1234-1234-1234-123456789012` |
| role_definition_id | `πŸ›‘οΈ Reader` (`acdd72a7-3385-48ef-bd42-f606fba81ae7`) |
| principal_id | `πŸ‘€ Jane Doe (User)` [`00000000-0000-0000-0000-000000000001`] |
| principal_type | `πŸ‘€ User` |
| role_definition_name | `πŸ›‘οΈ Reader` |

</details>
Principal Mapping File
{
  "users": {
    "12345678-1234-1234-1234-123456789012": "jane.doe@contoso.com",
    "87654321-4321-4321-4321-210987654321": "john.smith@contoso.com"
  },
  "groups": {
    "abcdef12-3456-7890-abcd-ef1234567890": "Platform Team"
  },
  "servicePrincipals": {
    "fedcba98-7654-3210-fedc-ba9876543210": "terraform-spn"
  }
}

Sensitive Value Masking

Learn more β†’

Sensitive values are automatically masked by default to prevent accidental exposure in PRs.

Default (Masked)
βž• azurerm_key_vault_secret db_password β€” πŸ†” db-password
Attribute Value
content_type password
key_vault_id Key Vault kv-tfplan2md in resource group rg-tfplan2md-demo of subscription 12345678-1234-1234-1234-123456789012
name πŸ†” db-password
value (sensitive)
<details style="margin-bottom:12px; border:1px solid rgb(var(--palette-neutral-10, 153, 153, 153)); padding:12px;">
<summary>βž• azurerm_key_vault_secret <b><code>db_password</code></b> β€” <code>πŸ†” db-password</code></summary>
<br>

| Attribute | Value |
| ----------- | ------- |
| content_type | `password` |
| key_vault_id | Key Vault `kv-tfplan2md` in resource group `rg-tfplan2md-demo` of subscription `12345678-1234-1234-1234-123456789012` |
| name | `πŸ†” db-password` |
| value | `(sensitive)` |

</details>
With --show-sensitive
βž• azurerm_key_vault_secret db_password β€” πŸ†” db-password
Attribute Value
content_type password
key_vault_id Key Vault kv-tfplan2md in resource group rg-tfplan2md-demo of subscription 12345678-1234-1234-1234-123456789012
name πŸ†” db-password
value super-secret-value
<details style="margin-bottom:12px; border:1px solid rgb(var(--palette-neutral-10, 153, 153, 153)); padding:12px;">
<summary>βž• azurerm_key_vault_secret <b><code>db_password</code></b> β€” <code>πŸ†” db-password</code></summary>
<br>

| Attribute | Value |
| ----------- | ------- |
| content_type | `password` |
| key_vault_id | Key Vault `kv-tfplan2md` in resource group `rg-tfplan2md-demo` of subscription `12345678-1234-1234-1234-123456789012` |
| name | `πŸ†” db-password` |
| value | `super-secret-value` |

</details>

Real-World Examples

Complete example projects showing tfplan2md in action.

πŸ“‹

Comprehensive Demo

A handcrafted Terraform plan demonstrating all tfplan2md features: firewall rules, NSG rules, role assignments, module grouping, and more.

23 resources 4 modules 8 resource types
Module grouping Firewall rules Role assignments Sensitive values
πŸ”§

Azure DevOps Example

Real Terraform configuration creating Azure DevOps projects, repositories, variable groups, and pipelines. Generate your own plans and test tfplan2md.

4 resources azuredevops provider
Project creation Git repository Variable groups Pipelines

Try It Yourself

Run the comprehensive demo using Docker or build from source.

Using Docker
# Default report with principal mapping
docker run --rm oocx/tfplan2md \
  /examples/comprehensive-demo/plan.json \
  --principals /examples/comprehensive-demo/demo-principals.json

# Summary report
docker run --rm oocx/tfplan2md \
  /examples/comprehensive-demo/plan.json \
  --template summary

# Show sensitive values
docker run --rm oocx/tfplan2md \
  /examples/comprehensive-demo/plan.json \
  --principals /examples/comprehensive-demo/demo-principals.json \
  --show-sensitive
From Source
git clone https://github.com/oocx/tfplan2md.git
cd tfplan2md

# Default report
dotnet run --project src/Oocx.TfPlan2Md/Oocx.TfPlan2Md.csproj -- \
  examples/comprehensive-demo/plan.json \
  --principals examples/comprehensive-demo/demo-principals.json

# Summary report
dotnet run --project src/Oocx.TfPlan2Md/Oocx.TfPlan2Md.csproj -- \
  examples/comprehensive-demo/plan.json \
  --template summary