Amazon EventBridgeの内容をAWS ChatbotでSlackに通知する(EC2インスタンスの開始・停止をSlackに通知する)

Amazon EventBridgeの内容をAWS ChatbotでSlackに通知してみました。サンプルとして、EC2インスタンスの状態変化をSlackに通知します。
2021.10.04

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

以前、SlackのワークフローでEC2インスタンスを開始・停止する仕組みを作りました。

EC2の状態を都度確認するのはめんどくさいので、「EC2インスタンスの状態変化をSlackに通知しよう」となりました。やってみました。

おすすめの方

  • Amazon EventBridgeをCloudFormationで作りたい方
  • Amazon EventBridgeの内容をAWS ChatbotでSlackに通知したい方
  • Amazon EC2インスタンスの状態変化をSlackに通知したい方

前提

  • EC2インスタンスは作成済みとします

AWS Chatbotを準備する

Slackワークスペースの認証とワークスペースID取得

WebコンソールでAWS Chatbotにアクセスし、ワークスペースを追加します。下記のワークスペースIDはあとで必要なのでメモしておきます。

SlackワークスペースのIDを確認する

SlackチャンネルIDを取得

任意のチャンネルのリンクを取得します。

SlackチャンネルIDを確認する

このリンクの最後の文字列を使います。下記例だとABCD1234がチャンネルIDです。

https://classmethod.slack.com/archives/ABCD1234

Amazon EventBridgeをCloudFormationで作成する

CloudFormationテンプレートファイル

AWS ChatbotやIAMロールは、以前の記事の内容そのままです。(Lambdaは無いです) 新たに追加したのは下記です。

  • AWS Chatbotのチャンネル設定が購読するSNS Topic設定
  • SNS Topic
  • SNS Topic Policy
  • Amazon EventBridgeルール

インスタンスIDは直接記載していますが、Slack情報みたいに外部から渡してもOKです。

eventbridge.yaml

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Chatbot-EC2-Command

Parameters:
  Env:
    Type: String
    Default: Env

  SlackWorkspaceId:
    Type: String

  SlackEc2ChannelId:
    Type: String

Resources:
  Ec2SlackChatbot:
    Type: AWS::Chatbot::SlackChannelConfiguration
    Properties:
      ConfigurationName: !Sub xxx-ec2-slack-chatbot-${Env}
      IamRoleArn: !GetAtt Ec2SlackChatbotIamRole.Arn
      LoggingLevel: INFO
      SlackWorkspaceId: !Ref SlackWorkspaceId
      SlackChannelId: !Ref SlackEc2ChannelId
      SnsTopicArns:
        - !Ref SubscribeEc2StatusForChatbotTopic

  Ec2SlackChatbotIamRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub xxx-ec2-slack-chatbot-role-${Env}
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service: chatbot.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: !Sub xxx-ec2-slack-chatbot-policy-${Env}
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - ec2:DescribeInstanceStatus
                Resource:
                  - "*"

  SubscribeEc2StatusForChatbotTopic:
    Type: AWS::SNS::Topic
    Properties:
      TopicName: !Sub xxx-subscribe-ec2-status-for-chatbot-topic-${Env}

  SubscribeEc2StatusForChatbotTopicPolicy:
    Type: AWS::SNS::TopicPolicy
    Properties:
      PolicyDocument:
        Statement:
          - Effect: Allow
            Principal:
              Service: events.amazonaws.com
            Action: sns:Publish
            Resource: '*'
      Topics:
        - !Ref SubscribeEc2StatusForChatbotTopic

  SubscribeEc2StatusEventRule:
    Type: AWS::Events::Rule
    Properties:
      EventPattern:
        source:
          - aws.ec2
        detail-type:
          - EC2 Instance State-change Notification
        detail:
          instance-id:
            - i-xxxx
          state:
            - running
            - stopped
      Targets:
        - Id: SubscribeEc2StatusForChatbotTopic
          Arn: !Ref SubscribeEc2StatusForChatbotTopic

デプロイ

aws cloudformation deploy \
    --template-file eventbridge.yaml \
    --stack-name notify-chatbot-ec2-status-stack \
    --capabilities CAPABILITY_NAMED_IAM \
    --parameter-overrides \
        Env=dev \
        SlackWorkspaceId=XYZXYZ \
        SlackEc2ChannelId=ABCD1234 \
    --no-fail-on-empty-changeset

動作確認

EC2インスタンスを開始したとき

EC2インスタンスを開始してしばらく待つと、Slackに通知が来ました!

Slackに通知されたイベント情報(EC2開始)

EC2インスタンスを停止したとき

EC2インスタンスを停止してしばらく待つと、Slackに通知が来ました!

Slackに通知されたイベント情報(EC2停止)

さいごに

Amazon EventBridgeをCloudFormationで作成してみました。意外と参考例がアリませんでしたので、どなたかの参考になれば幸いです。 (特にSNS Topic Policy関連)

参考