AWS Chatbotを使ってSlackに通知をさせてみた結果(CloudFormation編)
こんにちは、あるがです。
今回は、過去に書いた「AWS Chatbotを使ってSlackに通知をさせてみた結果(導入〜テスト編)」記事の続編となります。
よろしくお願いいたします。
serverless.yml の記述
以前はコンソール上で行っていた ChatBot 作成ですが、いちいち、手で作るのは非常に面倒ですし、
忘れた頃に、消さなければいけなくなったとき、どれをどのようにどこで作ったのか
資料があればよいですが、なければ、消すのにもそうとうな時間を要します。
また昨今では、こういった処理もコードで管理するのが主流となってますよね。
ある種、作成手順書にもなる yml ファイルですが、
その作成したファイル「aws-health-check-chatbot.yml」の中身がこちらになります。
AWSTemplateFormatVersion: "2010-09-09"
Description: aws-health-check-chatbot
Parameters:
SlackWorkspaceId:
Type: String
Default: ""
SlackChannelId:
Type: String
Default: ""
Resources:
# IAM role
HealthCheckIAMloreChatbot:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- chatbot.amazonaws.com
Action:
- "sts:AssumeRole"
Policies:
- PolicyName: policies
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action:
- cloudwatch:Describe*
- cloudwatch:Get*
- cloudwatch:List*
Resource: "*"
# AWS Chatbot
HealthCheckChatbotConfiguration:
Type: AWS::Chatbot::SlackChannelConfiguration
Properties:
ConfigurationName: HealthCheckChatbotConfiguration
GuardrailPolicies:
- arn:aws:iam::aws:policy/AdministratorAccess
IamRoleArn: !GetAtt HealthCheckIAMloreChatbot.Arn
SlackChannelId: !Ref SlackChannelId
SlackWorkspaceId: !Ref SlackWorkspaceId
SnsTopicArns:
- !Ref HealthCheckSNSTopic
# EventBridge
HealthCheckEventBridgeRule:
Type: AWS::Events::Rule
Properties:
Name: HealthCheckEventBridgeRule
EventPattern:
source:
- aws.health
detail-type:
- AWS Health Event
Targets:
- Arn: !Ref HealthCheckSNSTopic
Id: sns-topic
# SNS topic
HealthCheckSNSTopic:
Type: AWS::SNS::Topic
Properties:
TopicName: HealthCheckSNSTopic
HealthCheckTopicPolicy:
Type: AWS::SNS::TopicPolicy
Properties:
PolicyDocument:
Statement:
- Sid: AllowServices
Effect: Allow
Principal:
Service:
- events.amazonaws.com
Action: "sns:Publish"
Resource:
- !Ref HealthCheckSNSTopic
Topics:
- !Ref HealthCheckSNSTopic
ハマったところ
まずはこちらのブログ「AWSCloudformationでEventBridgeからSNSを設定したが通知がこないそこのあなたへ【コードあり】」をご覧ください。
ここにハマったところの詳細が書かれております。
SNSトピックからメッセージの発行ボタンで、Slackに通知するところまでは行ったのですが、
実際にEC2のアクションを、EventBridgeを通じて、SNSが通知をしてくれるところが
うまく機能しませんでした。
つまり、コンソールで作っていたときは自動で設定してくれていた
下記の処理を、AWS CloudFormation 用にあらためて書かなければなりませんでして、
それに気づくまでは Slack 通知がうまくできませんでした。
HealthCheckTopicPolicy:
Type: AWS::SNS::TopicPolicy
Properties:
PolicyDocument:
Statement:
- Sid: AllowServices
Effect: Allow
Principal:
Service:
- events.amazonaws.com
Action: "sns:Publish"
Resource:
- !Ref HealthCheckSNSTopic
Topics:
- !Ref HealthCheckSNSTopic
調べてみるとAWS公式にも、Q&Aがありましたのでご紹介しておきます。
AWS Chatbot が Amazon SNS からメッセージを受信しないのはなぜですか?
Amazon SNS トピックのアクセスポリシーが、別の AWS のサービスがトピックにメッセージを発行するために必要な許可を付与していることを確認する
1.Amazon SNS コンソールを開きます。
2.左側のナビゲーションペインで、[Topics] (トピック) を選択します。
3.AWS Chatbot がサブスクライブしたトピックを選択します。その後、[Edit] (編集) を選択します。
4.[Access policy] (アクセスポリシー) タブを選択します。その後、アクセスポリシーの [Statement] (ステートメント) セクションを確認します。適切な AWS のサービスが SNS:Publish API アクションを実行することをポリシーが許可していることを確認します。
5.適切なサービスがトピックにイベントを発行することを Amazon SNS アクセスポリシーが許可していない場合は、次の手順を実行してポリシーを更新します。
トピックページの [Details] (詳細) セクションで、[Edit] (編集) を選択します。
[アクセスポリシー] セクションを展開し、必要な許可を追加します。
また、インベント通知用の Slack チャンネルを作っておくことをおすすめいたします。
デプロイ方法
deployコマンドはこちらになります。
Slack のチャネルIDをデプロイ時に指定することで、yml にベタ書きする必要がなく
セキュリティ面強化が図れます。
※ 我社では、AWSアカウントが複数ありまして、その中に、本番用・開発用が存在しており、
万が一、デプロイで本番用に行かないように、aws s3 ls などのコマンドで
自分がデプロイする先(つまり、コピーしたAWSのCredentialsは
どこから持ってきたのか、s3のファイル一覧を見て、devという名称のファイルがあれば
開発用だなということ)を事前に確認しておきましょう。
皆さんのAWS環境は、本番用と開発用にわかれていますでしょうか?
aws cloudformation deploy --template ./aws-health-check-chatbot.yml --stack-name health-check-chatbot --capabilities CAPABILITY_NAMED_IAM --parameter-overrides SlackChannelId='xxxxxxxxxx' SlackWorkspaceId='xxxxxxx'
※ チャンネルIDとworkspaceidは過去に書いた「AWS Chatbotを使ってSlackに通知をさせてみた結果(導入〜テスト編)」記事を参考にして調べてください
※ すでにchatbotに登録されているslackチャンネルは指定できないのでご注意ください
削除コマンド
もし、間違ってデプロイしてしまったり、やり直したい場合は、
まずはこちらのコマンドで消してください。
aws cloudformation delete-stack --stack-name health-check-chatbot