AWS

【AWS】CodePipelineからの通知が来ないとき

今回はCodePipelineの通知ルール作成におけるハマりどころについて。

CodePipelineに限らず、開発者用ツールではそれぞれ通知ルールを作成することができ、状態変化などをトリガーにしてAmazon SNSやAWS Chatbotへの通知が可能です。

私もCodePipelineの実行結果(成功/失敗)の通知を受け取るべく、設定を行っていたところ「通知、こねえじゃねーか・・・」 という状況に陥りました。

CodePipelineからの通知設定は初めてじゃなかったのですが、なかなかハマりました。。

先に結論

「Amazon SNSトピックは、CodePipelineの通知ルール作成画面の中で作成すべし。」

当初、事前にAmazon SNSトピックを作成しておいて、CodePipelineの通知ルール作成時にターゲットとして指定する流れで作業していました。
しかし、この方法だとCodePipelineの通知ターゲットが「到達できない」のステータス表示になり上手くいかないことがあるようです。

原因はAmazon SNSトピック側のアクセスポリシーにあるようで、プリンシパルを”codestar-notifications.amazonaws.com” とするポリシーの記述がない点が根本の原因となります。

なので、正しい対応といては「Amazon SNSトピックのアクセスポリシーを整備する」となるのですが、、手っ取り早く回避方法として、前述の「Amazon SNSトピックの作成はCodePipelineの通知ルール作成画面の中で行う」という結論に至りました。

CodePipelineの通知ルール作成画面でAmazon SNSトピックを作成することで(アクセスポリシーが正しく設定され)、CodePipelineの通知ターゲットステータスが「有効」となり、想定通りの通知を飛ばすことができました。

今回お伝えしたかったことはこれが全てですが(笑)、せっかくなので以下に、調査内容や経緯について簡単に記載します。

通知が飛ばない原因を調べる

今回の通知処理は次の流れで構築しました。
[CodePipelineの通知]
 → [Amazon SNS]
  → [AWS Lambda]
   → [Microsoft Teams]

ゴールであるMicrosoft Teamsへの通知が来ていない原因を探すため、AWS LambdaやAmazon SNSのログなどを確認するも履歴なし。
そもそもCodePipelineからの通知が飛んでない状態だったので、改めて通知ルールを確認。

すると、通知ターゲットステータスには「到達できない」と表示されている。

明らかにこいつが原因だな、と思いつつ、その到達できない理由がわからなかった。

ターゲットとなるAmazon SNSのトピックは特に問題無さそうで、対象トピックでサブスクライブしているAWS Lambdaもステータス「確認済み」となっており正常値。

  • CodePipeline通知ルールの再作成
  • Amazon SNSトピックの再作成
  • CodePipeline通知ターゲットの再設定

無駄に色々試したが、結局いつもどおり答えは公式ドキュメントの中に。。

参照した公式ドキュメント

