CodePipelineでエラー発生時にSNSでメール通知する
AWS DVAの出題範囲の1つでもある、モニタリング・トラブルシューティングに関する内容です。
CodePipelineでCI/CD環境においてエラーが発生した際の通知方法について考えます。
AWS公式では、通知方法について以下の通りに説明されています。
You can set up notifications so that users of a resource, such as a build project, repository, deployment application, or pipeline, receive emails about the event types you specify according to the notification rule you create.
Notification concepts
本ページではこの通知ルールを使用して、パイプライン上で発生したエラーメッセージを、SNSを通じてメール通知する方法をご紹介します。
構築する環境
基本的な構成は、以下のページでご紹介したものと同様です。
これはCodePipelineを使用したCloudFormation用のCI/CD環境です。
本ページにおける変更点は、以下の2点です。
1点目はCodePipelineに通知ルールを設定する点です。
ルールは、パイプライン上で発生し得るエラー情報を通知するものです。
2点目は通知ルールの通知先に関する設定です。
内容をSNSを通じてメール通知します。
今回はテストスタック作成に、意図的に失敗を発生させます。
パイプラインのそれ以降のアクション・ステージには進みません。
失敗を受けて、通知ルールに従って、SNS経由でメールが通知されます。
CloudFormationテンプレートファイル
上記の構成をCloudFormationで構築します。
以下のURLにCloudFormationテンプレートを配置しています。
https://github.com/awstut-an-r/awstut-dva/tree/main/05/002
テンプレートファイルのポイント解説
本ページでは、CodePipelineにおける通知ルールに関する内容を中心に取り上げます。
それ以外の内容については、冒頭のページをご確認ください。
通知ルール
Resources:
NotificationRule:
Type: AWS::CodeStarNotifications::NotificationRule
Properties:
DetailType: BASIC
EventTypeIds:
- codepipeline-pipeline-action-execution-failed
- codepipeline-pipeline-stage-execution-failed
- codepipeline-pipeline-pipeline-execution-failed
- codepipeline-pipeline-manual-approval-failed
Name: !Sub "${Prefix}-NotificationRule"
Resource: !Sub "arn:aws:codepipeline:${AWS::Region}:${AWS::AccountId}:${Pipeline}"
Status: ENABLED
Targets:
- TargetAddress: !Ref TopicArn
TargetType: SNS
Code language: YAML (yaml)
通知ルールを作成する上でのポイントは3点です。
1点目は通知元です。
ResourceプロパティにCodePipelineのARNを指定します。
2点目は通知先です。
TargetsプロパティにSNSトピックのARN等を指定します。
3点目は通知するイベントに関する情報です。
EventTypeIdsプロパティに通知するイベントのIDを指定します。
通知可能なイベントですが、以下のAWS公式ページでまとめられています。
https://docs.aws.amazon.com/dtconsole/latest/userguide/concepts.html
今回はCodePipelineに関する4つのFailed通知を指定します。
SNS
トピック
Resources:
Topic:
Type: AWS::SNS::Topic
Properties:
Subscription:
- Endpoint: !Ref MailAddress
Protocol: email
TopicName: !Ref Prefix
Code language: YAML (yaml)
特別な設定は不要です。
サブスクライバーにメールアドレスを指定します。
アクセスポリシー
Resources:
TopicPolicy:
Type: AWS::SNS::TopicPolicy
Properties:
PolicyDocument:
Statement:
- Principal:
Service: codestar-notifications.amazonaws.com
Action: sns:Publish
Effect: Allow
Resource: !Ref TopicArn
Condition:
StringEquals:
aws:SourceAccount: !Ref AWS::AccountId
Topics:
- !Ref TopicArn
Code language: YAML (yaml)
通知先にSNSを指定する場合に、重要なポイントはSNSのアクセスポリシーです。
以下のAWS公式ページに従い、アクセスポリシーを設定します。
https://docs.aws.amazon.com/dtconsole/latest/userguide/set-up-sns.html
上記の通り、プリンシパルにCodeStarを指定した上で、「sns:Publish」を許可します。
CloudFormation関係のファイル
CodePipeline内のCloudFormationを実行するためのファイルを確認します。
テンプレートファイル
AWSTemplateFormatVersion: 2010-09-09
Parameters:
Prefix:
Type: String
Default: dva-05-002-sample-lambda
Environment:
Type: String
Default: test
Handler:
Type: String
Default: index.lambda_handler
MemorySize:
Type: Number
Default: 128
Runtime:
Type: String
Default: python3.8
Timeout:
Type: Number
Default: 5
Resources:
Function:
Type: AWS::Lambda::Function
Properties:
Code:
ZipFile: |
def lambda_handler(event, context):
print('sample lambda')
FunctionName: !Sub "${Prefix}-${Environment}-Function"
Handler: !Ref Handler
MemorySize: !Ref MemorySize
Runtime: !Ref Runtime
Role: !GetAtt LambdaRole.Arn
LambdaRole:
Type: AWS::IAM::Role
DeletionPolicy: Delete
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: sts:AssumeRole
Principal:
Service:
- lambda.amazonaws.com
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Code language: YAML (yaml)
Lambda関数およびIAMロールを定義します。
関数名(FunctionName)とメモリサイズ(MemorySize)がポイントです。
それぞれパラメータを埋め込む形で指定しますが、これらの値は後述のテンプレート設定ファイルによって、テストスタック・本番スタックで異なる値を設定します。
テストスタック用テンプレート設定ファイル
{
"Parameters" : {
"Environment": "test",
"MemorySize": "0"
}
}
Code language: JSON / JSON with Comments (json)
メモリサイズの値がポイントです。
あえて0 (MB)を指定します。
これでスタック作成時に失敗させます。
環境構築
CloudFormationを使用して、本環境を構築し、実際の挙動を確認します。
CloudFormationスタックを作成する
CloudFormationスタックを作成します。
スタックの作成および各スタックの確認方法については、以下のページをご確認ください。
各スタックのリソースを確認した結果、今回作成された主要リソースの情報は以下の通りです。
- SNSトピック:fa-117
- CodeCommit:dva-05-002
- CodePipeline:dva-05-002
メールアドレスの認証
SNSトピックのサブスクライバーとしてメールアドレスを指定した場合、そのメールアドレスを認証する必要があります。
指定したメールアドレスに、以下のような認証メールが送られてきます。
「Confirm subscription」を押下して、認証を進めます。
上記のページが表示されて、認証が完了したことがわかります。
リソース確認
AWS Management Consoleから各リソースを確認します。
まずSNSトピックを確認します。
SNSトピックのサブスクライバーとして、メールアドレスが指定されています。
CodePipelineを確認します。
パイプラインの実行に失敗しています。
これはCloudFormationスタック作成時に、CodeCommitが作成されたことがきっかけとして、パイプラインが実行されたためです。
現時点ではCodeCommitにコードをプッシュしていないため、パイプライン実行の過程でエラーが発生しました。
通知ルールを確認します。
確かに通知ルールが作成されています。
通知先に先述のSNSトピックが指定されており、有効化されていることがわかります。
つまりCodeStarがSNSトピックに対して、メッセージを通知する権限が適切に設定されているということです。
詳細も確認します。
CodePipelineに関するFailed通知を送信する内容です。
動作確認
準備が整いましたので、CodeCommitにコードをプッシュします。
$ git clone https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/dva-05-002
Cloning into 'dva-05-002'...
warning: You appear to have cloned an empty repository.
Code language: Bash (bash)
空のリポジトリがプルされました。
リポジトリに3つのファイル(sample-lambda.yaml、test-stack-configuration.json、prod-stack-configuration.json)を加えます。
$ ls -al
total 12
drwxrwxr-x 3 ec2-user ec2-user 118 Jan 22 11:31 .
drwxrwxr-x 4 ec2-user ec2-user 151 Jan 22 11:31 ..
drwxrwxr-x 7 ec2-user ec2-user 119 Jan 22 11:31 .git
-rw-rw-r-- 1 ec2-user ec2-user 98 Jan 18 12:43 prod-stack-configuration.json
-rw-rw-r-- 1 ec2-user ec2-user 1667 Jan 18 11:40 sample-lambda.yaml
-rw-rw-r-- 1 ec2-user ec2-user 95 Jan 21 11:55 test-stack-configuration.json
Code language: Bash (bash)
3ファイルをプッシュします。
$ git add .
$ git commit -m 'first commit'
...
create mode 100644 prod-stack-configuration.json
create mode 100644 sample-lambda.yaml
create mode 100644 test-stack-configuration.json
$ git push
...
* [new branch] master -> master
Code language: Bash (bash)
正常にプッシュできました。
これでパイプラインが開始されました。
しばらく待つと、パイプラインが途中が失敗します。
テストスタックの作成に失敗しています。
先述の通り、Lambda関数のメモリサイズを「0」としたことが原因です。
すぐに以下にメールが届きました。
メールは3件届きました。
Pipeline execution、Stage execution、Action executionに関するエラーが発生した旨が記されています。
CloudFormationスタックも確認します。
確かにテストスタックの作成に失敗しています。
このように通知ルールを作成し、その通知先にSNSトピックを指定することによって、CodePipeline実行時のエラーをメール通知することができました。
まとめ
CodePipelineでエラー発生時にSNSでメール通知する方法をご紹介しました。