如何将条件放入 serverless.yml 文件?
How can I put condition in serverless.yml file?
我正在使用 serverless
框架来部署 api 网关。我不想在 Serverless 的每个阶段都应用 VPC。有没有办法根据 stage
名称添加以下配置?
provider:
name: aws
runtime: nodejs12.x
...
endpointType: PRIVATE
vpcEndpointIds:
- 'Fn::ImportValue': 'api-gateway-endpoint'
resourcePolicy:
- Effect: Deny
...
您可以查看以下答案:Conditional serverless.yml based on stage?
因此,您会得到如下内容:
resources:
Conditions:
IsProd:
Fn::Equals:
- ${opt:stage}
- prod
Resources:
SomeIAMRole:
Type: AWS::IAM::Role
Condition: IsProd
Properties:
etc
etc
在 serverless.yml 中有几种方法可以进行条件部署,有些方法比其他方法更脆弱,每种方法都有 pros/cons 但这里是我收集的方法列表:
控制条件的变量
注意: 我们使用自定义正则表达式变量语法将无服务器变量与 cloudformation 变量语法分开。以下所有代码段都使用此修改后的语法:
provider:
name: aws
# Changes serverless variable to ${{}} double curly braces
variableSyntax: "\${{([ ~:a-zA-Z0-9._\'\",\-\/\(\)]+?)}}"
Serverless Custom Variables
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
奇怪的条件黑客(如果您决定实施它们,请记录使用情况)
有条件部署大系列资源
使用 Serverless 使用通过环境变量设置的字符串有选择地部署整个资源文件。
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.
为了在这些文件中使用无服务器变量,您可以将它们扩展为 .txt,只要实际文件的格式正确。json 或 .yml
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)}}
或者,有一个 Serverless Plugin Ifelse
添加插件:
plugins:
- serverless-plugin-ifelse
然后添加您的条件:
custom:
.....
....
serverlessIfElse:
- If: '"${opt:stage}" == "production"'
Set:
functions.helloWorld.cors: true
查看更多信息Serveless plugin if-else
我正在使用 serverless
框架来部署 api 网关。我不想在 Serverless 的每个阶段都应用 VPC。有没有办法根据 stage
名称添加以下配置?
provider:
name: aws
runtime: nodejs12.x
...
endpointType: PRIVATE
vpcEndpointIds:
- 'Fn::ImportValue': 'api-gateway-endpoint'
resourcePolicy:
- Effect: Deny
...
您可以查看以下答案:Conditional serverless.yml based on stage?
因此,您会得到如下内容:
resources:
Conditions:
IsProd:
Fn::Equals:
- ${opt:stage}
- prod
Resources:
SomeIAMRole:
Type: AWS::IAM::Role
Condition: IsProd
Properties:
etc
etc
在 serverless.yml 中有几种方法可以进行条件部署,有些方法比其他方法更脆弱,每种方法都有 pros/cons 但这里是我收集的方法列表:
控制条件的变量
注意: 我们使用自定义正则表达式变量语法将无服务器变量与 cloudformation 变量语法分开。以下所有代码段都使用此修改后的语法:
provider:
name: aws
# Changes serverless variable to ${{}} double curly braces
variableSyntax: "\${{([ ~:a-zA-Z0-9._\'\",\-\/\(\)]+?)}}"
Serverless Custom Variables
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
奇怪的条件黑客(如果您决定实施它们,请记录使用情况)
有条件部署大系列资源
使用 Serverless 使用通过环境变量设置的字符串有选择地部署整个资源文件。
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.
为了在这些文件中使用无服务器变量,您可以将它们扩展为 .txt,只要实际文件的格式正确。json 或 .yml
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)}}
或者,有一个 Serverless Plugin Ifelse
添加插件:
plugins:
- serverless-plugin-ifelse
然后添加您的条件:
custom:
.....
....
serverlessIfElse:
- If: '"${opt:stage}" == "production"'
Set:
functions.helloWorld.cors: true
查看更多信息Serveless plugin if-else