CodePipelineの進行状況をSlackに通知する
こんにちは。百木田です。
CI、回してますか?
CodePipelineで実行する
ポイントとしては、CodePipelineからLambda functionを呼ぶのではなく、CloudWatchイベントでCodePipelineステージのステータスの変化を検知してLambda functionを呼び出します。
今回はできるだけシンプルにするために、すでにCodePipelineは作成済みの想定で、すべてのステージにおけるSUCCEEDEDとFAILEDのステータスを通知します。なのでCodePipelineに変更は必要ありません。
また、Slack Botを作成しトークンを発行して使っていますがIncomming Webhookでも同じようなことはできるかと思います。
Serverless Frameworkを使ってCloudWatchイベントの設定と、slackに通知するためのLambda functionをデプロイします。
環境
$ serverless version
1.22.0
ディレクトリ構成
- functions/
- status_notification.py
- serverless.yml
- serverless.env.yml
デプロイ
コードは記事の下の方に書いときます。上記のディレクトリ構成のように配置したらデプロイします。
$ serverless deploy
デプロイできたらCodePipelineを動かしてみます。そうするとslackにこのような通知が来るかと思います。
いつの実行結果なのかをトレースできるようにCodePipelineの実行IDの前半7桁を表示しています。この辺はお好きにカスタマイズしてみてください。
まとめ
CloudWatchイベントの検知がリアルタイムじゃないので、CodePipelineの進行と通知にラグがあったり、前のステージの実行完了と次のステージの実行開始の通知が前後することなどもありますが、実行結果がわかればいいかなくらいの感じなので気にしないことにしてます。
ありがとうございました。
以下、コードたち
status_notification.py
# -*- coding:utf-8 -*-
"""CloudWatch Eventから送られてきたCodePipelineのステージステータスの変更をSlackに通知する"""
import os
import boto3
import urllib.request, urllib.parse
URL = 'https://slack.com/api/chat.postMessage'
SLACK_BOT_TOKEN = os.environ['SLACK_BOT_TOKEN']
CHANNEL = os.environ['CHANNEL']
client = boto3.client('codepipeline')
def handler(event, context):
stage_name = event['detail']['stage']
state = event['detail']['state']
pipeline_execution_id = event['detail']['execution-id']
post_message = '[' + pipeline_execution_id[:7] + '] ' + ' ' + state.ljust(10) + ': ' + stage_name
post_data = {}
post_data['text'] = post_message
post_data['token'] = SLACK_BOT_TOKEN
post_data['channel'] = CHANNEL
data_encoded = urllib.parse.urlencode(post_data).encode("utf-8")
req = urllib.request.Request(URL, data_encoded)
with urllib.request.urlopen(req) as response:
response.read().decode('utf-8')
return
serverless.env.yml
slack:
BOT_TOKEN: xoxb-xxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxx
CHANNEL: XXXXXXXXX
serverless.yml
※ detailのセクションを消すと、すべてのステータスが検知対象になります。
service: slack-notification-sample
frameworkVersion: ">=1.18.0 <2.0.0"
provider:
name: aws
runtime: python3.6
region: ap-northeast-1
stage: dev
environment:
TZ: Asia/Tokyo
package:
include:
- functions/**
exclude:
- serverless.yml
- serverless.env.yml
functions:
statusNotification:
handler: functions/status_notification.handler
events:
- cloudwatchEvent:
event:
source:
- aws.codepipeline
detail-type:
- CodePipeline Stage Execution State Change
detail:
state:
- SUCCEEDED
- FAILED
environment:
CHANNEL: ${file(./serverless.env.yml):slack.CHANNEL}
SLACK_BOT_TOKEN: ${file(./serverless.env.yml):slack.BOT_TOKEN}