代码之家  ›  专栏  ›  技术社区  ›  JJE

导致无服务器部署错误的原因:无法验证以下目标配置,S3 InvalidArgument?

  •  1
  • JJE  · 技术社区  · 7 年前

    我正在使用无服务器框架部署我的应用程序。最终目标是创建一个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 . 然而,我不认为这适用于我的情况,因为我只是将bucket上传到S3,而不是配置和SNS主题。

    1 回复  |  直到 7 年前
        1
  •  0
  •   JJE    7 年前

    我最终解决了这个问题。我将在下面发布代码,但本质上这是随机配置错误和我的bucket上的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>
    

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