使用CloudFormation创建lambda有三种方式:
CloudFormation yaml:
Resources:
LambdaExecutionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- sts:AssumeRole
Path: "/"
Policies:
- PolicyName: root
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- "s3:*"
Resource: "*"
- Effect: Allow
Action:
- "logs:CreateLogGroup"
- "logs:CreateLogStream"
- "logs:PutLogEvents"
Resource: "*"
ListBucketsS3Lambda:
Type: "AWS::Lambda::Function"
Properties:
Handler: "index.handler"
Role:
Fn::GetAtt:
- "LambdaExecutionRole"
- "Arn"
Runtime: "python3.7"
Code:
ZipFile: |
import boto3
# Create an S3 client
s3 = boto3.client('s3')
def handler(event, context):
# Call S3 to list current buckets
response = s3.list_buckets()
# Get a list of all bucket names from the response
buckets = [bucket['Name'] for bucket in response['Buckets']]
# Print out the bucket list
print("Bucket List: %s" % buckets)
return buckets
创建完成后可以到lambda界面里找到它:
总结:
如果有依赖(例如依赖paromiko库),或者代码行数超过4000行,这种方式不适合。
这种方式适合简单的lambda。
先建立一个桶和一个路径,用于上传打包后的lambda代码:
cloudformation代码如下(role的部分都一样,不同的是用S3指定代码位置):
Parameters:
S3BucketParam:
Type: String
S3KeyParam:
Type: String
Resources:
LambdaExecutionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- sts:AssumeRole
Path: "/"
Policies:
- PolicyName: root
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- "s3:*"
Resource: "*"
- Effect: Allow
Action:
- "logs:CreateLogGroup"
- "logs:CreateLogStream"
- "logs:PutLogEvents"
Resource: "*"
ListBucketsS3Lambda:
Type: "AWS::Lambda::Function"
Properties:
Handler: "index.handler"
Role:
Fn::GetAtt:
- "LambdaExecutionRole"
- "Arn"
Runtime: "python3.7"
Code:
S3Bucket: !Ref S3BucketParam
S3Key: !Ref S3KeyParam
创建stack时,将S3的参数填写进去:
创建完成后的效果:
代码如果要更新,此时将代码打包上传到S3相同位置,再进行更新:
由于参数为S3 bucketname和S3 path,两次检测到相同值,不会进行更新:
一种解决方法是上传时起不同名字的zip,再将zip名称填写到cloudformation的参数中,但这种方法不太优雅。
如果指定第三个变量versioning
,每次更新并打包上传代码后,加上version id
,cloudformation可以检测到变化,所以会进行更新:
Parameters:
S3BucketParam:
Type: String
S3KeyParam:
Type: String
S3ObjectVersionParam:
Type: String
Resources:
LambdaExecutionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- sts:AssumeRole
Path: "/"
Policies:
- PolicyName: root
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- "s3:*"
Resource: "*"
- Effect: Allow
Action:
- "logs:CreateLogGroup"
- "logs:CreateLogStream"
- "logs:PutLogEvents"
Resource: "*"
ListBucketsS3Lambda:
Type: "AWS::Lambda::Function"
Properties:
Handler: "index.handler"
Role:
Fn::GetAtt:
- "LambdaExecutionRole"
- "Arn"
Runtime: "python3.7"
Code:
S3Bucket:
Ref: S3BucketParam
S3Key:
Ref: S3KeyParam
S3ObjectVersion:
Ref: S3ObjectVersionParam
在S3里重新上传新版本的代码。更新堆栈,填写version id:
此时可以更新成功。