这是新的《Amazon CloudFormation 模板参考指南》。请更新您的书签和链接。有关开始使用 CloudFormation 的帮助,请参阅《Amazon CloudFormation 用户指南》https://docs.amazonaws.cn/AWSCloudFormation/latest/UserGuide/Welcome.html。
条件函数
您可以使用内置函数(如 Fn::If
或 Fn::Equals
)按条件逻辑创建和配置堆栈资源。这些条件会在堆栈创建或更新过程中进行评估。定义所有条件后,您可以在模板的 Resources
和 Outputs
部分将它们与资源或资源属性关联起来。
对于复杂场景,您可以使用 Fn::And
或 Fn::Or
函数组合多个条件,也可以使用 Fn::Not
函数对条件值取反。您还可以嵌套条件,以创建更复杂的条件逻辑。
如果您是首次在模板中使用条件,建议您先查看《Amazon CloudFormation 用户指南》中有关 CloudFormation 模板条件语法的内容。
注意
必须在模板的 Conditions
部分中定义所有条件(Fn::If
条件除外)。您可以在 Resources
和 Outputs
部分的 Metadata
属性、UpdatePolicy
属性和属性值中使用 Fn::If
条件。
Fn::And
如果所有指定条件计算为 true,则返回 true
,如果任意条件计算为 false,则返回 false
。Fn::And
用作 AND 运算符。您最少可以包含两个条件,最多可以包含 10 个条件。
声明
JSON
"Fn::And": [{
condition
}, {...
}]
参数
- condition
-
计算为
true
或false
的条件。
Fn::And
用法示例
当引用的安全组名称等于 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
-
您想要比较的字符串值。
Fn::Equals
用法示例
如果 IsProduction
参数的值等于 EnvironmentType
,则下面的 prod
条件计算为 true:
JSON
"IsProduction" : { "Fn::Equals": [ {"Ref": "EnvironmentType"}, "prod" ] }
YAML
IsProduction: !Equals [!Ref EnvironmentType, prod]
Fn::If
如果指定的条件计算为 true
,则返回一个值,如果指定的条件计算为 false
,则返回另一个值。当前,CloudFormation 在模板 Resources
部分和 Outputs
部分的 Metadata
属性、UpdatePolicy
属性和属性值中支持 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
时要返回的值。
Fn::If
用法示例
有条件地选择资源
以下示例在 Amazon EC2 资源定义中使用了一个 Fn::If
函数,用于确定将哪个安全组资源与实例关联。如果 CreateNewSecurityGroup
的评估结果为 true,则 CloudFormation 会使用 NewSecurityGroup
(在模板的其他位置创建的安全组)的引用值来指定 SecurityGroupIds
属性;如果 CreateNewSecurityGroup
为 false,则 CloudFormation 会使用 ExistingSecurityGroupId
(引用现有安全组的参数)的引用值。
JSON
"Resources": { "EC2Instance": { "Type": "AWS::EC2::Instance", "Properties": { "ImageId": "ami-0abcdef1234567890", "InstanceType": "t3.micro", "SecurityGroupIds": { "Fn::If": [ "CreateNewSecurityGroup", [{"Ref": "NewSecurityGroup"}], [{"Ref": "ExistingSecurityGroupId"}] ] }] } } }
YAML
Resources: EC2Instance: Type: AWS::EC2::Instance Properties: ImageId: ami-0abcdef1234567890 InstanceType: t3.micro SecurityGroupIds: !If - CreateNewSecurityGroup - [!Ref NewSecurityGroup] - [!Ref ExistingSecurityGroupId]
条件输出
在模板的 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" : "ExistingSecurityGroupId"} ] } } }
YAML
Outputs: SecurityGroupId: Description: Group ID of the security group used. Value: !If [CreateNewSecurityGroup, !Ref NewSecurityGroup, !Ref ExistingSecurityGroupId]
条件数组值
以下示例使用 Fn::If
根据条件提供不同的数组值。如果 MoreThan2AZs
条件的评估结果为 true,则使用三个公共子网。否则,仅使用两个公共子网。
JSON
"Subnets": { "Fn::If": [ "MoreThan2AZs", [ {"Fn::ImportValue": "PublicSubnet01"}, {"Fn::ImportValue": "PublicSubnet02"}, {"Fn::ImportValue": "PublicSubnet03"} ], [ {"Fn::ImportValue": "PublicSubnet01"}, {"Fn::ImportValue": "PublicSubnet02"} ] ] }
YAML
Subnets: Fn::If: - MoreThan2AZs - - Fn::ImportValue: PublicSubnet01 - Fn::ImportValue: PublicSubnet02 - Fn::ImportValue: PublicSubnet03 - - Fn::ImportValue: PublicSubnet01 - Fn::ImportValue: PublicSubnet02
条件属性和属性值
下面的示例在 AWS::NoValue
函数中使用 Fn::If
伪参数。仅当提供了快照 ID 时,该条件才对 Amazon RDS 数据库实例使用快照。如果 UseDBSnapshot
条件计算为 true,则 CloudFormation 对 DBSnapshotIdentifier
属性使用 DBSnapshotName
参数值。如果条件计算为 false,则 CloudFormation 删除 DBSnapshotIdentifier
属性。
此外,它还在 Amazon RDS 数据库实例的 AllocatedStorage
属性中使用了一个 Fn::If
函数。如果 IsProduction
的评估结果为 true,则存储大小将设置为 100
;否则,该值将设置为 20
。
JSON
"MyDatabase" : { "Type" : "AWS::RDS::DBInstance", "Properties": { "DBInstanceClass": "db.t3.micro", "AllocatedStorage": { "Fn::If": [ "IsProduction", 100, 20 ] }, "Engine" : "MySQL", "EngineVersion" : "5.5", "MasterUsername" : { "Ref" : "DBUser" }, "MasterUserPassword" : { "Ref" : "DBPassword" }, "DBParameterGroupName" : { "Ref" : "MyRDSParamGroup" }, "DBSnapshotIdentifier" : { "Fn::If" : [ "UseDBSnapshot", {"Ref" : "DBSnapshotName"}, {"Ref" : "AWS::NoValue"} ] } } }
YAML
MyDatabase: Type: AWS::RDS::DBInstance Properties: DBInstanceClass: db.t3.micro AllocatedStorage: !If [IsProduction, 100, 20] Engine: MySQL EngineVersion: 5.5 MasterUsername: !Ref DBUser MasterUserPassword: !Ref DBPassword DBParameterGroupName: !Ref MyRDSParamGroup DBSnapshotIdentifier: !If [UseDBSnapshot, !Ref DBSnapshotName, !Ref "AWS::NoValue"]
条件更新策略
以下代码段仅当 RollingUpdates
条件计算为 true 时,才提供 Auto Scaling 更新策略。如果条件计算结果为 false,则 CloudFormation 删除 AutoScalingRollingUpdate
更新策略。
JSON
"UpdatePolicy": { "Fn::If": [ "RollingUpdates", { "AutoScalingRollingUpdate": { "MaxBatchSize": 2, "MinInstancesInService": 2, "PauseTime": "PT0M30S" } }, { "Ref": "AWS::NoValue" } ] }
YAML
UpdatePolicy: !If - RollingUpdates - AutoScalingRollingUpdate: 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
)。
Fn::Not
用法示例
如果 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
的条件。
Fn::Or
用法示例
如果引用的安全组名称等于 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
-
其他条件函数
示例模板
按条件为生产、开发或测试堆栈创建资源
在某些情况下,您可能需要创建类似但略有不同的堆栈。例如,您可能有一个用于生产应用程序的模板。您需要创建相同的生产堆栈来用于开发或测试。但是,对于开发和测试,您可能不需要生产级堆栈中包含的所有额外容量。您可以使用环境类型输入参数按条件创建特定于生产、开发或测试的堆栈资源,如以下示例所示:
您可以为 prod
参数指定 dev
、test
或 EnvType
。对于每种环境类型,模板都指定一个不同的实例类型。实例类型范围可以从大型计算优化实例类型到小型通用实例类型。为了按条件指定实例类型,该模板在模板的 Conditions
部分定义两个条件:CreateProdResources
,如果 EnvType
参数值等于 prod
,则计算为 true;CreateDevResources
,如果该参数值等于 dev
,则计算为 true。
在 InstanceType
属性中,该模板嵌套了两个 Fn::If
内部函数来确定使用哪个实例类型。如果 CreateProdResources
条件为 true,则实例类型为 c5.xlarge
。如果条件为 false,则计算 CreateDevResources
条件。如果 CreateDevResources
条件为 true,则实例类型为 t3.medium
,否则实例类型为 t3.small
。
除实例类型之外,生产环境还向实例创建并附加一个 Amazon EC2 卷。MountPoint
和 NewVolume
资源与 CreateProdResources
条件相关联,目的是仅当条件计算为 true 时才创建资源。
例 JSON
{ "AWSTemplateFormatVersion" : "2010-09-09", "Parameters" : { "EnvType" : { "Description" : "Environment type.", "Default" : "test", "Type" : "String", "AllowedValues" : ["prod", "dev", "test"], "ConstraintDescription" : "must specify prod, dev, or test." } }, "Conditions" : { "CreateProdResources" : {"Fn::Equals" : [{"Ref" : "EnvType"}, "prod"]}, "CreateDevResources" : {"Fn::Equals" : [{"Ref" : "EnvType"}, "dev"]} }, "Resources" : { "EC2Instance" : { "Type" : "AWS::EC2::Instance", "Properties" : { "ImageId" : "ami-1234567890abcdef0", "InstanceType" : { "Fn::If" : [ "CreateProdResources", "c5.xlarge", {"Fn::If" : [ "CreateDevResources", "t3.medium", "t3.small" ]} ]} } }, "MountPoint" : { "Type" : "AWS::EC2::VolumeAttachment", "Condition" : "CreateProdResources", "Properties" : { "InstanceId" : { "Ref" : "EC2Instance" }, "VolumeId" : { "Ref" : "NewVolume" }, "Device" : "/dev/sdh" } }, "NewVolume" : { "Type" : "AWS::EC2::Volume", "Condition" : "CreateProdResources", "Properties" : { "Size" : "100", "AvailabilityZone" : { "Fn::GetAtt" : [ "EC2Instance", "AvailabilityZone" ]} } } } }
例 YAML
AWSTemplateFormatVersion: "2010-09-09" Parameters: EnvType: Description: Environment type. Default: test Type: String AllowedValues: [prod, dev, test] ConstraintDescription: must specify prod, dev, or test. Conditions: CreateProdResources: !Equals [!Ref EnvType, prod] CreateDevResources: !Equals [!Ref EnvType, "dev"] Resources: EC2Instance: Type: AWS::EC2::Instance Properties: ImageId: ami-1234567890abcdef0 InstanceType: !If [CreateProdResources, c5.xlarge, !If [CreateDevResources, t3.medium, t3.small]] MountPoint: Type: AWS::EC2::VolumeAttachment Condition: CreateProdResources Properties: InstanceId: !Ref EC2Instance VolumeId: !Ref NewVolume Device: /dev/sdh NewVolume: Type: AWS::EC2::Volume Condition: CreateProdResources Properties: Size: 100 AvailabilityZone: !GetAtt EC2Instance.AvailabilityZone
注意
有关使用条件创建资源的更复杂示例,请参阅 Condition 属性 主题。