条件函数
您可以使用内部函数 (如 Fn::If、Fn::Equals 和 Fn::Not) 按条件创建堆栈资源。这些条件根据您在创建或更新堆栈时声明的输入参数进行计算。定义所有条件后,您可以在模板的资源和输出部分将它们与资源或资源属性关联起来。
所有条件 (Fn::If 条件除外) 都是在模板的条件部分中定义的。您可以在模板 Resources 和 Outputs 部分的元数据属性、更新策略属性和属性值中使用 Fn::If 条件。
当您需要重新使用可在不同环境 (如测试环境与生产环境) 中创建资源的模板时,可能会使用条件。在模板中,您可以添加 EnvironmentType 输入参数,它接受 prod 或 test 以作为输入。对于生产环境,您可以包括带特定功能的 Amazon EC2 实例;但对于测试环境,您需要使用更少的功能来节约成本。使用条件,您可以定义对每个环境类型创建哪些资源以及如何配置它们。
有关条件部分的更多信息,请参阅条件。
注意
您只能从模板的参数和映射部分引用其他条件和值。例如,您可引用输入参数中的值,但不能在条件中引用资源的逻辑 ID。
关联条件
要有条件地创建资源、资源属性或输出,就必须为它们关联条件。可以将 Condition: 键和条件逻辑 ID 添加为属性以与条件相关联,如以下代码段所示。只有在 CreateProdResources 条件的计算结果为 true 时,Amazon 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}, {...}]
参数
示例
当引用的安全组名称等于 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]
参数
示例
要查看更多示例,请参阅示例模板。
示例 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}]
参数
示例
如果 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 -
其他条件函数