AWS::Lambda::Version
资源仅表示单个已发布的Lambda函数版本-它不会在每次代码更新时自动发布新版本。为了实现这一点,您有两个选项:
1. 自定义资源
您可以实现自己的自定义资源,该资源在每次更新时调用PublishVersion
。
对于此方法,每次更新堆栈时,您仍需要更改至少一个参数,以触发Custom Resource上的更新,从而触发PublishVersion操作。(但是,您不必实际更新模板。)
以下是完整的工作示例:
Description: Publish a new version of a Lambda function whenever the code is updated.
Parameters:
Nonce:
Description: Change this string when code is updated.
Type: String
Default: "Test"
Resources:
MyCustomResource:
Type: Custom::Resource
Properties:
ServiceToken: !GetAtt MyFunction.Arn
Nonce: !Ref Nonce
MyFunction:
Type: AWS::Lambda::Function
Properties:
Handler: index.handler
Role: !GetAtt LambdaExecutionRole.Arn
Code:
ZipFile: !Sub |
var response = require('cfn-response');
exports.handler = function(event, context) {
return response.send(event, context, response.SUCCESS, {Result: '${Nonce}'});
};
Runtime: nodejs4.3
LambdaDeploy:
Type: Custom::LambdaVersion
Properties:
ServiceToken: !GetAtt LambdaDeployFunction.Arn
FunctionName: !Ref MyFunction
Nonce: !Ref Nonce
LambdaDeployFunction:
Type: AWS::Lambda::Function
Properties:
Handler: "index.handler"
Role: !GetAtt LambdaExecutionRole.Arn
Code:
ZipFile: !Sub |
var AWS = require('aws-sdk');
var response = require('cfn-response');
exports.handler = (event, context) => {
console.log("Request received:\n", JSON.stringify(event));
if (event.RequestType == 'Delete') {
return response.send(event, context, response.SUCCESS);
}
var lambda = new AWS.Lambda();
lambda.publishVersion({FunctionName: event.ResourceProperties.FunctionName}).promise().then((data) => {
return response.send(event, context, response.SUCCESS, {Version: data.Version}, data.FunctionArn);
}).catch((e) => {
return response.send(event, context, response.FAILED, e);
});
};
Runtime: nodejs4.3
LambdaExecutionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal: {Service: [lambda.amazonaws.com]}
Action: ['sts:AssumeRole']
Path: /
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Policies:
- PolicyName: PublishVersion
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: ['lambda:PublishVersion']
Resource: '*'
Outputs:
LambdaVersion:
Value: !GetAtt LambdaDeploy.Version
CustomResourceResult:
Value: !GetAtt MyCustomResource.Result
2. 模板预处理器
你可以使用像嵌入式Ruby这样的模板预处理器(或者在每次部署时手动更新模板),通过更改AWS::Lambda::Version
资源的逻辑ID,在每次代码更新时发布新版本。
例如:
Description: Publish a new version of a Lambda function whenever the code is updated.
<%nonce = rand 10000%>
Resources:
LambdaVersion<%=nonce%>:
Type: AWS::Lambda::Version
Properties:
FunctionName: !Ref MyFunction
MyCustomResource:
Type: Custom::Resource
Properties:
ServiceToken: !GetAtt MyFunction.Arn
Nonce: <%=nonce%>
MyFunction:
Type: AWS::Lambda::Function
Properties:
Handler: index.handler
Role: !GetAtt LambdaExecutionRole.Arn
Code:
ZipFile: !Sub |
var response = require('cfn-response');
exports.handler = function(event, context) {
return response.send(event, context, response.SUCCESS, {Result: '<%=nonce%>'});
};
Runtime: nodejs4.3
LambdaExecutionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal: {Service: [lambda.amazonaws.com]}
Action: ['sts:AssumeRole']
Path: /
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Outputs:
LambdaVersion:
Value: !GetAtt LambdaVersion<%=nonce%>.Version
CustomResourceResult:
Value: !GetAtt MyCustomResource.Result
要通过erb
模板预处理器传递template.yml
来创建/更新堆栈,请运行:
运行:
aws cloudformation create-stack --stack-name myteststack --template-body file://template.yml --parameters "$(cat parameters.json)"
或者
aws cloudformation update-stack --stack-name myteststack --template-body file://template.yml --parameters "$(cat parameters.json)"
aws cloudformation [create|update]-stack \
--stack-name [stack_name] \
--template-body file://<(ruby -rerb -e "puts ERB.new(ARGF.read).result" < template.yml) \
--capabilities CAPABILITY_IAM