【问题标题】:What is causing Serverless deploy error: Unable to validate the following destination configurations, S3 InvalidArgument?是什么导致无服务器部署错误:无法验证以下目标配置,S3 InvalidArgument?
【发布时间】:2019-06-20 09:45:25
【问题描述】:

我正在使用无服务器框架来部署我的应用程序。最终目标是创建一个 SES 接收规则,将电子邮件捕获到某个子域并将它们上传到 S3 存储桶。对象上传将触发我的 lambda 函数。

在尝试部署我的“serverless.yml”时,我收到以下错误:

An error occurred: S3BucketEmails - Unable to validate the following 
destination configurations (Service: Amazon S3; Status Code: 400; 
Error Code: InvalidArgument; Request ID: <Request Id>; S3 Extended 
Request ID: <Extended Request Id>.

我的“serverless.yml”文件:

service: <my service name>

provider:
  name: aws
  runtime: python3.7
  stage: ${opt:stage, 'dev'}
  region: ${opt:region, 'us-west-2'}

  environment:
    AWS_ACCOUNT_ID: <my account number>
    SES_WRITABLE_ROLE_NAME: ${self:service}-${self:provider.stage}-ses-writable-role
    SES_WRITABLE_POLICY_NAME: ${self:service}-${self:provider.stage}-ses-writable-policy
    EMAIL_RECEIPT_RULE_NAME: ${self:service}-${self:provider.stage}-receipt-rule
    EMAIL_RECEIPT_RULE_SET_NAME: ${self:service}-${self:provider.stage}-receipt-set-name
    EMAIL_RECEIVED_TABLE_NAME: ${self:service}-${self:provider.stage}-table
    EMAIL_RECEIVED_BUCKET_NAME: ${self:service}-${self:provider.stage}-bucket
    REGION: ${self:provider.region}

  iamRoleStatements:
    -
      Effect: Allow
      Action:
        - dynamodb:CreateTable
        - dynamodb:DescribeTable
        - dynamodb:DeleteTable
        - dynamodb:GetItem
        - dynamodb:PutItem
        - dynamodb:DeleteItem
      Resource: arn:aws:dynamodb:::${self:provider.environment.EMAIL_RECEIVED_TABLE_NAME}
    - 
      Effect: Allow
      Action:
        - s3:CreateBucket
        - s3:DeleteBucket
        - s3:DeleteObject
        - s3:GetObject
        - s3:PutObject
        - s3:ListBucket
        - s3:PutBucketPolicy
      Resource: arn:aws:s3:::${self:provider.environment.EMAIL_RECEIVED_BUCKET_NAME}

functions:
  emailReceived:
    handler: emailHandler.emailReceived
    events:
      -
        s3: 
          bucket: emails
          event: s3:ObjectCreated:*
          rules:
            -
              prefix: emails/

resources:
  Resources:

    S3BucketEmails:
      Type: AWS::S3::Bucket
      Properties:
        BucketName: ${self:provider.environment.EMAIL_RECEIVED_BUCKET_NAME}

    SESWritableBucketRole:
      Type: AWS::IAM::Role
      Properties:
        RoleName: ${self:provider.environment.SES_WRITABLE_ROLE_NAME}
        AssumeRolePolicyDocument:
          Version: '2012-10-17'
          Statement:
            - Effect: Allow
              Principal:
                Service:
                  - ses.amazonaws.com
              Action: sts:AssumeRole
              Condition:
                StringEquals:
                  aws:Referer: ${self:provider.environment.AWS_ACCOUNT_ID}
        Policies:
          - PolicyName: ${self:provider.environment.SES_WRITABLE_POLICY_NAME}
            PolicyDocument:
              Version: '2012-10-17'
              Statement:
                - Effect: Allow
                  Action:
                    - s3:*
                  Resource: arn:aws:s3:::${self:provider.environment.EMAIL_RECEIVED_BUCKET_NAME}
      DependsOn: S3BucketEmails

    MyReceiptRuleSet:
      Type: AWS::SES::ReceiptRuleSet
      Properties:
        RuleSetName: ${self:provider.environment.EMAIL_RECEIPT_RULE_SET_NAME}
      DependsOn: SESWritableBucketRole

    MyReceiptRule:
      Type: AWS::SES::ReceiptRule
      Properties:
        RuleSetName: ${self:provider.environment.EMAIL_RECEIPT_RULE_SET_NAME}
        Rule:
          Name: ${self:provider.environment.EMAIL_RECEIPT_RULE_NAME}
          Enabled: true
          Recipients: 
            -
              subdomain.exampledomain.com
          Actions:
            -
              S3Action:
                BucketName: ${self:provider.environment.EMAIL_RECEIVED_BUCKET_NAME}
                ObjectKeyPrefix: emails/
      DependsOn: MyReceiptRuleSet

在我添加角色策略之前,我收到了一个与我的接收规则无法写入我的 S3 存储桶相关的错误。当它与SNS topic 相关时,我只发现了此错误的引用。但是,我认为这不适用于我的情况,因为我只是将存储桶上传到 S3,而不是配置和 SNS 主题。

【问题讨论】:

  • 不一定是你要问的,但是 SES ReceiptRule 可以直接触发 Lambda,你不必通过 S3 通知来做。见docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/…
  • @MilanCermak 是的,这是真的。不过,我想保存这些收到的电子邮件以备不时之需。
  • 两者兼得。 SES ReceiptRule 的Actions 属性是一个列表,因此您可以在S3Action 旁边定义一个LambdaAction

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


【解决方案1】:

我最终解决了这个问题。我将在下面发布代码,但本质上这是随机配置错误和我存储桶上的 Cors 属性的组合。

因为 S3 是全球性的,所以它没有在与我的所有其他资源相同的默认区域中创建。 SES 需要访问以从另一个来源写入存储桶,但由于未设置 Cors 属性而无法访问。

我最终将我的角色和政策分开,并更改了一些小的格式更改。这是我的资源和功能现在的样子。


functions:
  emailReceived:
    handler: emailHandler.emailReceived
    events:
      -
        s3: 
          bucket: <my-bucket-name>
          event: s3:ObjectCreated:*

resources:
  Resources:

    S3Bucket<My-bucket-name>:
      Type: AWS::S3::Bucket
      Properties:
        CorsConfiguration:
          CorsRules:
            -
              AllowedMethods:
                - "PUT"
                - "POST"
                - "GET"
                - "DELETE"
                - "HEAD"
              AllowedOrigins:
                - "*"

    SESWritableBucketPolicy:
      Type: AWS::IAM::Policy
      Properties:
        PolicyName: "SESWritableBucketPolicy"
        PolicyDocument:
          Version: '2012-10-17'
          Statement:
            - Effect: Allow
              Sid: "AllowSESPuts"
              Action: s3:PutObject
              Resource: "arn:aws:s3:::<my-bucket-name>"
              Condition:
                StringEquals:
                  aws:Referer: "#{AWS::AccountId}"
        Roles: 
          - SESWritableBucketRole
      DependsOn: EmailReceivedLambdaFunction

    SESWritableBucketRole:
      Type: AWS::IAM::Role
      Properties:
        RoleName: "SESWritableBucketRole"
        AssumeRolePolicyDocument:
          Version: '2012-10-17'
          Statement:
            - Effect: Allow
              Principal:
                Service: ses.amazonaws.com
              Action: sts:AssumeRole
              Condition:
                StringEquals:
                  aws:Referer: "#{AWS::AccountId}"
      DependsOn: SESWritableBucketPolicy

    EmailReceivedRuleSet:
      Type: AWS::SES::ReceiptRuleSet
      Properties:
        RuleSetName: "EmailReceivedRuleSet"

    EmailReceivedRule:
      Type: AWS::SES::ReceiptRule
      Properties:
        RuleSetName: "EmailReceivedRuleSet"
        Rule:
          Name: "EmailReceivedRule"
          Enabled: true
          Recipients:
            - "subdomain.domain.com"
          Actions:
            -
              S3Action:
                BucketName: <my-bucket-name>

现在我们的子域上有一个有效的收据规则。 SES 在收到子域的任何电子邮件地址时可以将电子邮件上传到的 S3 存储桶。通过将对象上传到该存储桶来触发的 lambda 函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-04
    • 2020-05-16
    • 2020-06-06
    • 2021-11-26
    • 1970-01-01
    • 2018-04-23
    • 1970-01-01
    • 2021-08-27
    相关资源
    最近更新 更多