7
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

CodeBuildのビルド結果をSlackで通知する

Posted at

2017-06-22のアップデートでCodeBuildのビルド結果をCloudWatchEventsで捕捉できるようになりました。
そのままSNSで通知してもいいのですが、LambdaからIncoming Webhookを使ってSlackに通知してみようと思います。

事前準備

以下のことはすでに済んでいる前提で話を進めます。

  • CodeBuildのプロジェクト作成
  • SlackのIncoming Webhookの設定(URL発行)

実装

さくっと済ませたいのでServerlessフレームワークを使います。

serverless.yml設定

まあこいつを見てもらおうか

serverless.yml
service: notify-build-result
provider:
  name: aws
  runtime: nodejs6.10
  timeout: 180
  stage: ${opt:stage, self:custom.defaultStage}
  #profileオプション追加
  profile: ${opt:profile, self:custom.defaultProfile}
  #regionオプション追加
  region: ${opt:region, self:custom.defaultRegion}
custom:
  defaultStage: dev
  #何も指定がなければ default profile
  defaultProfile: default
  #何も指定がなければ 北バージニア
  defaultRegion: us-east-1

functions:
  notify:
    handler: handler.notify
    memorySize: 128
    events:
      - cloudwatchEvent:
          event:
            source:
              - "aws.codebuild"
            detail-type:
              - "CodeBuild Build State Change"
            detail:
              build-status:
                - SUCCEEDED
                - FAILED
                - STOPPED
              project-name:
                - my-project-name
          enabled: true

イベントの設定

今回キモになるeventsの設定項目は詳しめに説明します。
cloudwatchEventを指定することで、cloudwatchのイベントをトリガーにできます。
cloudwatchEvent.event 以下の項目は

項目名 解説
source cloudwatchで見る対象 今回はCodeBuildが対象なのでaws.codebuildでOK
detail-type 検知するイベントの種類 "CodeBuild Build State Change"を指定するとCodeBuildのステートが変化したタイミングでイベントが発火します。
detail detail以下はCodeBuild特有の設定
detail.build-status CodeBuildのステートがここで設定したものになるとイベントが発火します。用意されているのはSUCCEEDED(成功), FAILED(失敗), STOPPED(中断), PROGRESS(進行中)がありますが、今回は結果を教えてほしいのでPROGRESSは外してます。
detail.project-name 監視対象のプロジェクト 配列の形で複数指定することもできます
enabled トリガーの有効/無効

Lambdaファンクション

payload確認

Lambdaファンクションの実装前に、cloudwatchEventからLambdaをコールしたときにevent引数に何が渡されるか確認しておきます。
いや、まじでトリガーによって引数全然違うから確認しとかないと死ぬ。

イベントの種類によってはLambdaのコンソールのテストイベントの設定からこんな感じで見れますが、
test_event.PNG

残念ながらCodeBuildのcloudwatchEventはこの方法では見られなかったので、Lambdaのコード内でconsole.log(event)とかやって調べます。

その結果がこちら

event.json
{
  "version": "0",
  "id": "50639ce0-1497-4911-baa0-79d9ca880a21",
  "detail-type": "CodeBuild Build State Change",
  "source": "aws.codebuild",
  "account": "account-number",
  "time": "2017-06-26T07:10:43Z",
  "region": "us-east-1",
  "resources": [
     "arn:aws:codebuild:us-east-1:account-number:build/my-project-name:9eb34205-9cba-40f2-a5d0-220497a9643a"
  ],
  "detail": {
    "build-status": "SUCCEEDED",
    "project-name": "my-project-name",
    "build-id": "arn:aws:codebuild:us-east-1:account-number:build/my-project-name:9eb34205-9cba-40f2-a5d0-220497a9643a",
    "current-phase": "COMPLETED",
    "current-phase-context": "[]",
    "version": "1"
  }
}

event.detail以下を見れば何とかなりそうですね。

ファンクション本体

それでは本体を実装していきましょう。
方針としては

  1. event引数からプロジェクト名とビルド結果を取得
  2. 予め用意したSlackのwebhook URLに送信

これだけです。
requestモジュールでPOSTするだけの簡単なお仕事ですね。

handler.js
"use strict";
const request = require('request');

function sendRequest(url, message, callback){

    const post = {
        text: message
    };
    //ヘッダーを定義
    const headers = {
        "Content-Type":"application/json"
    };

    const options = {
        url: url,
        method: "POST",
        headers: headers,
        json: true,
        body: post
    };
    request(options,  (error, response, body) => {
        console.log(body);
        return callback();
    })
}

module.exports.notify = (event, context, callback) => {
  const url = "your-webhook-url";
  const buildDetail = event.detail;
  const message = `${buildDetail["project-name"]}のビルドが${buildDetail["build-status"]}デース!`;
  sendRequest(url, message, () => {
    callback(null);
  });
};

結果確認

成功

pegasus_succeeded.PNG

失敗

pegasus_failed.PNG

なんでペガサスなの?

  1. SUCCEEDEDとかFAILEDとかわざわざ日本語に直すのがめんどくさかった
  2. かといって全部英文にして「英語で言われてもわかんねーよ」とか怒られるのも嫌だった
  3. せや、ペガサスだったら英語と日本語が混ざってても違和感ない!いけるやん!

実装してから気づいたこと、改善案

  1. cloudwatchEventの発火がめっちゃ早い
    • CodePipeline内に設置したCodeBuildに仕込んでたところ、ペガサスの通知が来てから数十秒間はCodePipelineのコンソールではビルド中と表示されていた。
  2. メンション欲しいかも
    • CodePipelineの手動承認とかと組み合わせるなら、担当者へのメンションが欲しい
7
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?