Amazon Simple Storage Service(Amazon S3) 이벤트 알림에 대한 AWS Lambda 함수 또는 Amazon Simple Notification Service(Amazon SNS) 주제를 구독할 때 "Unable to validate the following destination configurations" 오류가 나타납니다. 내 템플릿의 S3 버킷에서 SNS 주제 정책에 종속성을 설정하려고 하면 순환 종속성 확인 오류가 나타납니다.

AWS CloudFormation이 종속성 순서를 처리하는 방식 때문에 Amazon S3 이벤트 알림은 S3 버킷의 속성으로 정의되며, S3 버킷 리소스가 생성될 때 설정됩니다.

따라서 다음 순서로 리소스를 생성해야 합니다.
참고: 이 해결 방법에서는 Amazon SNS 주제를 예시로 이용합니다. AWS Lambda 함수를 사용할 때 오류가 발생하는 경우에도 해결 방법은 비슷합니다.

  1. S3 버킷은 SNS 주제를 참조하므로 SNS 주제를 생성합니다.
  2. SNS 주제 정책은 S3 버킷과 SNS 주제를 둘 다 참조하므로 S3 버킷을 생성합니다.

S3 이벤트 알림에 대한 SNS 주제를 구독하기 전에 적절한 권한으로 주제 정책(AWS::SNS::TopicPolicy)을 지정해야 하며, 해당 주제 정책이 존재하는 상태에서 구독을 생성해야 합니다.

다음 전략 중 하나를 이용해 "Unable to validate the following destination configurations" 오류를 방지할 수 있습니다.

CloudFormation 템플릿에 BucketName 값 지정

CloudFormation 템플릿의 S3Bucket 리소스에서 BucketName 속성 값을 지정하여 정적 S3 버킷 이름을 사용합니다. 이렇게 하면 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 리소스에는 SNSTopicPolicy에 대해 설정된 명시적 DependsOn 값이 있습니다. 이 속성은 템플릿에서 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"
                    }
                ]
            }
        }
    }
  }
}

스택 생성 후 스택 업데이트 수행

스택 생성을 두 단계로 나눕니다. 우선 스택을 생성하되 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