条件函数
您可以使用内部函数 (如 Fn::If
、Fn::Equals
和 Fn::Not
) 按条件创建堆栈资源。这些条件根据您在创建或更新堆栈时声明的输入参数进行计算。定义所有条件后,您可以在模板的资源和输出部分将它们与资源或资源属性关联起来。
所有条件 (Fn::If
条件除外) 都是在模板的条件部分中定义的。您可以在模板 Resources 和 Outputs 部分的元数据属性、更新策略属性和属性值中使用 Fn::If
条件。
当您需要重新使用可在不同环境 (如测试环境与生产环境) 中创建资源的模板时,可能会使用条件。在模板中,您可以添加 EnvironmentType
输入参数,它接受 prod
或 test
以作为输入。对于生产环境,您可以包括带特定功能的 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,则返回 false
。Fn::And
用作 AND 运算符。您最少可以包含两个条件,最多可以包含 10 个条件。
声明
JSON
"Fn::And": [{
condition
}, {...
}]
参数
condition
-
计算为
true
或false
的条件。
示例
当引用的安全组名称等于 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
伪参数作为返回值来删除相应的属性。
声明
JSON
"Fn::If": [
condition_name
,value_if_true
,value_if_false
]
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
的条件返回 true
。Fn::Not
用作 NOT 运算符。
声明
JSON
"Fn::Not": [{
condition
}]
参数
condition
-
计算为
Fn::Equals
或true
的条件 (如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,则返回 false
。Fn::Or
用作 OR 运算符。您最少可以包含两个条件,最多可以包含 10 个条件。
声明
JSON
"Fn::Or": [{
condition
}, {...
}]
YAML
完整函数名称的语法:
Fn::Or: [
condition, ...
]
短格式的语法:
!Or [
condition, ...
]
参数
condition
-
计算为
true
或false
的条件。
示例
如果引用的安全组名称等于 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::Equals
和 Fn::Or
:
-
Fn::FindInMap
-
Ref
-
其他条件函数