条件函数 - AWS CloudFormation

条件函数

您可以使用内部函数 (如 Fn::IfFn::EqualsFn::Not) 按条件创建堆栈资源。这些条件根据您在创建或更新堆栈时声明的输入参数进行计算。定义所有条件后,您可以在模板的资源和输出部分将它们与资源或资源属性关联起来。

所有条件 (Fn::If 条件除外) 都是在模板的条件部分中定义的。您可以在模板 Resources 和 Outputs 部分的元数据属性、更新策略属性和属性值中使用 Fn::If 条件。

当您需要重新使用可在不同环境 (如测试环境与生产环境) 中创建资源的模板时,可能会使用条件。在模板中,您可以添加 EnvironmentType 输入参数,它接受 prodtest 以作为输入。对于生产环境,您可以包括带特定功能的 Amazon EC2 实例;但对于测试环境,您需要使用更少的功能来节约成本。使用条件,您可以定义对每个环境类型创建哪些资源以及如何配置它们。

有关条件部分的更多信息,请参阅 CloudFormation 模板的 Conditions 部分语法参考

注意

您只能从模板的参数和映射部分引用其他条件和值。例如,您可引用输入参数中的值,但不能在条件中引用资源的逻辑 ID。

关联条件

要有条件地创建资源、资源属性或输出,就必须为它们关联条件。可以将 Condition: 键和条件逻辑 ID 添加为属性以与条件相关联,如以下代码段所示。只有在 CreateProdResources 条件的计算结果为 true 时,AWS CloudFormation 才会创建 NewVolume 资源。

JSON

