有几种方法可以在 serverless.yml 中进行条件部署,有些方法比其他方法更脆弱,每种方法各有利弊,但这里是我收集的方法列表:
控制条件的变量
注意:我们使用自定义正则表达式变量语法将无服务器变量与 cloudformation 变量语法分开。以下所有 sn-ps 都使用此修改后的语法:
provider:
name: aws
# Changes serverless variable to ${{}} double curly braces
variableSyntax: "\\${{([ ~:a-zA-Z0-9._\\'\",\\-\\/\\(\\)]+?)}}"
custom:
scheduleEnabled:
dev: true
stage: true
prod: true
# Then In lambda function declaration
events:
- schedule:
name: MyScheduleName
description: SomeDescription
rate: cron(0/5 * * * ? *)
# Use custom variable and the serverless `stage` supplied
# via your deployment command to choose whether this feature is enabled
enabled: ${{self:custom.scheduleEnabled.${{self:provider.stage}}}}
input: {"_keepwarm": true}
使用条件运算
设置 CloudFormation 条件
resources:
- Conditions:
# True if they are equal ==
MyCondition: [!Equals ["${{env:SOMETHING}}","SOME_STRING"]]
# True if they are not equal !=
MyConditionTwo: !Not [!Equals ["${{env:SOMETHING_ELSE}}","SOME_OTHER_STRING"]]
# Using a custom serverless variable
IsProd: [!Equals ["${{self:provider.stage}}","prod"]]
使用 Cloudformation 条件
如果你的条件有两个选项,你可以写成:
# If true choose X, if False choose Y
Source:
Type: !If
- MyCondition # Conditional Name
- GITHUB # If condition is true
- GITHUB_ENTERPRISE # if condition is false
如果你的条件是你想要打开或关闭的东西,你可以写成:
# If True do nothing, If False choose X
MyCodebuildSetup:
Type: "AWS::CodeBuild::Project"
VpcConfig: !If
- MyCondition # Condition Name
- !Ref AWS::NoValue # If True, AWS will not attach a VPC Config
- VpcId: <My_VPC_ID> # If False, Use this VPC Config
Subnets:
- <my_VPC_Subnet>
SecurityGroupIds:
- <my_VPC_security_group
Weird Conditional Hacks(如果您决定实施它们,请记录使用情况)
有条件地部署大量资源
使用无服务器通过环境变量设置的字符串选择性地部署整个资源文件。
resources:
- ${{file(some_dir/conditional_file_${{env:MY_CONDITION}}.yml)}}
这也是一种通过条件切换许多资源部署的方法。
conditional_file_A.yaml 可以包含您切换部署的所有资源,而conditional_file_B.yaml 可以包含一个空的资源列表(如果您不希望来自无服务器的“找不到文件”警告:
Resources:
在将发送到 cloudformation(参数存储文件等)的 buildspec.yml 文件或 .json 文件中使用无服务器变量
如果您想有条件地修改将作为某个 CloudFormation 键的值发送的 .json 或 .yml 文件(例如为参数存储部署 .json 文件,或为 CodePipeline 提交 buildspec.yml 文件) ,您实际上不能在这些外部文件中使用 ${} 无服务器语法。这是因为serverless gets confused with it's own method of calling Key/Values from external files。
为了在这些文件中使用无服务器变量,只要实际文件的格式为正确的 .json 或 .yml,您就可以将它们设为 .txt 扩展名
Source:
Type: CODEPIPELINE
# This file can't have any serverless variables in it
BuildSpec: ${{file(my_buildspec_file.yml)}}
Source:
Type: CODEPIPELINE
# This file CAN have serverless variables because it is
# interpreted by serverless as a .txt, the variables
# are resolved and then it is sent to cloudformation as a string anyway
BuildSpec: ${{file(my_buildspec_file_yaml_formatted.txt)}}