如何修复 S3 存储桶和 SQS 之间的循环依赖?
How can I fix the circular dependency between my S3 bucket and SQS?
我正在尝试为我的服务编写 serverless 配置。要求是 S3 存储桶在对象创建事件上向 SQS 队列发送通知。但是,当我尝试使用 serverless deploy
部署我的服务时,出现此错误:
Serverless Error ----------------------------------------
An error occurred: PolicyS3Bucket - Unable to validate the following destination configurations (Service: Amazon S3; Status Code: 400; Error Code: InvalidArgument; Request ID: 4D25CQFZN0R2Q9FG; S3 Extended Request ID: dLfKHJgOnDUcAF3xwN9EgW9LibP3bt7ITj7PyuCXs2qH6Qvmn2iZu7aXYbbUdqptPvgvjwkcWYM=; Proxy: null).
我发现 this page 其中(如果我理解正确的话)解释了我的 S3 存储桶和 SQS 队列之间存在循环依赖关系,并且我必须修复此循环依赖关系才能成功部署我的服务。
此页面说明我可以使用 Fn::Sub
or Fn::Join
修复循环依赖。基于这个建议,我将我的配置从原始版本修改为新版本,如下所示,使用 Sub
:
cfn.s3.yml
(原版)
Resources:
PolicyS3Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: ${self:custom.config.policyBucketName}
AccessControl: Private
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
NotificationConfiguration:
QueueConfigurations:
- Event: s3:ObjectCreated:*
Queue: !GetAtt SQSQueue.Arn
BucketEncryption:
ServerSideEncryptionConfiguration:
- BucketKeyEnabled: true
ServerSideEncryptionByDefault:
KMSMasterKeyID: !Ref CustomMasterKey
SSEAlgorithm: aws:kms
Tags: ${redacted}
cfn.s3.yml
(新版本,粗体变化)
Resources:
PolicyS3Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: ${self:custom.config.policyBucketName}
AccessControl: Private
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
NotificationConfiguration:
QueueConfigurations:
- Event: s3:ObjectCreated:*
Queue: !Sub arn:aws:sqs:${self:provider.region}:${AWS::AccountId}:${self:custom.config.sqsQueueName}
BucketEncryption:
ServerSideEncryptionConfiguration:
- BucketKeyEnabled: true
ServerSideEncryptionByDefault:
KMSMasterKeyID: !Ref CustomMasterKey
SSEAlgorithm: aws:kms
Tags: ${redacted}
我不变cfn.sqs.yml
Resources:
SQSQueue:
Type: AWS::SQS::Queue
Properties:
QueueName: ${self:custom.config.sqsQueueName}
当我尝试 serverless deploy
使用新版本时,我遇到了同样的错误。
我也尝试了@kgiannakakis 的建议来使用 DependsOn
,但是我在尝试时遇到了同样的错误。
如何修复我的无服务器配置以便成功部署我的服务?
我找到了一个有效的修复程序。
我必须更新我的 cfn.sqs.yml
以包含 S3 存储桶将事件发送到 SQS 队列的权限,如下所示:
Resources:
SQSQueue:
Type: AWS::SQS::Queue
Properties:
QueueName: ${self:custom.config.sqsQueueName}
S3EventQueuePolicy:
Type: AWS::SQS::QueuePolicy
DependsOn: SQSQueue
Properties:
PolicyDocument:
Id: SQSPolicy
Statement:
- Effect: Allow
Sid: PutS3Events
Action: SQS:SendMessage
Resource: !GetAtt SQSQueue.Arn
Principal:
Service: s3.amazonaws.com
Queues:
- !Ref SQSQueue
至于我的 cfn.s3.yml
,引用队列的正确方法是
Queue: !GetAtt SQSQueue.Arn
我认为问题在于 AWS 检查通知是否可以在部署时发送,而不是让您的服务在运行时失败,如 this answer:
中所述
A lot of AWS configuration allows you to connect services and they fail at runtime if they don't have permission, however S3 notification configuration does check some destinations for access.
这意味着,由于我没有配置我的 SQS 队列以允许来自 S3 存储桶的通知,AWS 注意到了这个错误配置并停止了部署并出错。
我正在尝试为我的服务编写 serverless 配置。要求是 S3 存储桶在对象创建事件上向 SQS 队列发送通知。但是,当我尝试使用 serverless deploy
部署我的服务时,出现此错误:
Serverless Error ----------------------------------------
An error occurred: PolicyS3Bucket - Unable to validate the following destination configurations (Service: Amazon S3; Status Code: 400; Error Code: InvalidArgument; Request ID: 4D25CQFZN0R2Q9FG; S3 Extended Request ID: dLfKHJgOnDUcAF3xwN9EgW9LibP3bt7ITj7PyuCXs2qH6Qvmn2iZu7aXYbbUdqptPvgvjwkcWYM=; Proxy: null).
我发现 this page 其中(如果我理解正确的话)解释了我的 S3 存储桶和 SQS 队列之间存在循环依赖关系,并且我必须修复此循环依赖关系才能成功部署我的服务。
此页面说明我可以使用 Fn::Sub
or Fn::Join
修复循环依赖。基于这个建议,我将我的配置从原始版本修改为新版本,如下所示,使用 Sub
:
cfn.s3.yml
(原版)
Resources:
PolicyS3Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: ${self:custom.config.policyBucketName}
AccessControl: Private
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
NotificationConfiguration:
QueueConfigurations:
- Event: s3:ObjectCreated:*
Queue: !GetAtt SQSQueue.Arn
BucketEncryption:
ServerSideEncryptionConfiguration:
- BucketKeyEnabled: true
ServerSideEncryptionByDefault:
KMSMasterKeyID: !Ref CustomMasterKey
SSEAlgorithm: aws:kms
Tags: ${redacted}
cfn.s3.yml
(新版本,粗体变化)
Resources: PolicyS3Bucket: Type: AWS::S3::Bucket Properties: BucketName: ${self:custom.config.policyBucketName} AccessControl: Private PublicAccessBlockConfiguration: BlockPublicAcls: true BlockPublicPolicy: true IgnorePublicAcls: true RestrictPublicBuckets: true NotificationConfiguration: QueueConfigurations: - Event: s3:ObjectCreated:* Queue: !Sub arn:aws:sqs:${self:provider.region}:${AWS::AccountId}:${self:custom.config.sqsQueueName} BucketEncryption: ServerSideEncryptionConfiguration: - BucketKeyEnabled: true ServerSideEncryptionByDefault: KMSMasterKeyID: !Ref CustomMasterKey SSEAlgorithm: aws:kms Tags: ${redacted}
我不变cfn.sqs.yml
Resources:
SQSQueue:
Type: AWS::SQS::Queue
Properties:
QueueName: ${self:custom.config.sqsQueueName}
当我尝试 serverless deploy
使用新版本时,我遇到了同样的错误。
我也尝试了@kgiannakakis 的建议来使用 DependsOn
,但是我在尝试时遇到了同样的错误。
如何修复我的无服务器配置以便成功部署我的服务?
我找到了一个有效的修复程序。
我必须更新我的 cfn.sqs.yml
以包含 S3 存储桶将事件发送到 SQS 队列的权限,如下所示:
Resources:
SQSQueue:
Type: AWS::SQS::Queue
Properties:
QueueName: ${self:custom.config.sqsQueueName}
S3EventQueuePolicy:
Type: AWS::SQS::QueuePolicy
DependsOn: SQSQueue
Properties:
PolicyDocument:
Id: SQSPolicy
Statement:
- Effect: Allow
Sid: PutS3Events
Action: SQS:SendMessage
Resource: !GetAtt SQSQueue.Arn
Principal:
Service: s3.amazonaws.com
Queues:
- !Ref SQSQueue
至于我的 cfn.s3.yml
,引用队列的正确方法是
Queue: !GetAtt SQSQueue.Arn
我认为问题在于 AWS 检查通知是否可以在部署时发送,而不是让您的服务在运行时失败,如 this answer:
中所述A lot of AWS configuration allows you to connect services and they fail at runtime if they don't have permission, however S3 notification configuration does check some destinations for access.
这意味着,由于我没有配置我的 SQS 队列以允许来自 S3 存储桶的通知,AWS 注意到了这个错误配置并停止了部署并出错。