
複数ある Amazon EC2 インスタンス(Auto Scaling グループ未使用)に対して Terraform で Amazon CloudWatch アラームを設定するコードを実装してみた🧪
実装方針としては aws_instances データソースで Amazon EC2 インスタンスを取得して(今回はタグでフィルタリングする),Terraform の for_each メタ引数を使って aws_cloudwatch_metric_alarm リソースを宣言するイメージ💡
ちなみに aws_instances データソースのドキュメントには「増減するような一時的なインスタンスを取得するのは非推奨」といったニュアンスの警告が載っている.
It's strongly discouraged to use this data source for querying ephemeral instances (e.g., managed via autoscaling group), as the output may change at any time and you'd need to re-run apply every time an instance comes up or dies.
そして,単なるリソース監視ではなくサービス全体の監視を優先するべきという話が「入門監視」に載っていたりもして,どちらも理解した上で実験してみよう〜というモチベーション \( 'ω')/
サンプルコード1
今回は ApplicationName: sandbox というタグを設定した Amazon EC2 インスタンスを取得して,Amazon EC2 インスタンスごとに CPUUtilization に対するアラームを設定してみた.アラーム名は CPUUtilization ${each.key} にした.閾値などの値は何でも OK👌
data "aws_instances" "instances" { instance_state_names = ["running"] instance_tags = { ApplicationName = "sandbox" } } resource "aws_cloudwatch_metric_alarm" "cpu_utilization" { for_each = toset(data.aws_instances.instances.ids) alarm_name = "CPUUtilization ${each.key}" namespace = "AWS/EC2" metric_name = "CPUUtilization" statistic = "Average" threshold = 90 comparison_operator = "GreaterThanThreshold" period = 300 evaluation_periods = 1 dimensions = { InstanceId = each.key } }
Amazon EC2 インスタンスを2台起動してからデプロイすると期待通りになった👏

サンプルコード2
もし Amazon EC2 インスタンス ID 以外の値を参照する場合は aws_instance データソース(aws_instances ではなく🛑)と組み合わせる必要がある.
以下の例ではアラーム説明に Amazon EC2 インスタンスが起動しているアベイラビリティゾーンを表示できるように CPUUtilization alarm of ${each.key} (${data.aws_instance.instance[each.key].availability_zone}) とした👌(特に意味はないけどサンプルとして)
data "aws_instances" "instances" { instance_state_names = ["running"] instance_tags = { ApplicationName = "sandbox" } } data "aws_instance" "instance" { for_each = toset(data.aws_instances.instances.ids) instance_id = each.key } resource "aws_cloudwatch_metric_alarm" "cpu_utilization" { for_each = toset(data.aws_instances.instances.ids) alarm_name = "CPUUtilization ${each.key}" alarm_description = "CPUUtilization alarm of ${each.key} (${data.aws_instance.instance[each.key].availability_zone})" namespace = "AWS/EC2" metric_name = "CPUUtilization" statistic = "Average" threshold = 90 comparison_operator = "GreaterThanThreshold" period = 300 evaluation_periods = 1 dimensions = { InstanceId = each.key } }
もう一度デプロイして期待通りになった👏
