Amazon Simple Notification Service (Amazon SNS) トピックまたは AWS Lambda 関数を Amazon Simple Storage Service (Amazon S3) イベント通知にサブスクライブすると、「Unable to validate the following destination configurations (以下の送信先設定を検証できません)」というエラーが発生します。 テンプレートで S3 バケットから SNS トピックポリシーへの依存関係の設定を試みましたが、循環依存関係検証エラーが返されました。

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

したがって、リソースは次の順序で作成する必要があります。
注意: この解決方法では、例として Amazon SNS トピックを使用します。AWS Lambda 関数を使用する際にエラーが発生する場合の解決方法はこれと似ています。

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

SNS トピックを S3 イベント通知にサブスクライブする前に、適切なアクセス許可を持つトピックポリシー (AWS::SNS::TopicPolicy) を指定する必要があります。このトピックポリシーは、サブスクリプションの作成前に存在している必要があります。

「Unable to validate the following destination configurations (以下の送信先設定を検証できません)」というエラーを回避するには、以下のいずれかの方法をお試しください。

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

S3 バケットに静的な名前を付けます。その方法として、CloudFormation テンプレートで S3Bucket リソース内の BucketName プロパティに値を指定します。これにより、SNS トピックポリシーに { "Ref": "paramBucketName" } を含める必要がなくなり、SNS トピックポリシーと Amazon S3 の間に組み込まれている依存関係を削除できます。

次の 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": { "AWS": "*" },
                        "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 リソースには明示的な DependsOn 値があり、SNSTopicPolicy に設定されています。この属性では、S3Bucket リソースの前に SNSTopicPolicy を作成するテンプレートを指定します。

別の名前で S3 バケット用の同じ 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": { "AWS": "*" },
                        "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 イベント通知が設定されることを避けられます。

最初のステージでは、次の例に示すように、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": { "AWS": "*" },
                            "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"
            }
        }
    }
}

次に、以下の例に示すように、スタックを更新して 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": { "AWS": "*" },
                        "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"
                    }
                ]
            }
        }
    }
  }
}

詳細については、「スタックの操作」を参照してください。

注意: YAML CloudFormation テンプレートを使用するには、JSON 形式と YAML 形式の間で AWS CloudFormation テンプレートを変換するためのツールに関する記事を参照してください。


このページは役に立ちましたか? はい | いいえ

AWS サポート ナレッジ センターに戻る

サポートが必要ですか? AWS サポートセンターをご覧ください。

公開日: 2016 年 09 月 15 日

更新: 2018 年 11 月 02 日