Visualizing Terraform Graph
1. Generating Dependency Graph
| Command | Description | Options | Notes |
|---|---|---|---|
| terraform graph | Generates a graph of resources and their dependencies | -draw-cycles - Detect and draw cycles in the graph-type=TYPE - Type of graph to generate (default: "plan") |
Useful for visualizing resource dependencies and identifying potential issues in the configuration |
Note: The output of
terraform graph is in DOT format, which can be visualized using tools like Graphviz.
Summary of terraform graph command
- Generates a dependency graph for Terraform resources
- Helps visualize resource relationships and dependencies
- Supports cycle detection with
-draw-cycles - Output format is DOT (Graphviz)
2. Exporting Graph to DOT Format
Use the terraform graph command to export the Terraform configuration graph in DOT format for visualization.
| Option | Description | Default |
|---|---|---|
| -format=dot | Output format for the graph (supported: dot, json) |
dot |
| -draw-cycles | Draw cycles in the graph (useful for debugging) | false |
| -verbose | Enable verbose output for more details in the graph | false |
Note: The DOT format can be visualized using tools like Graphviz (
dot command) or online graph viewers.
3. Rendering Graph Images
| Command | Description | Notes |
|---|---|---|
| terraform graph | Generates a graph of resources in DOT format | Output can be piped to graphing tools |
| dot -Tpng | Converts DOT format to PNG image | Requires Graphviz installed |
Note: The
dot command is part of Graphviz, which must be installed separately.
| Format | Extension | Tool Required |
|---|---|---|
| PNG | .png |
Graphviz dot |
| SVG | .svg |
Graphviz dot |
.pdf |
Graphviz dot |
Warning: Large graphs may produce images that are too large to view effectively in some tools.
4. Filtering Graph by Type
| Filter Type | Description | Usage Example |
|---|---|---|
| -type=resource | Shows only resource nodes in the graph | terraform graph -type=resource |
| -type=module | Shows only module nodes in the graph | terraform graph -type=module |
| -type=output | Shows only output nodes in the graph | terraform graph -type=output |
| -type=variable | Shows only variable nodes in the graph | terraform graph -type=variable |
Note: The
-type flag can be combined with other filters to narrow down the visualization.5. Generating Plan Graphs
| Option | Values | Description |
|---|---|---|
| -graph | true |
Generate a graph of the Terraform plan in DOT format |
| -graph-output | dot, json |
Output format for the graph (default: dot) |
| -out | plan.out |
Path to save the generated plan file |
Note: The graph output can be visualized using Graphviz or online tools like Graphviz Online.
Example: Save plan to file and generate graph
terraform plan -out=plan.out
terraform graph -out=graph.dot
6. Analyzing Resource Dependencies
| Resource | Dependencies | Description |
|---|---|---|
| aws_instance.web | aws_security_group.web_sg |
Web instance depends on security group for network access |
| aws_s3_bucket.example | aws_iam_role.s3_access |
S3 bucket requires IAM role for access control |
| aws_route53_record.www | aws_cloudfront_distribution.main |
DNS record depends on CloudFront distribution for routing |
Example: Dependency Analysis with terraform graph
terraform graph | dot -Tsvg -o terraform-graph.svg
Note: The
terraform graph command generates a DOT file that can be visualized using Graphviz tools.
Warning: Circular dependencies in Terraform configurations will cause a validation error during
terraform plan.
| Dependency Type | Description | Example |
|---|---|---|
| Explicit | Defined using depends_on |
depends_on = [aws_s3_bucket.example] |
| Implicit | Inferred from resource references in configuration | aws_instance.web.arn = aws_s3_bucket.example.arn |
| Module | Dependencies between modules | module.vpc.aws_subnet.subnet |
7. Identifying Circular Dependencies
Note: Circular dependencies in Terraform occur when resources depend on each other, either directly or indirectly, causing a loop that prevents successful execution.
| Dependency Type | Description | Impact |
|---|---|---|
| Direct Circular Dependency | Resource A depends on Resource B, and Resource B depends on Resource A. | Prevents Terraform plan/apply from completing |
| Indirect Circular Dependency | Resource A depends on Resource B, Resource B depends on Resource C, and Resource C depends on Resource A. | Prevents Terraform plan/apply from completing |
Example: Direct Circular Dependency
resource "aws_instance" "web" {
ami = "ami-12345678"
instance_type = "t2.micro"
# Depends on the 'db' resource
depends_on = [aws_instance.db]
}
resource "aws_instance" "db" {
ami = "ami-12345678"
instance_type = "t2.micro"
# Depends on the 'web' resource - creates circular dependency
depends_on = [aws_instance.web]
}
How to Identify Circular Dependencies
- Run
terraform planorterraform apply - Look for error messages like
Error: Cycle detected... - Use
terraform graphto visualize dependencies - Review resource dependencies in configuration files
Common Causes of Circular Dependencies
- Explicit
depends_onbetween resources - Implicit dependencies through data sources or variables
- Resource references in
count,for_each, ordynamicblocks - Modules that depend on each other
Circular Dependency vs. Valid Dependency
- Circular: Resource A depends on B, and B depends on A
- Valid: Resource A depends on B, and B does not depend on A
8. Using Graph Tools
| Command | Description | Options |
|---|---|---|
| terraform graph | Generates a visual representation of the Terraform graph | -draw-cycles to detect cycles, -type= to specify graph type |
Note: The output is in DOT format and can be visualized using Graphviz or online tools.
Comparison: Graph Visualization Tools
- Graphviz: Local tool, requires installation, highly customizable
- Online DOT viewers: No local setup, easy to use but less control
- Terraform Cloud: Built-in visualization in the UI, collaborative features
9. Interpreting Graph Nodes
| Node Type | Description | Visual Indicators | Usage |
|---|---|---|---|
| Resource | Represents a managed resource in your configuration | Rounded rectangle with resource type label | Shows the actual infrastructure being created or modified |
| Data Source | Retrieves information from external systems without managing state | Dashed border rounded rectangle | Used for fetching metadata or configuration from providers |
| Module | Reusable configuration blocks that encapsulate resources | Hexagon shape with module name | Organizes complex configurations into manageable units |
| Provider | Defines the interface to interact with a cloud or service provider | Circle with provider name | Indicates which provider is used to manage resources |
| Variable | Input values that customize configurations | Double rectangle with variable name | Allows dynamic configuration based on input values |
| Output | Values that are returned after applying configuration | Double circle with output name | Displays results or values that can be referenced externally |
Example: Resource Node
resource "aws_instance" "web" {
ami = data.aws_ami.ubuntu.id
instance_type = "t2.micro"
}
Example: Data Source Node
data "aws_ami" "ubuntu" {
most_recent = true
owners = ["099720109477"]
filters {
name = "ubuntu/images/*"
values = ["hvm:ssd/ubuntu-*"]
}
}
Note: The graph visualization helps identify dependencies between nodes, such as a resource depending on a data source or another resource.
10. Optimizing Graph Structure
| Optimization | Description | Impact |
|---|---|---|
| module dependencies | Use depends_on to explicitly define module order |
Improves graph clarity and prevents unexpected execution order |
| resource grouping | Group related resources in modules or data sources | Reduces graph complexity and improves readability |
| provider configuration | Centralize provider configurations to minimize redundancy | Reduces graph clutter and improves consistency |
Example: Using depends_on for explicit ordering
resource "aws_instance" "web" {
ami = "ami-12345678"
instance_type = "t2.micro"
depends_on = [
aws_security_group.firewall
]
}
resource "aws_security_group" "firewall" {
name = "web-firewall"
}
Note: Avoid overusing
depends_on as it can make the graph less flexible and harder to maintain.