"NewVolume" : { "Type" : "AWS::EC2::Volume", "Condition" : "CreateProdResources", "Properties" : { "Size" : "100", "AvailabilityZone" : { "Fn::GetAtt" : [ "EC2Instance", "AvailabilityZone" ]} }

YAML

NewVolume: Type: "AWS::EC2::Volume" Condition: CreateProdResources Properties: Size: 100 AvailabilityZone: !GetAtt EC2Instance.AvailabilityZone

Fn::If

对于 Fn::If 函数,只需指定条件名称。下面的代码段说明如何使用 Fn::If 有条件地指定资源属性。如果 CreateLargeSize 条件为 true,则 CloudFormation 将卷大小设为 100。如果条件为 false,则 CloudFormation 将卷大小设置为 10

JSON

{ "NewVolume": { "Type": "AWS::EC2::Volume", "Properties": { "Size": { "Fn::If": [ "CreateLargeSize", "100", "10" ] }, "AvailabilityZone": { "Fn::GetAtt": [ "Ec2Instance", "AvailabilityZone" ] } }, "DeletionPolicy": "Snapshot" } }

YAML

NewVolume: Type: 'AWS::EC2::Volume' Properties: Size: 'Fn::If': - CreateLargeSize - '100' - '10' AvailabilityZone: 'Fn::GetAtt': - Ec2Instance - AvailabilityZone DeletionPolicy: Snapshot

嵌套条件

您还可以在条件中使用其他条件。下面的代码段来自模板的 Conditions 部分。MyAndCondition 条件包含 SomeOtherCondition 条件:

JSON
"MyAndCondition": { "Fn::And": [ {"Fn::Equals": ["sg-mysggroup", {"Ref": "ASecurityGroup"}]}, {"Condition": "SomeOtherCondition"} ] }
YAML
MyAndCondition: !And - !Equals ["sg-mysggroup", !Ref "ASecurityGroup"] - !Condition SomeOtherCondition

Fn::And

如果所有指定条件计算为 true,则返回 true,如果任意条件计算为 false,则返回 falseFn::And 用作 AND 运算符。您最少可以包含两个条件,最多可以包含 10 个条件。

声明

JSON

"Fn::And": [{condition}, {...}]

YAML

完整函数名称的语法:

Fn::And: [condition]

短格式的语法:

!And [condition]

参数

condition

计算为 truefalse 的条件。

示例

当引用的安全组名称等于 MyAndCondition 并且 sg-mysggroup 计算为 true 时,下面的 SomeOtherCondition 计算为 true:

JSON

"MyAndCondition": { "Fn::And": [ {"Fn::Equals": ["sg-mysggroup", {"Ref": "ASecurityGroup"}]}, {"Condition": "SomeOtherCondition"} ] }

YAML

MyAndCondition: !And - !Equals ["sg-mysggroup", !Ref ASecurityGroup] - !Condition SomeOtherCondition

Fn::Equals

比较两个值是否相等。如果两个值相等,则返回 true,如果不等,则返回 false

声明

JSON

"Fn::Equals" : ["value_1", "value_2"]

YAML

完整函数名称的语法:

Fn::Equals: [value_1, value_2]

短格式的语法:

!Equals [value_1, value_2]

参数

value

要比较的任意类型的值。

示例

如果 UseProdCondition 参数的值等于 EnvironmentType,则下面的 prod 条件计算为 true:

JSON

"UseProdCondition" : { "Fn::Equals": [ {"Ref": "EnvironmentType"}, "prod" ] }

YAML

UseProdCondition: !Equals [!Ref EnvironmentType, prod]

Fn::If

如果指定的条件计算为 true,则返回一个值,如果指定的条件计算为 false,则返回另一个值。当前,CloudFormation 在模板 Resources 部分和 Outputs 部分的元数据属性、更新策略属性和属性值中支持 Fn::If 内部函数。您可以使用 AWS::NoValue 伪参数作为返回值来删除相应的属性。

声明

YAML

完整函数名称的语法:

Fn::If: [condition_name, value_if_true, value_if_false]

短格式的语法:

!If [condition_name, value_if_true, value_if_false]

参数

condition_name

条件部分中对条件的引用。使用条件名称引用它。

value_if_true

当指定的条件计算为 true 时要返回的值。

value_if_false

当指定的条件计算为 false 时要返回的值。

示例

要查看更多示例,请参阅 示例 模板

示例 1

下面的代码段在 Amazon EC2 资源的 SecurityGroups 属性中使用了一个 Fn::If 函数。如果 CreateNewSecurityGroup 条件计算为 true,则 CloudFormation 使用 NewSecurityGroup 的引用值指定 SecurityGroups 属性;否则,CloudFormation 使用 ExistingSecurityGroup 的引用值。

JSON
"SecurityGroups" : [{ "Fn::If" : [ "CreateNewSecurityGroup", {"Ref" : "NewSecurityGroup"}, {"Ref" : "ExistingSecurityGroup"} ] }]
YAML
SecurityGroups: - !If [CreateNewSecurityGroup, !Ref NewSecurityGroup, !Ref ExistingSecurityGroup]

示例 2

在模板的 Output 部分中,您可以使用 Fn::If 函数按条件输出信息。在以下代码段中,如果 CreateNewSecurityGroup 条件的计算结果为 true,则 CloudFormation 输出 NewSecurityGroup 资源的安全组 ID。如果条件为 false,则 CloudFormation 输出 ExistingSecurityGroup 资源的安全组 ID。

JSON
"Outputs" : { "SecurityGroupId" : { "Description" : "Group ID of the security group used.", "Value" : { "Fn::If" : [ "CreateNewSecurityGroup", {"Ref" : "NewSecurityGroup"}, {"Ref" : "ExistingSecurityGroup"} ] } } }
YAML
Outputs: SecurityGroupId: Description: Group ID of the security group used. Value: !If [CreateNewSecurityGroup, !Ref NewSecurityGroup, !Ref ExistingSecurityGroup]

示例 3

下面的代码段在 AWS::NoValue 函数中使用 Fn::If 伪参数。仅当提供了快照 ID 时,该条件才对 Amazon RDS 数据库实例使用快照。如果 UseDBSnapshot 条件计算为 true,则 CloudFormation 对 DBSnapshotIdentifier 属性使用 DBSnapshotName 参数值。如果条件计算为 false,则 CloudFormation 删除 DBSnapshotIdentifier 属性。

JSON
"MyDB" : { "Type" : "AWS::RDS::DBInstance", "Properties" : { "AllocatedStorage" : "5", "DBInstanceClass" : "db.t2.small", "Engine" : "MySQL", "EngineVersion" : "5.5", "MasterUsername" : { "Ref" : "DBUser" }, "MasterUserPassword" : { "Ref" : "DBPassword" }, "DBParameterGroupName" : { "Ref" : "MyRDSParamGroup" }, "DBSnapshotIdentifier" : { "Fn::If" : [ "UseDBSnapshot", {"Ref" : "DBSnapshotName"}, {"Ref" : "AWS::NoValue"} ] } } }
YAML
MyDB: Type: "AWS::RDS::DBInstance" Properties: AllocatedStorage: 5 DBInstanceClass: db.t2.small Engine: MySQL EngineVersion: 5.5 MasterUsername: !Ref DBUser MasterUserPassword: !Ref DBPassword DBParameterGroupName: !Ref MyRDSParamGroup DBSnapshotIdentifier: !If [UseDBSnapshot, !Ref DBSnapshotName, !Ref "AWS::NoValue"]

示例 4

以下代码段仅当 RollingUpdates 条件计算为 true 时,才提供 Auto Scaling 更新策略。如果条件计算结果为 false,则 CloudFormation 删除 AutoScalingRollingUpdate 更新策略。

JSON
"UpdatePolicy": { "AutoScalingRollingUpdate": { "Fn::If": [ "RollingUpdates", { "MaxBatchSize": "2", "MinInstancesInService": "2", "PauseTime": "PT0M30S" }, { "Ref" : "AWS::NoValue" } ] } }
YAML
UpdatePolicy: AutoScalingRollingUpdate: !If - RollingUpdates - MaxBatchSize: 2 MinInstancesInService: 2 PauseTime: PT0M30S - !Ref "AWS::NoValue"

Fn::Not

对计算为 true 的条件返回 false,对计算为 false 的条件返回 trueFn::Not 用作 NOT 运算符。

声明

JSON

"Fn::Not": [{condition}]

YAML

完整函数名称的语法:

Fn::Not: [condition]

短格式的语法:

!Not [condition]

参数

condition

计算为 Fn::Equalstrue 的条件 (如 false)。

示例

如果 EnvironmentType 参数的值不等于 prod,则下面的 EnvCondition 条件计算为 true:

JSON

"MyNotCondition" : { "Fn::Not" : [{ "Fn::Equals" : [ {"Ref" : "EnvironmentType"}, "prod" ] }] }

YAML

MyNotCondition: !Not [!Equals [!Ref EnvironmentType, prod]]

Fn::Or

如果任意一个指定条件计算为 true,则返回 true,如果所有条件都计算为 false,则返回 falseFn::Or 用作 OR 运算符。您最少可以包含两个条件,最多可以包含 10 个条件。

声明

JSON

"Fn::Or": [{condition}, {...}]

YAML

完整函数名称的语法:

Fn::Or: [condition, ...]

短格式的语法:

!Or [condition, ...]

参数

condition

计算为 truefalse 的条件。

示例

如果引用的安全组名称等于 MyOrCondition 或者 sg-mysggroup 计算为 true,则下面的 SomeOtherCondition 计算为 true:

JSON

"MyOrCondition" : { "Fn::Or" : [ {"Fn::Equals" : ["sg-mysggroup", {"Ref" : "ASecurityGroup"}]}, {"Condition" : "SomeOtherCondition"} ] }

YAML

MyOrCondition: !Or [!Equals [sg-mysggroup, !Ref ASecurityGroup], Condition: SomeOtherCondition]

支持的函数

您可以在 Fn::If 条件中使用以下函数:

  • Fn::Base64

  • Fn::FindInMap

  • Fn::GetAtt

  • Fn::GetAZs

  • Fn::If

  • Fn::Join

  • Fn::Select

  • Fn::Sub

  • Ref

您可在所有其他条件函数中使用以下函数,如 Fn::EqualsFn::Or

  • Fn::FindInMap

  • Ref

  • 其他条件函数