我正在写一个lambda来更新RDS实例。显然,RDS实例必须位于VPC中,并且lambda必须位于VPC中,以便它可以访问RDS。好吧那么。所以我将lambda配置为VPC,然后它没有权限在EC2上打开网络接口,所以我必须给lambda一个具有这些权限的角色。
这是我的serverless.yml:
service: users-to-rds
plugins:
- serverless-plugin-typescript
provider:
name: aws
runtime: nodejs6.10
stage: dev
timeout: 30
region: ap-southeast-2
iamRoleStatements:
- Effect: Allow
Action:
- "S3:*"
Resource: arn:aws:s3:::*
- Effect: Allow
Action:
- "rds:*"
Resource: "*"
vpc:
securityGroupIds:
- sg-stuff
subnetIds:
- subnet-stuff
- subnet-stuff
- subnet-stuff
functions:
writeToDB:
handler: write-users-to-rds.writeToDB
events:
- sns: userlists
role:
Fn::GetAtt: [ "doStuffFromInsideVPC", "Arn" ]
Resources:
SNSInvokeLambdaPermission:
Type: "AWS::Lambda::Permission"
Properties:
Action: "lambda:InvokeFunction"
Principal: "sns.amazonaws.com"
SourceArn:
Ref: UserListNotification
FunctionName:
Fn::GetAtt: [ "UserListToRDS", "Arn" ]
doStuffFromInsideVPC:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument:
Version: '2017'
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: doStuffFromInsideVPCPolicy
PolicyDocument:
Version: '2017'
Statement:
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource:
- 'Fn::Join':
- ':'
- - 'arn:aws:logs'
- Ref: 'AWS::Region'
- Ref: 'AWS::AccountId'
- 'log-group:/aws/lambda/*:*:*'
- Effect: Allow
Action:
- ec2:CreateNetworkInterface
- ec2:DescribeNetworkInterfaces
- ec2:DetachNetworkInterface
- ec2:DeleteNetworkInterface
Resource: "*"
当我进行无服务器部署时,它会将zip上传到AWS,然后我被告知:
CloudFormation模板无效:模板错误:Fn :: GetAtt实例引用未定义资源doStuffFromInsideVPC
当然完全是胡说八道。就在那里。显然曾经有一个错误,CloudFormation没有及时创建角色资源,所以无服务器更新后添加了DependsOn,导致它等到角色存在。看看.serverless / cloudformation-template-update-stack.json它似乎有一个需要它的DependsOn。
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "The AWS CloudFormation template for this Serverless application",
"Resources": {
"ServerlessDeploymentBucket": {
"Type": "AWS::S3::Bucket",
"Properties": {
"AccelerateConfiguration": {
"AccelerationStatus": "Suspended"
}
}
},
"WriteToDBLogGroup": {
"Type": "AWS::Logs::LogGroup",
"Properties": {
"LogGroupName": "/aws/lambda/users-to-rds-dev-writeToDB"
}
},
"WriteToDBLambdaFunction": {
"Type": "AWS::Lambda::Function",
"Properties": {
"Code": {
"S3Bucket": {
"Ref": "ServerlessDeploymentBucket"
},
"S3Key": "serverless/users-to-rds/dev/1515307801502-2018-01-07T06:50:01.502Z/users-to-rds.zip"
},
"FunctionName": "users-to-rds-dev-writeToDB",
"Handler": "write-users-to-rds.writeToDB",
"MemorySize": 1024,
"Role": {
"Fn::GetAtt": [
"doStuffFromInsideVPC",
"Arn"
]
},
"Runtime": "nodejs6.10",
"Timeout": 30,
"VpcConfig": {
"SecurityGroupIds": [
"sg-stuff"
],
"SubnetIds": [
"subnet-stuff",
"subnet-stuff",
"subnet-stuff"
]
}
},
"DependsOn": [
"WriteToDBLogGroup",
"doStuffFromInsideVPC"
]
},
"WriteToDBLambdaVersionAOwtYsOPCw4hVAkxPXSzE66bZXvdbu2xQUzGAe58E": {
"Type": "AWS::Lambda::Version",
"DeletionPolicy": "Retain",
"Properties": {
"FunctionName": {
"Ref": "WriteToDBLambdaFunction"
},
"CodeSha256": "7gOzejhkEn37BviNCIVy1lw32IwPs9/oyeaPBQjlqVA="
}
},
"SNSTopicUserlists": {
"Type": "AWS::SNS::Topic",
"Properties": {
"TopicName": "userlists",
"DisplayName": "",
"Subscription": [
{
"Endpoint": {
"Fn::GetAtt": [
"WriteToDBLambdaFunction",
"Arn"
]
},
"Protocol": "lambda"
}
]
}
},
"WriteToDBLambdaPermissionUserlistsSNS": {
"Type": "AWS::Lambda::Permission",
"Properties": {
"FunctionName": {
"Fn::GetAtt": [
"WriteToDBLambdaFunction",
"Arn"
]
},
"Action": "lambda:InvokeFunction",
"Principal": "sns.amazonaws.com",
"SourceArn": {
"Fn::Join": [
"",
[
"arn:aws:sns:",
{
"Ref": "AWS::Region"
},
":",
{
"Ref": "AWS::AccountId"
},
":",
"userlists"
]
]
}
}
}
},
"Outputs": {
"ServerlessDeploymentBucketName": {
"Value": {
"Ref": "ServerlessDeploymentBucket"
}
},
"WriteToDBLambdaFunctionQualifiedArn": {
"Description": "Current Lambda function version",
"Value": {
"Ref": "WriteToDBLambdaVersionAOwtYsOPCw4hVAkxPXSzE66bZXvdbu2xQUzGAe58E"
}
}
}
}
任何想法,任何人?谢谢。
答案 0 :(得分:3)
根据serverless.yaml reference,资源应按以下方式定义:
resources:
Resources:
YourResource:
...
在你的情况下试试这个:
resources:
Resources:
SNSInvokeLambdaPermission:
Type: "AWS::Lambda::Permission"
...