これは、なにをしたくて書いたもの?
Terraformのリソースの依存関係を出力できないのかな?と思ったのですが、terraform graphコマンドでGraphvizのdot形式で出力可能な
ようなので、1度試してみることにしました。
Command: graph - Terraform by HashiCorp
terraform graph
正確には、Terraformの定義ファイルの構成または実行計画を、可視化するコマンドです。
Command: graph - Terraform by HashiCorp
graph Create a visual graph of Terraform resources
グラフを作成するディレクトリを指定して実行するようで、省略するとカレントディレクトリを対象にして処理を行うようです。
「terraform graph」のヘルプを見てみると、
$ terraform graph -help Usage: terraform graph [options] [DIR]
以下のようなオプションを指定できることが確認できます。
Options:
-draw-cycles Highlight any cycles in the graph with colored edges.
This helps when diagnosing cycle errors.
-type=plan Type of graph to output. Can be: plan, plan-destroy, apply,
validate, input, refresh.
-module-depth=n (deprecated) In prior versions of Terraform, specified the
depth of modules to show in the output.
循環参照や、出力する種類を指定できるようです。出力対象にするモジュールの深さも指定できるようですが、今は非推奨の模様。
こちらを使って、動きをみてみましょう。
環境
今回の環境は、こちらです。
$ terraform version Terraform v0.12.24
また、出力対象としては、MySQL Providerを使ったリソース定義を行います。
サンプルを作成する
作成するのは、MySQLデータベースと、ユーザー×2、ユーザーに紐付ける権限、という構成にします。
あまり意味はないですが、MySQLデータベースだけサブモジュールに切り出してみます。
ざっくり、こんな構成。
$ find main.tf modules -type f main.tf modules/my_mysql/outputs.tf modules/my_mysql/main.tf modules/my_mysql/variables.tf
モジュールは、こんな感じにしました。MySQL Providerは、ルートモジュールの方で宣言しています。
modules/my_mysql/main.tf
resource "mysql_database" "database" {
name = var.database_name
default_character_set = "utf8mb4"
default_collation = "utf8mb4_ja_0900_as_cs_ks"
}
中身は、データベース定義のみです。
あと、Input Variables、Output Variablesも一応作成。
modules/my_mysql/variables.tf
variable "mysql_endpoint" {
default = "localhost:3306"
}
variable "mysql_admin_username" {}
variable "mysql_admin_password" {}
variable "database_name" {}
modules/my_mysql/outputs.tf
output "database_name" {
value = mysql_database.database.name
}
ルートモジュールのメインの構成ファイル。こちらでは、ユーザーの作成と、権限の紐付けを行っています。
main.tf
terraform {
required_version = ">= 0.12.24"
}
locals {
endpoint = "172.17.0.2:3306"
admin_username = "root"
admin_password = "password"
database_admin_user_username = "adminuser"
database_admin_user_password = "password"
database_admin_user_host = "%"
database_application_user_username = "appuser"
database_application_user_password = "password"
database_application_user_host = "%"
}
provider "mysql" {
endpoint = local.endpoint
username = local.admin_username
password = local.admin_password
version = "1.9.0"
}
module "my_mysql" {
source = "./modules/my_mysql"
mysql_endpoint = "172.17.0.2:3306"
mysql_admin_username = "root"
mysql_admin_password = "password"
database_name = "practice"
}
resource "mysql_user" "admin_user" {
user = local.database_admin_user_username
plaintext_password = local.database_admin_user_password
host = local.database_admin_user_host
}
resource "mysql_grant" "admin_user" {
user = local.database_admin_user_username
host = local.database_admin_user_host
database = module.my_mysql.database_name
privileges = ["ALL"]
depends_on = [mysql_user.admin_user]
}
resource "mysql_user" "application_user" {
user = local.database_application_user_username
plaintext_password = local.database_application_user_password
host = local.database_application_user_host
}
resource "mysql_grant" "application_user" {
user = local.database_application_user_username
host = local.database_application_user_host
database = module.my_mysql.database_name
privileges = ["SELECT", "INSERT", "UPDATE", "DELETE"]
depends_on = [mysql_user.application_user]
}
init等々。
$ terraform init $ terraform version Terraform v0.12.24 + provider.mysql v1.9.0 $ terraform fmt -recursive $ terraform validate
今回はここは主題ではありませが、一応、applyできることも確認しておきます。
$ terraform apply -auto-approve $ terraform destroy -force
terraform graphで可視化してみる
では、「terraform graph」で構成を可視化してみましょう。
Command: graph - Terraform by HashiCorp
ドキュメントのサンプルでは、SVG形式で出力していますね。
$ terraform graph | dot -Tsvg > graph.svg
Graphvizで出力に指定できる形式は、こちら。
今回は、PNGにしてみましょう。
$ terraform graph | dot -Tpng > graph.png
出力結果は、こんな感じです。

リソースだけではなくて、ローカル変数も含めて、変数なども表示されるんですね。
図形の種類について
ところで、各要素で図形が異なるようです。
パッと見、ルートは楕円、Providerはひし形、リソースは四角、ローカル変数やInput/Output Variablesはノートのようになっています。
これを確認するには、ソースコードのDotNode関数を見れば良さそうです。
https://github.com/hashicorp/terraform/blob/v0.12.24/terraform/node_provider_abstract.go#L88-L96
https://github.com/hashicorp/terraform/blob/v0.12.24/terraform/node_resource_abstract.go#L413-L421
https://github.com/hashicorp/terraform/blob/v0.12.24/terraform/node_root_variable.go#L56-L64
https://github.com/hashicorp/terraform/blob/v0.12.24/terraform/node_module_variable.go#L142-L150
https://github.com/hashicorp/terraform/blob/v0.12.24/terraform/node_output.go#L131-L139
https://github.com/hashicorp/terraform/blob/v0.12.24/terraform/node_local.go#L62-L70
https://github.com/hashicorp/terraform/blob/v0.12.24/terraform/transform_provider.go#L458-L469
- Provider … diamond
- リソース、データーソース … box
- 変数(variable、local variable) … note
という感じですね。
今回は、Data Sourceを確認しませんでしたが、表示形式としてはboxになるようです。