AWS CloudFormation で「次の送信先設定を検証できません」というエラーを回避するにはどうすればよいですか?

所要時間3分
0

Amazon Simple Notification Service (Amazon SNS) トピックまたは AWS Lambda 関数を Amazon Simple Storage Service (Amazon S3) イベント通知に登録します。「次の送信先設定を検証できません」というエラーが表示されます。 テンプレートの S3 バケットから SNS トピックポリシーへの依存関係を設定しようとすると、循環依存関係の検証エラーが発生します。

簡単な説明

AWS CloudFormation が依存関係の順序を処理する方法により、Amazon S3 イベント通知は S3 バケットの属性として定義されます。これらの通知は、S3 バケットリソースの作成時に確立されます。

エラーを回避するには、次の順でリソースを作成する必要があります。

  1. S3 バケットが SNS トピックを参照するため、SNS トピックを作成します
  2. SNS トピックポリシーは S3 バケットと SNS トピックの両方を参照するため、S3 バケットを作成します

SNS トピックを S3 イベント通知に登録する前に、適切なアクセス許可のあるトピックポリシー (AWS::SNS::TopicPolicy) を指定する必要があります。そのトピックポリシーが登録する前に存在している必要があります。

「次の送信先設定を検証できません」というエラーを回避するには、次のいずれかの方法をお試しください。

  • AWS CloudFormation テンプレートで BucketName の値を指定する
  • スタックを作成し、スタック更新を実行する

解決方法

AWS CloudFormation テンプレートで BucketName の値を指定する

AWS CloudFormation テンプレートの S3Bucket リソースで BucketName プロパティの値を指定して、S3 バケットに静的な名前を使用します。これにより、SNS トピックポリシーに {"Ref": "paramBucketName"} を含めなくて済みます。SNS トピックポリシーと Amazon S3 の間の固有の依存関係が削除されます。

次の AWS CloudFormation テンプレートの例では、BucketName プロパティにハードコードされた値 (-Bucket-Name-) を指定します。テンプレートで -Bucket-Name- のすべてのインスタンスをバケット名に置き換えます。

{
  "Resources": {
    "SNSTopic": {
      "Type": "AWS::SNS::Topic"
    },
    "SNSTopicPolicy": {
      "Type": "AWS::SNS::TopicPolicy",
      "Properties": {
        "PolicyDocument": {
          "Id": "MyTopicPolicy",
          "Version": "2012-10-17",
          "Statement": [
            {
              "Sid": "Statement-id",
              "Effect": "Allow",
              "Principal": {
                "Service": "s3.amazonaws.com"
              },
              "Action": "sns:Publish",
              "Resource": {
                "Ref": "SNSTopic"
              },
              "Condition": {
                "ArnLike": {
                  "aws:SourceArn": {
                    "Fn::Join": [
                      "",
                      [
                        "arn:aws:s3:::",
                        "-Bucket-Name-"
                      ]
                    ]
                  }
                }
              }
            }
          ]
        },
        "Topics": [
          {
            "Ref": "SNSTopic"
          }
        ]
      }
    },
    "S3Bucket": {
      "Type": "AWS::S3::Bucket",
      "DependsOn": [
        "SNSTopicPolicy"
      ],
      "Properties": {
        "AccessControl": "BucketOwnerFullControl",
        "BucketName": "-Bucket-Name-",
        "NotificationConfiguration": {
          "TopicConfigurations": [
            {
              "Topic": {
                "Ref": "SNSTopic"
              },
              "Event": "s3:ObjectCreated:Put"
            }
          ]
        }
      }
    }
  }
}

注意: S3Bucket リソースには、SNSTopicPolicy に設定されている明示的な DependsOn 値があります。この属性は、テンプレートが S3Bucket リソースの前に SNSTopicPolicy リソースを作成するように指定します。

S3 バケットで同じ AWS CloudFormation テンプレートを異なる名前で使用するには、バケット名にパラメータを定義します。パラメータを使用すると、スタックの作成時にバケット名をパラメータとして渡すことによって、異なるバケット名に同じテンプレートを使用できます。

次のサンプルテンプレートを使用するには、スタックの作成時に paramBucketName パラメータとしてバケット名を渡す必要があります。

