Codepipelineのデプロイが完了したらどのバージョンをデプロイしたのかをCFn一撃通知してみる

2019.03.01

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

梶原大使at福岡です。

Codepipelineのデプロイが完了したらCodepipelineがどのバージョンをデプロイしたのかSNS通知(メール)してみます。

さっそくですが、 つ CloudFormationテンプレート

ってことで、CFn一撃化して必要なのはメアドだけにしておきました。 テンプレートも載せていますのでカスタマイズはご自由に。

構成図はこんな感じです。

いるもの

AWSアカウント(各種権限)

各種設定

CloudWatch Events Rule

  • ソース: CodePipeline
  • イベントタイプ:CodePipelineの状態変更
  • 状態: 成功 or 失敗
CodePipelineCwEventsRule:
Type: AWS::Events::Rule
Properties:
EventPattern:
source:
- aws.codepipeline
detail-type:
- CodePipeline Pipeline Execution State Change
detail:
state:
- SUCCEEDED
- FAILED
State: ENABLED
Targets:
- Id: "CodePipelineGetExecutionLambda"
Arn: !GetAtt CodePipelineGetExecutionFunction.Arn

成功、失敗以外に欲しい状態があれば、stateに追加してください。

Lambdaでやっている事

  1. イベント通知からパイプライン名、実行IDを取得
  2. デプロイの詳細情報を取得(getPipelineExecution)
  3. デプロイの詳細情報をSNS通知

特に迷うところはないかと。

ちょっと注意

コンソールで設定した場合はよしなにやってくれるのですが CloudFormationの場合はEventsからLambdaを呼び出すので Lambda側に許可設定を実施します

LambdaInvokePermission:
Type: AWS::Lambda::Permission
Properties:
FunctionName: !GetAtt CodePipelineGetExecutionFunction.Arn
Action: lambda:InvokeFunction
Principal: events.amazonaws.com
SourceArn: !GetAtt CodePipelineCwEventsRule.Arn

やってみる

CloudFormationの実行

最後のテンプレートをCloudFormationで実行してください。

CodepipeLineの実行

Codepipelineの実行が成功/失敗すると下記のようなメールが通知されます。 まんま、getPipelineExecutionの中身になりますが

見るべきところは

  • pipelineName:パイプライン名
  • status: デプロイ結果正常終了時はSucceeded, 失敗時はFailed
  • revisionId: githbuやCodecommitの場合はコミットのハッシュ値
  • revisionSummary: githubやCodecommitの場合はコミット時のコメント
  • revisionUrl: 何気にコミット時の差異がみれるので便利かも? (前回のデプロイの差異とかではなくあくまでコミット時の差分です)

になります。

件名:CodePipeline Execution Succeeded

{
"pipelineExecution": {
"pipelineName": "temp-pipeline-hogehoge",
"pipelineVersion": 1,
"pipelineExecutionId": "XXXX-YYYY-ZZZ-1111-XXXXX",
"status": "Succeeded",
"artifactRevisions": [
{
"name": "SourceArtifact",
"revisionId": "XXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"revisionSummary": "update hoge\n",
"revisionUrl": "https://ap-northeast-1.console.aws.amazon.com/codecommit/home#/repository/repo/commit/XXXXXXXXXXXXXXXXX"
}
]
}
}

まとめ

Pipeline Execution State Changeの通知だけでも失敗、成功は判別できますが どのリビジョンがデプロイされたか知りたかったので作ってみました。 どなたかの役に立てば幸いです。

テンプレート全体

AWSTemplateFormatVersion: '2010-09-09'
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
- Label:
default: "SNS Settings"
Parameters:
- EMailAddress
ParameterLabels:
EMailAddress:
default: "E-Mail Address"
Parameters:
EMailAddress:
Type: String
Default: hogefuga@exsample.com

Resources:

EMailSNSTopic:
Type: AWS::SNS::Topic
Properties:
Subscription:
- Endpoint: !Ref EMailAddress
Protocol: email

CodePipelineCwEventsRule:
Type: AWS::Events::Rule
Properties:
EventPattern:
source:
- aws.codepipeline
detail-type:
- CodePipeline Pipeline Execution State Change
detail:
state:
- SUCCEEDED
- FAILED
State: ENABLED
Targets:
- Id: "CodePipelineGetExecutionLambda"
Arn: !GetAtt CodePipelineGetExecutionFunction.Arn

CodePipelineGetExecutionFunction:
Type: AWS::Lambda::Function
Properties:
Handler: index.handler
Role: !GetAtt LambdaExecutionRole.Arn
Environment:
Variables:
SNS_TOPIC_ARN: !Ref EMailSNSTopic
Code:
ZipFile: !Sub |
var AWS = require('aws-sdk');
var SNS_TOPIC_ARN = process.env.SNS_TOPIC_ARN;
exports.handler = async(event) => {
// console.log(JSON.stringify(event, null, 4));
var codepipeline = new AWS.CodePipeline();
var sns = new AWS.SNS();
var params = {
pipelineExecutionId: event.detail['execution-id'],
pipelineName: event.detail.pipeline
};
var pipelineExecution = await codepipeline.getPipelineExecution(params).promise();
// console.log(JSON.stringify(pipelineExecution, null, 4));
params = {
Message: JSON.stringify(pipelineExecution, null, 4),
Subject: 'CodePipeline Execution ' + pipelineExecution.pipelineExecution.status,
TopicArn: SNS_TOPIC_ARN
};
var result = await sns.publish(params).promise();
return result;
};
Runtime: nodejs8.10
Timeout: 30

LambdaExecutionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
- arn:aws:iam::aws:policy/AWSCodePipelineReadOnlyAccess
Path: "/"
Policies:
- PolicyName: LambdaExecutionRole-SnsPublishPolicy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- sns:Publish
Resource: arn:aws:sns:*:*:*

LambdaInvokePermission:
Type: AWS::Lambda::Permission
Properties:
FunctionName: !GetAtt CodePipelineGetExecutionFunction.Arn
Action: lambda:InvokeFunction
Principal: events.amazonaws.com
SourceArn: !GetAtt CodePipelineCwEventsRule.Arn