【问题标题】:How can I fix the circular dependency between my S3 bucket and SQS?如何修复 S3 存储桶和 SQS 之间的循环依赖关系?
【发布时间】:2021-12-23 06:57:43
【问题描述】:

我正在尝试为我的服务编写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::SubFn::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(新版本,更改为粗体)

资源: PolicyS3Bucket: 类型:AWS::S3::桶 特性: 桶名:${self:custom.config.policyBucketName} 访问控制:私人 公共访问块配置: BlockPublicAcls: 真 块公共政策:真 IgnorePublicAcls: 真 RestrictPublicBuckets:真 通知配置: 队列配置: - 事件:s3:ObjectCreated:* 队列:!Sub arn:aws:sqs:${self:provider.region}:${AWS::AccountId}:${self:custom.config.sqsQueueName} 桶加密: 服务器端加密配置: - BucketKeyEnabled:真 服务器端加密默认: KMSMasterKeyID: !Ref CustomMasterKey SSE算法:aws:kms 标签:${已编辑}

我不变的cfn.sqs.yml

Resources:
  SQSQueue:
    Type: AWS::SQS::Queue
    Properties:
      QueueName: ${self:custom.config.sqsQueueName}

当我尝试使用新版本 serverless deploy 时,我得到了同样的错误。

我也尝试了@kgiannakakis 的建议来使用DependsOn,但是当我尝试这样做时,我得到了同样的错误。

如何修复无服务器配置,以便成功部署服务?

【问题讨论】:

  • 您需要 SQS ARN 中的区域和账户 ID:docs.aws.amazon.com/general/latest/gr/…
  • 我修复了 ARN,请参阅更新后的问题。
  • 尝试使用 DependsOn 属性 (docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/…),以便首先创建队列。我仍然不清楚,为什么桶和队列之间存在循环依赖关系。
  • 我不确定自己是否存在循环依赖。我刚刚搜索了“无法验证以下目标配置”,这将我带到了我在问题中链接的 AWS 文档页面,这表明该错误意味着循环依赖。我是 CloudFormation 和无服务器的新手,所以我只是假设只有在存在循环依赖时才会发生错误,但这可能是一个错误的假设。
  • @kgiannakakis 我试过DependsOn,但我仍然遇到同样的错误。

标签: amazon-web-services amazon-s3 amazon-cloudformation amazon-sqs serverless-framework


【解决方案1】:

我找到了一个有效的修复方法。

我必须更新我的 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 中所述:

许多 AWS 配置允许您连接服务,但如果它们没有权限,它们会在运行时失败,但是 S3 通知配置确实会检查一些目标以进行访问。

这意味着,由于我没有将 SQS 队列配置为允许来自 S3 存储桶的通知,AWS 注意到了这种错误配置并停止了部署并出现错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-21
    • 2019-12-03
    • 1970-01-01
    • 2016-09-24
    • 1970-01-01
    • 1970-01-01
    • 2021-09-27
    • 2016-10-18
    相关资源
    最近更新 更多