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.
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!