AWS Systems Manager Run Commandの実行結果をSlackに通知する方法
どうも、7月中旬から1~3ヶ月のレンジでホーチミンでリモートワークをする予定のため、今からとても楽しみな古川です。
今回はタイトルの通り、AWS Systems Manager Run Commandの実行結果をSlackに通知する方法を共有したいと思います。
処理フロー
AWS Systems Manager Run Command -> Amazon SNS -> AWS Lambda -> Slack
前提
- AWS Systems Manager Run Commandを実行するメンテナンスウィンドウを作成済み
- AWS Systems Manager Run Commandのドキュメントは
AWS-RunPatchBaseline
の想定とする - Slackへの通知はIncoming Webhookで作成した
Webhook URL
を対象に行い、既に設定が完了しているものとする - AWS LambdaはRubyで作成する
作業の大まかな流れ
- Amazon SNSのトピック作成
- Slack通知の処理を担当するAWS Lambdaのセットアップ
- AWS Systems Manager Run CommandにAmazon SNSを関連づける
実作業
1. Amazon SNSのトピック作成
1-1. IAMロールの作成
URLの「タスク 1: Amazon SNS 通知の IAM ロールを作成する」、「タスク 2: iam:PassRole ポリシーを Amazon SNS ロールにアタッチする」に従いIAMロールを作成。
後述の「4. AWS Systems Manager Run CommandにAmazon SNSを関連づける」内で使用する想定。
上記手順により、以下のような設定のIAMロールが作成される。
※ インラインポリシーが作成されているか要確認。
1-2. トピックの作成
Amazon SNS管理コンソール上でトピックの作成をクリック。
名前を入力して保存。
2.AWS Lambdaのセットアップ
2-1. AWS Lambdaを作成
ランタイムをRuby2.5とし、Lambdaを作成。
作成したLambdaの「コードエントリタイプ」を「コードをインラインで編集」にして以下のコードを main.rb
というファイル名で作成。ハンドラを「 main.lambda_handler
」とする。
コード
require 'uri'
require 'net/http'
require 'json'
def color_by(status)
color = ""
case status
when "Failed"
color = "danger"
when "Success"
color = "good"
when "InProgress"
color = "#16B0FF" #skyblue
else
color = "warning"
end
color
end
def make_notification_text(subject, msg)
content = {
"Subject" => subject,
"CommandID" => msg["commandId"],
"Status" => msg["status"],
"DocumentName" => msg["documentName"],
"InstanceID" => msg["instanceId"],
"RequestedDatetime" => msg["requestedDateTime"],
"EventTime" => msg["eventTime"]
}
text = ""
content.each do |k, v|
text << "*#{k}:*
#{v}
"
end
text
end
def lambda_handler(event:, context:)
puts event
event["Records"].each do |record|
msg = JSON.parse(record["Sns"]["Message"])
# HTTPSで通信するための設定
uri = URI.parse(ENV['SLACK_HOOK_URL'])
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
req = Net::HTTP::Post.new(uri.path, initheader = { 'Content-Type' => 'application/json' })
# attachmentsをキーとすることでSlackの通知メッセージにcolorをセット
# 参考: https://api.slack.com/docs/message-attachments
req.body = { "attachments": [{ "text" => make_notification_text(record["Sns"]["Subject"], msg), "color" => color_by(msg["status"]) }] }.to_json
res = http.request(req)
puts "Response #{res.code} #{res.message}: #{res.body}"
end
end
2-2. 環境変数の設定
Lambdaの環境変数設定にて環境変数をセットする。
SLACK_HOOK_URL
というキーで Incoming Webhook
で作成してある Webhook URL
をセットする。
2-3. Amazon SNSのトリガーを追加
AWS LambdaにAmazon SNSのトリガーを追加。
設定するARNは「1. Amazon SNSのトピック作成」の手順で作成したAmazon SNSのトピックのものとする。
2-4. 実行ロールの設定
AWSLambdaBasicExecutionRole
のポリシーがアタッチされたロールを「実行ロール」にて選択。
3. AWS Systems Manager Run CommandにAmazon SNSを関連づける
既に作成されているAWS Systems Managerのメンテナンスウィンドウより操作。
↓のように対象のメンテナンスウィンドウの「タスク」より①、②と順番にクリックし編集画面へ移動。
編集画面下部に↓の編集項目があるのでそれぞれ値を入力し保存する。
① - チェックをし有効化。
② - 前述の「1. Amazon SNSのトピック作成」の「1-1. IAMロールの作成」で作成したIAMロールを選択。
③ - 前述の「1. Amazon SNSのトピック作成」の「1-2. トピックの作成」で作成したトピックのARNを入力。
以上の設定が完了次第、AWS Systems Manager Run Commandの実行結果が、以下のような形式でSlackへと通知が行くようになります。
ステータスごとに色が変わるので一見してわかりやすくて良いですね。