CloudFormationスタックの失敗を整形して通知する
最近CloudFormationスタックの失敗を通知する仕組みが欲しいなーと思ったので、CloudFormationでサクッと通知できるテンプレートを作成しました。
できるようになること
スタックの作成や更新、失敗が失敗するとこんなメールを通知できます。
構成
EventBridgeでCloudFormationスタックの失敗イベントを取得。インプットトランスフォーマーで整形してSNS経由でメール通知します。
CloudFormationテンプレート
通知の構成を一発で作成できるCloudFormationテンプレートです。パラメータに通知先としたメールアドレスを入力すれば使えます。
AWSTemplateFormatVersion: 2010-09-09 Description: CloudFormation Stack Failed Notification Parameters: NotificationTarget: Description: Email for notification Type: String Resources: # アラーム検出・通知用のリソース ## SNSトピック SnsTopic: Type: AWS::SNS::Topic Properties: TopicName: cfn-failed-notification-topic Subscription: - Endpoint: !Ref NotificationTarget Protocol: email ## SNSトピックポリシー EventTopicPolicy: Type: AWS::SNS::TopicPolicy Properties: PolicyDocument: Statement: - Effect: "Allow" Principal: Service: "events.amazonaws.com" Action: "sns:Publish" Resource: "*" Topics: - !Ref SnsTopic ## EventBridge AlarmEvent: Type: AWS::Events::Rule Properties: Description: "Get CloudFormation failures" EventPattern: !Sub | { "source": ["aws.cloudformation"], "detail-type": ["CloudFormation Stack Status Change"], "detail": { "status-details": { "status": ["CREATE_FAILED", "UPDATE_FAILED", "DELETE_FAILED","ROLLBACK_COMPLETE","ROLLBACK_FAILED"] } } } Targets: - Arn: !Ref SnsTopic Id: sns-topic InputTransformer: InputPathsMap: { "account": "$.account", "detail-type": "$.detail-type", "region": "$.region", "stack-id": "$.detail.stack-id", "status": "$.detail.status-details.status", "time": "$.time", } InputTemplate: | "CloudFormationスタックでエラーが発生しました。" "アカウント: <account>" "時間: <time>" "リージョン: <region>" "スタックID: <stack-id>" "ステータス: <status>" "コンソールURL: https://<region>.console.aws.amazon.com/cloudformation/home?#/stack/detail?stackId=<stack-id>"
動作確認
上記のCloudFormationテンプレートをデプロイします。入力したメールアドレスにサブスクリプションの承認メールが届きますので承諾してください。
動作確認のため、わざと失敗するCloudFormationスタックを作成してみます。
スタックの失敗オプションをデフォルト(すべてのスタックリソースをロールバックする)にした状態であれば、ステータスがROLLBACK_COMPLETEとなることが確認できます。
するとメールに通知が届き、アカウントIDやステータス、コンソールURL等が確認できました。
EventBridgeの実装詳細
CloudFormationで作成している以下を少し解説します。
## EventBridge AlarmEvent: Type: AWS::Events::Rule Properties: Description: "Get CloudFormation failures" EventPattern: !Sub | { "source": ["aws.cloudformation"], "detail-type": ["CloudFormation Stack Status Change"], "detail": { "status-details": { "status": ["CREATE_FAILED", "UPDATE_FAILED", "DELETE_FAILED","ROLLBACK_COMPLETE","ROLLBACK_FAILED"] } } } Targets: - Arn: !Ref SnsTopic Id: sns-topic InputTransformer: InputPathsMap: { "account": "$.account", "detail-type": "$.detail-type", "region": "$.region", "stack-id": "$.detail.stack-id", "status": "$.detail.status-details.status", "time": "$.time", } InputTemplate: | "CloudFormationスタックでエラーが発生しました。" "アカウント: <account>" "時間: <time>" "リージョン: <region>" "スタックID: <stack-id>" "ステータス: <status>" "コンソールURL: https://<region>.console.aws.amazon.com/cloudformation/home?#/stack/detail?stackId=<stack-id>"
Event Ruleのイベントパターン
CloudFormationスタックのステータスを以下のイベントパターンで取得しています。
{ "source": ["aws.cloudformation"], "detail-type": ["CloudFormation Stack Status Change"], "detail": { "status-details": { "status": ["CREATE_FAILED", "UPDATE_FAILED", "DELETE_FAILED","ROLLBACK_COMPLETE","ROLLBACK_FAILED"] } } }
取得したいステータスは「スタックが失敗」した時なので、失敗を表すステータスを対象としています。
CloudFormationスタックのステータスコード詳細は以下ドキュメント参照。
スタックの情報とリストの取得 - AWS CloudFormation
スタックのステータスはデプロイ時のオプションで変わります。選択できるのは「すべてのスタックリソースをロールバックする」と「正常にプロビジョニングされたリソースの保持」となっており、このオプションによって最終的なスタックのステータスが変わります。
デフォルトの動作であるロールバックでは最終的なスタックのステータスはROLLBACK_COMPLETE
かROLLBACK_FAILED
。
リソースの保持を設定していれば、作成やアップデート時の失敗でスタックが止まるためCREATE_FAILED
やUPDATE_FAILED
を取得する必要があります。他に拾いたいステータスがあれば、お好みで追加してください。
入力トランスフォーマー
メッセージの整形はEvent Rule内の入力トランスフォーマーで行っています。個人的に必要な情報を入れましたが、こちらもお好みで変更ください。サンプルイベントを載せておきます。
サンプルイベント
{ "version": "0", "source": "aws.cloudformation", "account": "123456789012", "id": "12345678-1234-1234-1234-111122223333", "region": "us-east-1", "detail-type": "CloudFormation Stack Status Change", "time": "2022-04-31T17:00:00Z", "resources": ["arn:aws:cloudformation:us-east-1:123456789012:stack/teststack"], "detail": { "stack-id": "arn:aws:cloudformation:us-west-1:123456789012:stack/teststack", "status-details": { "status": "CREATE_COMPLETE", "status-reason": "" } } }
まとめ
CloudFormationスタックの失敗を入力トランスフォーマーで整形して通知してみました。とりあえずスタックの失敗を通知したい時にはご利用頂ければ幸いです。