SAM 模板是 Cloudformation 的超集。任何 Cloudformation 模板都可以通过 SAM 原样运行,并且可以正常工作。 SAM 支持 Cloudformation 模板中可用的所有类型,因此您可以将 SAM 视为“CloudFormation++”。
但是,SAM 还为您提供了额外的“转换”,让您可以简洁地定义某些概念,SAM 会弄清楚您的意思并填补缺失的部分,以创建完整、扩展、合法的 Cloudformation 模板。
示例:对于主要处理 Lambda 函数的 SAM(和无服务器框架)用户,最有用的转换之一是 Lambda 函数上的 Events 属性——SAM 将添加访问该函数所需的所有对象通过 API Gateway 中的 API 路径运行。
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: HelloWorldFunction
Handler: app.lambdaHandler
Runtime: nodejs12.x
Events: # <--- "Events" property is not a real Cloudformation Lambda property
HelloWorld:
Type: Api
Properties:
Path: /hello
Method: get
上面显示的 SAM 模板 sn-p 被转换/扩展为几个 API Gateway 对象(一个 RestApi、一个部署和一个阶段)。此 sn-p 中使用的 AWS::Serverless::Function 类型不是真正的 Cloudformation 类型——您不会在文档中找到它。 SAM 将其扩展为一个 Cloudformation 模板,其中包含一个 AWS::Lambda::Function 对象和 Cloudformation 可以理解的几个不同的 AWS::ApiGateway::* 对象。
为了让您了解这为您节省了多少手动编码,以下是上述 SAM 模板的扩展版本作为完整 Cloudformation 模板的样子:
Resources:
HelloWorldFunctionHelloWorldPermissionProd:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:InvokeFunction
Principal: apigateway.amazonaws.com
FunctionName:
Ref: HelloWorldFunction
SourceArn:
Fn::Sub:
- arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/hello
- __Stage__: "*"
__ApiId__:
Ref: ServerlessRestApi
HelloWorldFunctionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Action:
- sts:AssumeRole
Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Tags:
- Value: SAM
Key: lambda:createdBy
ServerlessRestApiProdStage:
Type: AWS::ApiGateway::Stage
Properties:
DeploymentId:
Ref: ServerlessRestApiDeployment_NNN
RestApiId:
Ref: ServerlessRestApi
StageName: Prod
ServerlessRestApiDeployment_NNN:
Type: AWS::ApiGateway::Deployment
Properties:
RestApiId:
Ref: ServerlessRestApi
Description: 'RestApi deployment id: ???'
StageName: Stage
ServerlessRestApi:
Type: AWS::ApiGateway::RestApi
Properties:
Body:
info:
version: '1.0'
title:
Ref: AWS::StackName
paths:
"/hello":
get:
x-amazon-apigateway-integration:
httpMethod: POST
type: aws_proxy
uri:
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${HelloWorldFunction.Arn}/invocations
responses: {}
swagger: '2.0'
HelloWorldFunction:
Type: AWS::Lambda::Function
Properties:
Code:
S3Bucket: aws-sam-cli-managed-default-samclisourcebucket-???
S3Key: temp/???
Tags:
- Value: SAM
Key: lambda:createdBy
Handler: app.lambdaHandler
Role:
Fn::GetAtt:
- HelloWorldFunctionRole
- Arn
Timeout: 3
Runtime: nodejs12.x
以前,如果您要编写纯 Cloudformation,则必须为要创建的每个 API 网关端点手动一遍又一遍地编写所有这些代码。现在,使用 SAM 模板,您可以将 API 定义为 Lambda 函数的“事件”属性,而 SAM(或无服务器框架)会处理这些苦差事。
在过去,当我们不得不手动完成所有这些工作时,它完全糟透了。但现在,一切又恢复了辉煌。