{
  "Parameters": {
    "paramBucketName": {
      "Type": "String",
      "Description": "Bucket Name"
    }
  },
  "Resources": {
    "SNSTopic": {
      "Type": "AWS::SNS::Topic"
    },
    "SNSTopicPolicy": {
      "Type": "AWS::SNS::TopicPolicy",
      "Properties": {
        "PolicyDocument": {
          "Id": "MyTopicPolicy",
          "Version": "2012-10-17",
          "Statement": [
            {
              "Sid": "Statement-id",
              "Effect": "Allow",
              "Principal": {
                "Service": "s3.amazonaws.com"
              },
              "Action": "sns:Publish",
              "Resource": {
                "Ref": "SNSTopic"
              },
              "Condition": {
                "ArnLike": {
                  "aws:SourceArn": {
                    "Fn::Join": [
                      "",
                      [
                        "arn:aws:s3:::",
                        {
                          "Ref": "paramBucketName"
                        }
                      ]
                    ]
                  }
                }
              }
            }
          ]
        },
        "Topics": [
          {
            "Ref": "SNSTopic"
          }
        ]
      }
    },
    "S3Bucket": {
      "Type": "AWS::S3::Bucket",
      "DependsOn": [
        "SNSTopicPolicy"
      ],
      "Properties": {
        "AccessControl": "BucketOwnerFullControl",
        "BucketName": {
          "Ref": "paramBucketName"
        },
        "NotificationConfiguration": {
          "TopicConfigurations": [
            {
              "Topic": {
                "Ref": "SNSTopic"
              },
              "Event": "s3:ObjectCreated:Put"
            }
          ]
        }
      }
    }
  }
}

スタックを作成し、スタック更新を実行する

スタックの作成を 2 つのステージに分割します。まず、スタックを作成します。ただし、S3Bucket リソースで NotificationConfiguration プロパティを指定してはいけません。次に、スタックの更新を実行して S3 イベント通知を追加します。これにより、SNS トピックポリシーが作成される前に S3 イベント通知が設定されることを防ぐことができます。

1.    SNS トピックポリシーを含むすべてのリソースを作成します。以下はその例です。

{
  "Resources": {
    "SNSTopic": {
      "Type": "AWS::SNS::Topic"
    },
    "SNSTopicPolicy": {
      "Type": "AWS::SNS::TopicPolicy",
      "Properties": {
        "PolicyDocument": {
          "Id": "MyTopicPolicy",
          "Version": "2012-10-17",
          "Statement": [
            {
              "Sid": "Statement-id",
              "Effect": "Allow",
              "Principal": {
                "Service": "s3.amazonaws.com"
              },
              "Action": "sns:Publish",
              "Resource": {
                "Ref": "SNSTopic"
              },
              "Condition": {
                "ArnLike": {
                  "aws:SourceArn": {
                    "Fn::Join": [
                      "",
                      [
                        "arn:aws:s3:::",
                        {
                          "Ref": "S3Bucket"
                        }
                      ]
                    ]
                  }
                }
              }
            }
          ]
        },
        "Topics": [
          {
            "Ref": "SNSTopic"
          }
        ]
      }
    },
    "S3Bucket": {
      "Type": "AWS::S3::Bucket",
      "Properties": {
        "AccessControl": "BucketOwnerFullControl"
      }
    }
  }
}

2.    スタックを更新して S3 イベント通知を追加します。例:

{
  "Resources": {
    "SNSTopic": {
      "Type": "AWS::SNS::Topic"
    },
    "SNSTopicPolicy": {
      "Type": "AWS::SNS::TopicPolicy",
      "Properties": {
        "PolicyDocument": {
          "Id": "MyTopicPolicy",
          "Version": "2012-10-17",
          "Statement": [
            {
              "Sid": "Statement-id",
              "Effect": "Allow",
              "Principal": {
                "Service": "s3.amazonaws.com"
              },
              "Action": "sns:Publish",
              "Resource": {
                "Ref": "SNSTopic"
              },
              "Condition": {
                "ArnLike": {
                  "aws:SourceArn": {
                    "Fn::Join": [
                      "",
                      [
                        "arn:aws:s3:::",
                        {
                          "Ref": "S3Bucket"
                        }
                      ]
                    ]
                  }
                }
              }
            }
          ]
        },
        "Topics": [
          {
            "Ref": "SNSTopic"
          }
        ]
      }
    },
    "S3Bucket": {
      "Type": "AWS::S3::Bucket",
      "Properties": {
        "AccessControl": "BucketOwnerFullControl",
        "NotificationConfiguration": {
          "TopicConfigurations": [
            {
              "Topic": {
                "Ref": "SNSTopic"
              },
              "Event": "s3:ObjectCreated:Put"
            }
          ]
        }
      }
    }
  }
}

注: AWS CloudFormation テンプレートフリップを使用して、AWS CloudFormation テンプレートを JSON 形式と YAML 形式の間で変換できます。


関連情報

AWS CloudFormation の Lambda イベント通知で「次の宛先設定を検証できません」エラーを解決する方法を教えてください。

AWS CloudFormation スタック更新

Amazon SNS 通知の設定

AWS公式
AWS公式更新しました 2年前
コメントはありません

関連するコンテンツ