我正在使用无服务器框架来部署我的应用程序。最终目标是创建一个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主题。
答案 0 :(得分:0)
我最终解决了这个问题。我将在下面发布代码,但实际上这是我的存储桶中随机配置错误和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>
现在,我们在子域上有一条有效的收货规则。一个S3存储桶,SES可以在收到子域的任何电子邮件地址时将电子邮件上传到该存储桶。通过将对象上传到存储桶触发的lambda函数。