Closed12

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

not75743not75743

メモ

awscc

  • dafault_tagsが使用できない

chatbot

  • あらかじめslackワークスペースを登録しておく
  • 既存のチャネルの重複はできない
  • チャネルIDはチャネルのリンクから取得可能
    • https://xxxxxxxxx-xxxxxxxx.slack.com/archives/<チャネルID>
not75743not75743

動作確認

停止していたEC2を起動すると、こんな通知がきます

EC2を停止するとこんな感じです。

成功ですね

not75743not75743

Terraformコード

特筆すべき点はなし

EventBridge

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
}
not75743not75743

プロバイダ

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、初めて知りました。
Cloud Control API を利用する事で、作成、参照、変更、削除 基本的なリソース操作が共通で使えるようになるらしい
今度調べてみる
https://docs.aws.amazon.com/cloudcontrolapi/latest/userguide/what-is-cloudcontrolapi.html
https://dev.classmethod.jp/articles/aws-cloud-control-api-kinesis/

not75743not75743

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]
  }
}
not75743not75743

ChatBotと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

設定済みチャネルをdataで使用する

こちらのほうが使用機会多いかな

variable "slack_configration_id" {}

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

idにはarnを入れればOKです

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

not75743not75743

ガードレールのポリシー

明示して設定しないとAdministratorAccessが設定されることがわかった
正直こいつの存在がよくわかっていない

このスクラップは2023/06/28にクローズされました