エンジニア

CodePipelineの進行状況をSlackに通知する

CodePipelineの進行状況をSlackに通知する

こんにちは。百木田です。
CI、回してますか?
CodePipelineで実行するステージの進行状況を手軽に見たいと思い、Slackに流れるようにしたので共有します。
ポイントとしては、CodePipelineからLambda functionを呼ぶのではなく、CloudWatchイベントでCodePipelineステージのステータスの変化を検知してLambda functionを呼び出します
今回はできるだけシンプルにするために、すでにCodePipelineは作成済みの想定で、すべてのステージにおけるSUCCEEDEDFAILEDのステータスを通知します。なので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}

一覧に戻る