TerraformでCloudWatch Dashboardを作る
TerraformでCloudWatch Dashboardを作る機会があったので、それのメモです。
Terraformのバージョン
terraform { required_version = "= 0.12.29" required_providers [ aws = "= 2.70.0" ] }
バージョン低すぎるのは許して...
Terraform Resource
ドキュメントを見るとwidgetsの設定をJSONで渡してあげるようです。
https://registry.terraform.io/providers/hashicorp/aws/2.70.0/docs/resources/cloudwatch_dashboard
ですが、共通項目などがあったりするのでまとめたくなりました。
そこでtemplate_file
を使ってよしなにやってみようと思います。
https://registry.terraform.io/providers/hashicorp/template/latest/docs/data-sources/file
ソースコード
- main.tf
locals { dashboard_name = "sample" dashboard_widgets = [ { metrics: [ "AWS/ECS", "CPUUtilization", "ServiceName", "sample", "ClusterName", "sample" ] title: "cpu utilization" stat: "Average" }, { metrics: [ "AWS/ECS", "MemoryUtilization", "ServiceName", "sample", "ClusterName", "sample" ] title: "memory utilization" stat: "Sum" }, { metrics: [ "AWS/RDS", "CPUUtilization", "DBInstanceIdentifier", "dbinstance" ] title: "db cpu utilization" stat: "Average" }, { metrics: [ "AWS/RDS", "DatabaseConnections", "DBInstanceIdentifier", "dbinstance" ] title: "db connection" stat: "Sum" }, ] } data "template_file" "dashboard" { template = file(./templates/dashboard.tpl") vars = { widgets = jsonencode(local.dashboard_widgets) } } resource "aws_cloudwatch_dashboard" "main" { dashboard_name = local.dashboard_name dashboard_body = data.template_file.dashboard.rendered }
{ "widgets": ${jsonencode([ for index, widget in jsondecode(widgets) : { type = "metric" x = index % 4 * 6 y = floor(index / 4) * 6 width = 6 height = 6 properties = { metrics = [ widget.metrics ] view = "timeSeries" stacked = false region = "ap-northeast-1" title = widget.title period = 60 stat = widget.stat } } ])} }
本来ならModule化してVariableで渡すと思うのですが、ここではlocals
で定義してます。
template_file
に変数を渡すときは、型がstringのみなのでjsonencode
でJSON文字列に変えてテンプレートファイルに渡しています。
stringにしてしまうと変数として扱えないので、テンプレートファイルの中でjsondecode
で戻しています。
そして、JSONの配列の最後だけは,
がいらないので、それに対応するためにまたjsonencode
をつかって、配列の最後だったら,
がつかないようにしています。
最後に
jsonencode -> jsondecode -> jsonencode
しているので、なんだかスマートじゃないように見えますが、ほかにいい方法があったら教えてください。