【Terraform】AWS/ChatBotを使用し、EC2の状態が変わったらSlackへ通知する

2023/06/28に公開

はじめに

しばらくSNS・Lambdaを使ってメール通知を試していたのですが、
今回はSlackへの通知を試すため、AWSのChatBotを使用します。

https://aws.amazon.com/jp/chatbot/

EventBridge→SNS→ChatBotのような構成です。
通知するイベントはEC2の状態変化にします。

構成図

どんな通知が届く?

こんな感じです

環境

Terraform 1.4.6

前提

  • プロビジョニングにはTerraformを使用します
  • 通知するイベントはEC2のEC2 Instance State-change Notificationです
  • あらかじめslackワークスペースを登録しておく
  • 既存のチャネルとの重複が不可であるため、通知するチャネルを事前に確認する
  • チャネルIDはチャネルのリンクから取得可能
    • https://xxxxxxxxx-xxxxxxxx.slack.com/archives/<チャネルID>

Terraformコード

プロバイダ

awsプロバイダだとChatBotを管理出来ないため、awsccプロバイダを使用します。

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.65.0"
    }
    awscc = {
      source  = "hashicorp/awscc"
      version = "~> 0.54.0"
    }
  }
}

provider "aws" {
  region = "ap-northeast-1"
  default_tags {
    tags = {
      env       = "test"
      provision = "terraform"
    }
  }
}

provider "awscc" {
  region = "ap-northeast-1"
}

https://registry.terraform.io/providers/hashicorp/awscc/latest/docs

Cloud Control API を利用する事で、作成、参照、変更、削除 基本的なリソース操作が共通で使えるようになるらしいです。
その操作をTerraform上でできるみたいです。
慣れていないため、今度改めて使ってみましょう。
https://docs.aws.amazon.com/cloudcontrolapi/latest/userguide/what-is-cloudcontrolapi.html
https://dev.classmethod.jp/articles/aws-cloud-control-api-kinesis/

EventBridge

EC2 Instance State-change Notificationイベントを飛ばすようにします。

resource "aws_cloudwatch_event_rule" "rule" {
  name           = "ec2-state-rule"
  event_bus_name = "default"

  tags = {
    Name = "ec2-state-rule"
  }

  event_pattern = <<EOF
{
  "source": ["aws.ec2"],
  "detail-type": ["EC2 Instance State-change Notification"]
}
EOF
}

resource "aws_cloudwatch_event_target" "sns" {
  rule = aws_cloudwatch_event_rule.rule.name
  arn  = aws_sns_topic.topic.arn
}

SNS

アクセスポリシーを適切に設定し、EventBridgeからアクセス出来るようにします。
今回はaws_sns_topic_subscriptionでのサブスクリプションの作成は不要です。

resource "aws_sns_topic" "topic" {
  name       = "topic"
  fifo_topic = false
}

resource "aws_sns_topic_policy" "policy" {
  arn    = aws_sns_topic.topic.arn
  policy = data.aws_iam_policy_document.sns_topic_policy.json
}

data "aws_iam_policy_document" "sns_topic_policy" {
  statement {
    effect  = "Allow"
    actions = ["SNS:Publish"]

    principals {
      type        = "Service"
      identifiers = ["events.amazonaws.com"]
    }

    resources = [aws_sns_topic.topic.arn]
  }
}

ChatBotとそのIAMロール

IAMロールにポリシーをアタッチしなくても動作しますね...
後日調べてみましょう

variable "slack_channel_id" {}
variable "slack_workspace_id" {}

resource "awscc_chatbot_slack_channel_configuration" "slack_channel" {
  provider           = awscc
  configuration_name = "slack-test"
  iam_role_arn       = aws_iam_role.slack_role.arn
  slack_channel_id   = var.slack_channel_id
  slack_workspace_id = var.slack_workspace_id
  sns_topic_arns     = [aws_sns_topic.topic.arn]
}

resource "aws_iam_role" "slack_role" {
  name = "slack_role"
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect    = "Allow"
        Principal = { Service = "chatbot.amazonaws.com" }
        Action    = "sts:AssumeRole"
      }
    ]
  })
}

https://registry.terraform.io/providers/hashicorp/awscc/latest/docs/resources/chatbot_slack_channel_configuration

ガードレールは?

今回はguardrail_policiesを設定しませんでした。
その場合、AdministratorAccessが選択されました。

ChatBot(dataを使う場合)

既存チャネルをterraformで使用する場合はこちら
idにはチャネルのArnを入れればOKです

variable "slack_configration_id" {}

data "awscc_chatbot_slack_channel_configuration" "slack_channel" {
  id = var.slack_configration_id
}

https://registry.terraform.io/providers/hashicorp/awscc/latest/docs/data-sources/chatbot_slack_channel_configuration

動作確認

EC2を起動します。

$ aws ec2 start-instances --instance-ids i-035df68f105b21780

通知が届けばOK

停止もしてみましょう。

$ aws ec2 stop-instances --instance-ids i-035df68f105b21780

しばらくまってSTOPPEDに遷移します。OKですね

おわりに

Slackに通知が飛ぶのは便利です。
IAMポリシー周りの理解が追いついていないため、これから固めていきます。

参考

ChatBotを使った通知
https://dev.classmethod.jp/articles/cost-anomaly-detection-slack-terraform/
https://hi1280.hatenablog.com/entry/2022/08/06/191154

ガードレール
https://docs.aws.amazon.com/chatbot/latest/adminguide/understanding-permissions.html
https://qiita.com/hedgehog051/items/15b1817e851b5e338150

Discussion