CodeBuildの実行結果をLambda(Go)でSlackに通知する
目的
AWS CodeBuildの実行結果をLambdaを使ってSlackに通知するようにしました。
前回のブログで、CodeBuildでMackerelの監視設定の最新を取得し、GitHubにpushする処理を行いました。
今回はそのCodeBuildの処理結果をSlackに通知するように CloudWatch Eventの設定 と Lambda Functionの実装について〜。
アーキテクチャについて
- CodeBuildで処理が実行されるとCloudWatchにログが出力される
- CloudWatch Eventルールに定義したログが出力されたらLambda関数を起動する
- Lambda関数でSlackにCodeBuildのプロジェクト名と実行ステータスを通知する
実装について
Lambda関数とCloudWatchEventの作成
今回はServerlessFrameworkでリソース作成・デプロイを行いました。
■ serverless.yml
service: slack-notice frameworkVersion: ">=1.48.0" provider: name: aws runtime: go1.x stage: dev region: ap-northeast-1 functions: codebuild: handler: main role: codebuildSlack timeout: 30 description: codebuild status slack memorySize: 128 environment: SLACKURL: ${opt:slackurl} events: - cloudwatchEvent: event: source: - 'aws.codebuild' detail-type: - 'CodeBuild Build State Change' detail: build-status: - FAILED - STOPPED - SUCCEEDED - IN_PROGRESS resources: Resources: codebuildSlack: Type: AWS::IAM::Role Properties: RoleName: codebuildSlack AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: sts:AssumeRole ManagedPolicyArns: - arn:aws:iam::aws:policy/ReadOnlyAccess Policies: - PolicyName: codebuildSlackLogs PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - "logs:CreateLogGroup" - "logs:CreateLogStream" - "logs:PutLogEvents" Resource: "*"
Lambda関数の実装
CloudwatchのログからCodeBuildのプロジェクト名と実行ステータスを取得してSlackに通知する処理を実装。
GoでSlackに通知する方法は、以前のブログに記載しています。
実行環境について
- Lambdaのランタイムは
go1.x
- Goのバージョンは:
1.12.4
- Lambdaのランタイムは
CodeBuildの情報 ( プロジェクト名とステータス ) を取得するために構造体を確認
■ main.go
package main import ( "encoding/json" "fmt" "os" "github.com/ashwanthkumar/slack-go-webhook" "github.com/aws/aws-lambda-go/events" "github.com/aws/aws-lambda-go/lambda" ) const version = "0.0.1" var ( // CHANNEL slack channel name CHANNEL = "dev" // USERNAME slack username USERNAME = "CodeBuild" // SLACKURL slack webhook SLACKURL = os.Getenv("SLACKURL") ) // CodeBuildPhaseStatus set status type CodeBuildPhaseStatus string // CodeBuildEventDetail set event detail type CodeBuildEventDetail struct { BuildStatus CodeBuildPhaseStatus `json:"build-status"` ProjectName string `json:"project-name"` } func main() { lambda.Start(Handler) } // Handler Lambda func Handler(event events.CloudWatchEvent) { resInfo := &CodeBuildEventDetail{} err := json.Unmarshal(event.Detail, &resInfo) if err != nil { fmt.Println(err) } PostSlack(resInfo.ProjectName, string(resInfo.BuildStatus)) } func checkStatus(status string) string { var color string if status == "SUCCEEDED" { color = "#00ff00" } else if status == "IN_PROGRESS" { color = "#0000ff" } else { color = "#dc143c" } return color } // PostSlack post slack result func PostSlack(pjtName string, status string) { statusColor := checkStatus(status) field1 := slack.Field{Title: "ProjectName", Value: pjtName} field2 := slack.Field{Title: "BuildStatus", Value: status} attachment := slack.Attachment{} attachment.AddField(field1).AddField(field2) color := statusColor attachment.Color = &color payload := slack.Payload{ Username: USERNAME, Channel: CHANNEL, Attachments: []slack.Attachment{attachment}, } err := slack.Send(SLACKURL, "", payload) if err != nil { os.Exit(1) } }
Slackの通知結果
デプロイ方法
■ ソースコードはこちら github.com
■ デプロイ方法
$ make build $ sls deploy --aws-profile <PROFILE> --slackurl <SLACKURL>
→ <SLACKURL>
はSlackに通知したいチャンネルのwebhookをセットします。
今回はこの設定方法は省略しています。
まとめ
今回は、CodeBuildの実行結果をSlack通知するために、CloudwatchEventとLambda(Go)を利用して実装しました。 デプロイについてはServerlessFrameworkを利用しています。 イベント駆動でLambdaでごにょっと処理ができると便利なことが多いと思うので他の場合もLambda(Go)で書いていきたいと思います。