はじめに
Terraform state や 定義から構成図を出力する inframap というツールはご存じでしょうか
今回 inframap を動かす所までを実施してみました
inframap は terraform graph で出力される構成をより分かりやすくしたいというモチベーションのもと開発されています
inframap を install する
macOS を利用し、 Homebrew が設定済みの場合は以下コマンドを実行するだけで完了します。
また、後のステップで dot
や graph-easy
を利用する場合は graphviz
等も install しておきましょう
併せて、必要に応じて path を通すことも忘れず実施してください
brew install inframap
brew install graphviz # dot を利用する場合
cpan Graph::Easy # graph-easy を利用する場合
inframap を実行する
今回 inframap を実行するために S3 + CloudFront で static site を管理していたと仮定し進めます。
S3 + CloudFront の構成なので以下のような記述になるはずです
provider "aws" {
region = "ap-northeast-1"
}
resource "aws_s3_bucket" "test" {}
resource "aws_s3_bucket_acl" "example_bucket_acl" {
bucket = aws_s3_bucket.test.id
acl = "private"
}
resource "aws_s3_bucket_website_configuration" "test" {
bucket = aws_s3_bucket.test.bucket
index_document {
suffix = "index.html"
}
error_document {
key = "error.html"
}
}
resource "aws_s3_bucket_policy" "test" {
bucket = aws_s3_bucket.test.id
policy = data.aws_iam_policy_document.test.json
}
data "aws_iam_policy_document" "test" {
statement {
sid = "Allow from CloudFront"
effect = "Allow"
actions = ["s3:GetObject"]
resources = ["${aws_s3_bucket.test.arn}/*"]
principals {
type = "AWS"
identifiers = [aws_cloudfront_origin_access_identity.test.iam_arn]
}
}
}
resource "aws_cloudfront_distribution" "test" {
enabled = true
default_root_object = "index.html"
origin {
domain_name = aws_s3_bucket.test.bucket_regional_domain_name
origin_id = aws_s3_bucket.test.id
s3_origin_config {
origin_access_identity = aws_cloudfront_origin_access_identity.test.cloudfront_access_identity_path
}
}
default_cache_behavior {
allowed_methods = ["GET", "HEAD"]
cached_methods = ["GET", "HEAD"]
target_origin_id = aws_s3_bucket.test.id
viewer_protocol_policy = "redirect-to-https"
min_ttl = 0
default_ttl = 3600
max_ttl = 86400
forwarded_values {
query_string = false
cookies {
forward = "none"
}
}
}
restrictions {
geo_restriction {
restriction_type = "none"
locations = []
}
}
viewer_certificate {
cloudfront_default_certificate = true
}
}
resource "aws_cloudfront_origin_access_identity" "test" {}
それでは、用意した main.tf
に対して inframap を実行してみます
$ inframap generate main.tf
strict digraph G {
"aws_cloudfront_distribution.test"->"aws_s3_bucket.test";
"aws_cloudfront_distribution.test" [ height=1.15, image="/Users/mziyut/Library/Caches/inframap/assets/aws/Networking_and_Content_Delivery/Amazon-CloudFront.png", imagepos=tc, labelloc=b, shape=plaintext ];
"aws_s3_bucket.test" [ height=1.15, image="/Users/mziyut/Library/Caches/inframap/assets/aws/Storage/Amazon-Simple-Storage-Service-S3.png", imagepos=tc, labelloc=b, shape=plaintext ];
}
$ inframap generate main.tf | dot -Tpng > inframap_generate.png
# generate inframap_generate.png
$ inframap generate main.tf | dot -Tsvg > inframap_generate.svg
# generate inframap_generate.svg
$ inframap generate main.tf | /usr/local/Cellar/perl/5.36.0/bin/graph-easy
aws_cloudfront_distribution.test
|
|
v
aws_s3_bucket.test
今回は S3 と CloudFront のみの簡単な構成だっため図もシンプルになっています
もう少し複雑な構成であれば、 inframap の恩恵をさらに受けることが出来ます
その他
参考までに terraform graph の実行結果も記載します。
terraform graph も inframap 同様に画像やテキストでの出力を行うことが出来ます
$ terraform graph
digraph {
compound = "true"
newrank = "true"
subgraph "root" {
"[root] aws_cloudfront_distribution.test (expand)" [label = "aws_cloudfront_distribution.test", shape = "box"]
"[root] aws_cloudfront_origin_access_identity.test (expand)" [label = "aws_cloudfront_origin_access_identity.test", shape = "box"]
"[root] aws_s3_bucket.test (expand)" [label = "aws_s3_bucket.test", shape = "box"]
"[root] aws_s3_bucket_acl.example_bucket_acl (expand)" [label = "aws_s3_bucket_acl.example_bucket_acl", shape = "box"]
"[root] aws_s3_bucket_policy.test (expand)" [label = "aws_s3_bucket_policy.test", shape = "box"]
"[root] aws_s3_bucket_website_configuration.test (expand)" [label = "aws_s3_bucket_website_configuration.test", shape = "box"]
"[root] data.aws_iam_policy_document.test (expand)" [label = "data.aws_iam_policy_document.test", shape = "box"]
"[root] provider[\"registry.terraform.io/hashicorp/aws\"]" [label = "provider[\"registry.terraform.io/hashicorp/aws\"]", shape = "diamond"]
"[root] aws_cloudfront_distribution.test (expand)" -> "[root] aws_cloudfront_origin_access_identity.test (expand)"
"[root] aws_cloudfront_distribution.test (expand)" -> "[root] aws_s3_bucket.test (expand)"
"[root] aws_cloudfront_origin_access_identity.test (expand)" -> "[root] provider[\"registry.terraform.io/hashicorp/aws\"]"
"[root] aws_s3_bucket.test (expand)" -> "[root] provider[\"registry.terraform.io/hashicorp/aws\"]"
"[root] aws_s3_bucket_acl.example_bucket_acl (expand)" -> "[root] aws_s3_bucket.test (expand)"
"[root] aws_s3_bucket_policy.test (expand)" -> "[root] data.aws_iam_policy_document.test (expand)"
"[root] aws_s3_bucket_website_configuration.test (expand)" -> "[root] aws_s3_bucket.test (expand)"
"[root] data.aws_iam_policy_document.test (expand)" -> "[root] aws_cloudfront_origin_access_identity.test (expand)"
"[root] data.aws_iam_policy_document.test (expand)" -> "[root] aws_s3_bucket.test (expand)"
"[root] provider[\"registry.terraform.io/hashicorp/aws\"] (close)" -> "[root] aws_cloudfront_distribution.test (expand)"
"[root] provider[\"registry.terraform.io/hashicorp/aws\"] (close)" -> "[root] aws_s3_bucket_acl.example_bucket_acl (expand)"
"[root] provider[\"registry.terraform.io/hashicorp/aws\"] (close)" -> "[root] aws_s3_bucket_policy.test (expand)"
"[root] provider[\"registry.terraform.io/hashicorp/aws\"] (close)" -> "[root] aws_s3_bucket_website_configuration.test (expand)"
"[root] root" -> "[root] provider[\"registry.terraform.io/hashicorp/aws\"] (close)"
}
}
$ terraform graph | dot -Tpng > terraform_graph.png
# generate terraform_graph.png
$ terraform graph | dot -Tsvg > terraform_graph.svg
# generate terraform_graph.svg
$ terraform graph | /usr/local/Cellar/perl/5.36.0/bin/graph-easy
+ - - - - - - - - - - - - - - - - - - - - - - - - - - +
' root '
' '
' +-------------------------------------------------+ '
' | [root] root | '
' +-------------------------------------------------+ '
' | '
' | '
' | '
+- - - - - - - - - - - - - - - - - - - - - - - - - | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+
' v '
' +------------------------------------------+ +---------------------------------------------------------------------------------------+ +--------------------------------------+ '
' | aws_s3_bucket_website_configuration.test | <---- | [root] provider["registry.terraform.io/hashicorp/aws"] (close) | ----> | aws_s3_bucket_acl.example_bucket_acl | '
' +------------------------------------------+ +---------------------------------------------------------------------------------------+ +--------------------------------------+ '
' | | | | '
' | | | | '
' | v v | '
' | +-------------------------------------------------+ +----------------------------------+ | '
' | | aws_s3_bucket_policy.test | | aws_cloudfront_distribution.test | ---+ | '
' | +-------------------------------------------------+ +----------------------------------+ | | '
' | | | | | '
' | | | | | '
' | v | | | '
' | +-------------------------------------------------+ | | | '
' | +--- | data.aws_iam_policy_document.test | | | | '
' | | +-------------------------------------------------+ | | | '
' | | | | | | '
' | | | | | | '
' | | v | | | '
' | | +-------------------------------------------------+ | | | '
' | | | aws_cloudfront_origin_access_identity.test | <--+ | | '
' | | +-------------------------------------------------+ | | '
' | | | | | '
' | | | - - - - - - - - - - - - - - - - - - | | '
' | | | ' ' | | '
' | | | ' ' | | '
' | | v ' ' | | '
' | | +-------------------------------------------------+ ' ' | | '
' | | | provider["registry.terraform.io/hashicorp/aws"] | ' ' | | '
' | | +-------------------------------------------------+ ' ' | | '
+ - - - | | ^ ' ' | | '
' | | | ' ' | | '
' | | | ' ' | | '
' +------+-------------------------------------------+ | ' ' | | '
' | | | ' ' | | '
' | | | - - - - - - - - - - - - - - - - - - | | '
' | | | | | '
' | | +---------------------------------------------------------------------------------------+ | | '
' | +----------------------------------------------> | aws_s3_bucket.test | <--+ | '
' | +---------------------------------------------------------------------------------------+ | '
' | ^ ^ | '
' +---------------------------------------------------------+ +------------------------------------------+ '
' '
' '
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+
最後に
今回は HCL ファイル main.tf
から構成を出力しましたが、 state ファイルなどからも出力することが出来ます
詳しくは、 README を参照してみてください
References
- cycloidio/inframap: Read your tfstate or HCL to generate a graph specific for each provider, showing only the resources that are most important/relevant.
- Command: graph | Terraform | HashiCorp Developer
- Download | Graphviz
- ironcamel/Graph-Easy: Convert or render graphs (as ASCII, HTML, SVG or via Graphviz)
- aws_s3_bucket_acl | Resources | hashicorp/aws | Terraform Registry
- aws_s3_bucket_website_configuration | Resources | hashicorp/aws | Terraform Registry
- aws_s3_bucket_policy | Resources | hashicorp/aws | Terraform Registry
- aws_cloudfront_distribution | Resources | hashicorp/aws | Terraform Registry
- aws_cloudfront_origin_access_identity | Resources | hashicorp/aws | Terraform Registry