探すのに若干時間かかりましたが公式ドキュメントに関連記述(答え)がありました。
公式ドキュメントにある『通知を設定する最も簡単な方法は、通知ルールを作成するときに Amazon SNS トピックを作成することです。』の記述が、冒頭の結論とイコールです。

  • トラブルシューティング

    →ポイント: 通知に必要なポリシーが Amazon SNS トピックに存在しない。

    Q: 通知ターゲットのステータスが到達不能と表示される理由を教えてください

    A: ターゲットのステータスには、[アクティブ] と [到達不能] の 2 つがあります。[到達不能] は、ターゲットに送信された通知が未到着であることを示します。通知はそのターゲットに引き続き送信され、到着すると、ステータスが [アクティブ] にリセットされます。

    通知ルールのターゲットは、次のいずれかの理由で使用不能になる場合があります。

    ・リソース (Amazon SNS トピックまたは AWS Chatbotクライアント)が削除された。通知ルールの別のターゲットを選択した。
    ・Amazon SNS トピックが暗号化されており、暗号化されたトピックに必要なポリシーが見つからないか、AWS KMS キーが削除されている。詳細については、「通知の Amazon SNS トピックの設定」を参照してください。
    ・通知に必要なポリシーが Amazon SNS トピックに存在しない。トピックにポリシーがない場合、通知を Amazon SNS トピックに送信することはできません。詳細については、「通知の Amazon SNSトピックの設定」を参照してください。
    ・ターゲット (Amazon SNS または AWS Chatbot) のサポートサービスに問題が発生している可能性がある。

  • 通知の Amazon SNS トピックの設定

    →ポイント: 通知を設定する最も簡単な方法は、通知ルールを作成するときに Amazon SNS トピックを作成することです

    通知を設定する最も簡単な方法は、通知ルールを作成するときに Amazon SNS トピックを作成することです。 以下の要件を満たしている場合は、既存の Amazon SNS トピックを使用できます。

    ・通知ルールを作成する対象のリソース(ビルドプロジェクト、デプロイアプリケーション、リポジトリ、またはパイプライン)と同じ AWS リージョンに作成されています。
    ・2019 年 11 月 5 日より前の CodeCommitの通知を送信するためには使用されていません。使用している場合は、その機能を有効にしたポリシーステートメントが含まれます。このトピックを使用することもできますが、手順で指定されているように、追加のポリシーを追加する必要があります。2019 年 11 月 5 日より前に通知用に 1 つ以上のリポジトリーが設定されている場合は、既存のポリシーステートメントを削除しないでください。
    ・トピックに通知を発行することを AWS CodeStar Notifications に許可するポリシーがあります。

    AWS CodeStar Notifications 通知ルールのターゲットとして使用する Amazon SNS トピックを設定するには、SNSトピックのアクセスポリシーに以下のステートメントを追加する。

    	{
          "Sid": "AWSCodeStarNotifications_publish",
          "Effect": "Allow",
          "Principal": {
            "Service": [
              "codestar-notifications.amazonaws.com"
            ]
          },
          "Action": "SNS:Publish",
          "Resource": "arn:aws:sns:us-east-2:123456789012:codestar-notifications-MyTopicForNotificationRules"
        }
    

    Amazon SNSトピックのアクセスポリシーを比較する

    参考までに、Amazon SNSトピックのアクセスポリシーを載せておきます。

    • OKパターン(CodePipeline通知ルール作成画面からSNSトピック作成した場合)
    • NGパターン(SNSコンソールからSNSトピック作成した場合)

    OKパターン(CodePipeline通知ルール作成画面からSNSトピック作成した場合)

    {
      "Version": "2008-10-17",
      "Statement": [
        {
          "Sid": "CodeNotification_publish",
          "Effect": "Allow",
          "Principal": {
            "Service": "codestar-notifications.amazonaws.com"
          },
          "Action": "SNS:Publish",
          "Resource": "arn:aws:sns:ap-northeast-1::"
        }
      ]
    }
    

    NGパターン(SNSコンソールからSNSトピック作成した場合)

    {
      "Version": "2008-10-17",
      "Id": "__default_policy_ID",
      "Statement": [
        {
          "Sid": "__default_statement_ID",
          "Effect": "Allow",
          "Principal": {
            "AWS": "*"
          },
          "Action": [
            "SNS:GetTopicAttributes",
            "SNS:SetTopicAttributes",
            "SNS:AddPermission",
            "SNS:RemovePermission",
            "SNS:DeleteTopic",
            "SNS:Subscribe",
            "SNS:ListSubscriptionsByTopic",
            "SNS:Publish",
            "SNS:Receive"
          ],
          "Resource": "arn:aws:sns:ap-northeast-1::",
          "Condition": {
            "StringEquals": {
              "AWS:SourceOwner": "120664262713"
            }
          }
        }
      ]
    }
    

    参考

    余談

    社内ではMicrosoft Teamsを利用しているので試してないのですが、開発者用ツールの通知はAWS Chatbotを利用してSlackへの通知もできるようなので検証してみたい。
    個人的にはSlackの方が圧倒的に使いやすいので。。

    以上です。最後まで読んでいただきありがとうございました。