Terraform has a built-in command to generate a Graphviz digraph representing the output of terraform plan
, but this output is pretty messy and can’t render in MermaidJS.
terraform graph > graph.dot
These steps should clean things up so your graphs can be used in Gitlab, your blog, anywhere that supports MermaidJS!
digraph {
compound = "true"
newrank = "true"
subgraph "root" {
"[root] google_compute_address.nextcloud (expand)" [label = "google_compute_address.nextcloud", shape = "box"]
"[root] google_compute_firewall.iap-to-nextcloud (expand)" [label = "google_compute_firewall.iap-to-nextcloud", shape = "box"]
"[root] google_compute_firewall.nextcloud-external (expand)" [label = "google_compute_firewall.nextcloud-external", shape = "box"]
"[root] google_compute_firewall.nextcloud-internal (expand)" [label = "google_compute_firewall.nextcloud-internal", shape = "box"]
...
Remove all lines with label = "
as they aren’t setting any useful aliases and won’t work in MermaidJS.
Remove the strings [root]
, " (expand)"
, " (close)"
& \"
as they are added to every element and don’t serve a purpose. Presumably Hashicorp imagined this graph being interactive.
Convert ->
to -->
and remove all "
& \"
, lastly remove the top config lines (that don’t have ->
) and the closing }
at the end of file.
Example command:
sed -ri '/label =/d; s|\[root\] ||g; s| \(expand\)||g; s| \(close\)||g; s|\\"||g; s|\"||g; s|\s+->\s+|-->|g; /\t+?}/d' graph.dot
MermaidJS
supports many graph formats but the one I typically use, and the only one I’ve properly tested these instructions against, is
Flow Chart
. To use flowchart add a line to the top with either flowchart LR;
for left-to-right or flowchart TD;
for top-to-bottom.
flowchart TD;
google_compute_address.nextcloud-->provider[registry.terraform.io/hashicorp/google]
google_compute_firewall.iap-to-nextcloud-->google_compute_network.nextcloud
google_compute_firewall.nextcloud-external-->google_compute_network.nextcloud
google_compute_firewall.nextcloud-internal-->google_compute_network.nextcloud
google_compute_global_address.nextcloud_ip_address-->google_compute_network.nextcloud
google_compute_health_check.nextcloud-->provider[registry.terraform.io/hashicorp/google]
google_compute_instance_group_manager.nextcloud-->google_compute_health_check.nextcloud
google_compute_instance_group_manager.nextcloud-->google_compute_instance_template.nextcloud
google_compute_instance_template.nextcloud-->google_compute_address.nextcloud
google_compute_instance_template.nextcloud-->google_service_account.nextcloud
google_compute_instance_template.nextcloud-->google_sql_database_instance.nextcloud
google_compute_instance_template.nextcloud-->var.container_name
google_compute_instance_template.nextcloud-->var.container_tag
google_compute_instance_template.nextcloud-->var.objectstore
google_compute_instance_template.nextcloud-->var.smtp
google_compute_network.nextcloud-->provider[registry.terraform.io/hashicorp/google]
google_monitoring_dashboard.nextcloud-overview-->provider[registry.terraform.io/hashicorp/google]
google_project_service.project-->provider[registry.terraform.io/hashicorp/google]
google_service_account.nextcloud-->provider[registry.terraform.io/hashicorp/google]
google_service_networking_connection.nextcloud_vpc_connection-->google_compute_global_address.nextcloud_ip_address
google_sql_database.nextcloud-->google_sql_database_instance.nextcloud
google_sql_database_instance.nextcloud-->google_service_networking_connection.nextcloud_vpc_connection
google_sql_database_instance.nextcloud-->var.prefix
google_sql_database_instance.nextcloud-->var.sql
google_sql_user.nextcloud-->google_sql_database_instance.nextcloud
google_storage_bucket.nextcloud-data-->provider[registry.terraform.io/hashicorp/google]
google_storage_bucket.nextcloud-data-->var.domain
google_storage_bucket.nextcloud-data-->var.objectstore
provider[registry.terraform.io/hashicorp/google]-->google_compute_firewall.iap-to-nextcloud
provider[registry.terraform.io/hashicorp/google]-->google_compute_firewall.nextcloud-external
provider[registry.terraform.io/hashicorp/google]-->google_compute_firewall.nextcloud-internal
provider[registry.terraform.io/hashicorp/google]-->google_compute_instance_group_manager.nextcloud
provider[registry.terraform.io/hashicorp/google]-->google_monitoring_dashboard.nextcloud-overview
provider[registry.terraform.io/hashicorp/google]-->google_project_service.project
provider[registry.terraform.io/hashicorp/google]-->google_sql_database.nextcloud
provider[registry.terraform.io/hashicorp/google]-->google_sql_user.nextcloud
provider[registry.terraform.io/hashicorp/google]-->google_storage_bucket.nextcloud-data
provider[registry.terraform.io/hashicorp/google]-->var.gcp_project
provider[registry.terraform.io/hashicorp/google]-->var.gcp_region
provider[registry.terraform.io/hashicorp/google]-->var.gcp_zone
root-->provider[registry.terraform.io/hashicorp/google]
root-->var.label
root-->var.machine_type
root-->var.nextcloud_repo
root-->var.redis
This can be further tidied up by getting rid of the root-->
& provider[registry.terraform.io/hashicorp/google]
.
sed -ri '/provider\[registry\.terraform\.io\/hashicorp\/google\]/d; /root-->/d' graph.dot
flowchart TD;
google_compute_firewall.iap-to-nextcloud-->google_compute_network.nextcloud
google_compute_firewall.nextcloud-external-->google_compute_network.nextcloud
google_compute_firewall.nextcloud-internal-->google_compute_network.nextcloud
google_compute_global_address.nextcloud_ip_address-->google_compute_network.nextcloud
google_compute_instance_group_manager.nextcloud-->google_compute_health_check.nextcloud
google_compute_instance_group_manager.nextcloud-->google_compute_instance_template.nextcloud
google_compute_instance_template.nextcloud-->google_compute_address.nextcloud
google_compute_instance_template.nextcloud-->google_service_account.nextcloud
google_compute_instance_template.nextcloud-->google_sql_database_instance.nextcloud
google_compute_instance_template.nextcloud-->var.container_name
google_compute_instance_template.nextcloud-->var.container_tag
google_compute_instance_template.nextcloud-->var.objectstore
google_compute_instance_template.nextcloud-->var.smtp
google_service_networking_connection.nextcloud_vpc_connection-->google_compute_global_address.nextcloud_ip_address
google_sql_database.nextcloud-->google_sql_database_instance.nextcloud
google_sql_database_instance.nextcloud-->google_service_networking_connection.nextcloud_vpc_connection
google_sql_database_instance.nextcloud-->var.prefix
google_sql_database_instance.nextcloud-->var.sql
google_sql_user.nextcloud-->google_sql_database_instance.nextcloud
google_storage_bucket.nextcloud-data-->var.domain
google_storage_bucket.nextcloud-data-->var.objectstore
I hope this can save you time with your next infrastructure diagram!
For those wanting to generate image files from mermaid, this can be achieved with
mermaid-cli
.