CloudFormation 模板 Conditions 语法
可选的 Conditions
部分包含一些声明,以定义在哪些情况下创建或配置实体。例如,您可以创建一个条件,然后将其与某个资源或输出关联,以便 CloudFormation 仅在该条件成立时创建该资源或输出。同样,您可以将条件与一个属性关联,以便 CloudFormation 仅在该条件为 true 时将该属性设置为特定的值。如果该条件为 false,则 CloudFormation 会将该属性设置为您指定的其他值。
当您需要重新使用模板在不同环境(如测试环境与生产环境)中创建资源时,可以使用条件。例如,在模板中,您可以添加 EnvironmentType
输入参数,它接受 prod
或 test
以作为输入。对于 prod
环境,您可以采用带特定功能的 EC2 实例;但对于 test
环境,您可以使用更少功能,以便节约资金。通过定义条件,您可以定义为每个环境类型创建哪些资源以及如何配置资源。
语法
Conditions
部分包括键名称 Conditions
。每个条件声明均包括一个逻辑 ID 和多个内置函数。
JSON
"Conditions": { "
LogicalConditionName1
": { "Intrinsic function
":...
[ }, "LogicalConditionName2
": { "Intrinsic function
":...
} }
YAML
Conditions:
LogicalConditionName1
:Intrinsic function
:...
LogicalConditionName2
:Intrinsic function
:...
条件的工作原理
要使用条件,请按照下列步骤操作:
-
添加参数定义:定义条件在模板
Parameters
部分中进行评估的输入。根据这些输入参数的值,条件评估结果为 true 或 false。请注意,伪参数是自动可用的,不需要在Parameters
部分中进行明确定义。有关伪参数的更多信息,请参阅使用伪参数获取 AWS 值。 -
添加条件定义:使用内置函数(例如
Fn::If
或Fn::Equals
)在Conditions
部分中定义条件。这些条件将决定 CloudFormation 何时创建关联的资源。条件可以基于:-
输入或伪参数值
-
其他条件
-
映射值
但是,您不能在条件中引用资源逻辑 ID 或其属性。
-
-
将条件与资源或输出关联:使用
Condition
键和条件的逻辑 ID 在资源或输出中引用条件。或者,也可以在模板的其他部分(例如属性值)中使用Fn::If
以根据条件设置值。有关更多信息,请参阅 使用 Condition 密钥。
在创建或更新堆栈时,CloudFormation 会评估条件。CloudFormation 创建与成立的条件关联的实体,并忽略与不成立的条件关联的实体。在每个堆栈更新期间,CloudFormation 还会在修改任何资源之前重新评估这些条件。与 true 条件关联的实体将会更新,与 false 条件关联的实体将会删除。
重要
堆栈更新期间,您无法更新条件本身。您只能在包含添加、修改或删除资源的更改时更新条件。
条件内部函数
您可以使用以下内部函数定义条件:
注意
仅在模板的 Resources
和 Outputs
部分中的元数据属性、更新策略属性和属性值中支持 Fn::If
。
使用 Condition
密钥
定义条件后,您可以使用 Condition
密钥将其应用于模板中的多个位置,例如 Resources
和 Outputs
。Condition
密钥引用条件的逻辑名称并返回指定条件的评估结果。
将条件与资源关联
要有条件地创建资源,请添加 Condition
密钥,并将条件的逻辑 ID 作为属性添加到该资源中。仅当 条件评估为 true 时,CloudFormation 才会创建 资源。
JSON
"NewVolume" : { "Type" : "AWS::EC2::Volume", "Condition" : "IsProduction", "Properties" : { "Size" : "100", "AvailabilityZone" : { "Fn::GetAtt" : [ "EC2Instance", "AvailabilityZone" ]} } }
YAML
NewVolume: Type: AWS::EC2::Volume Condition: IsProduction Properties: Size: 100 AvailabilityZone: !GetAtt EC2Instance.AvailabilityZone
将条件与输出关联
您还可以将条件与输出关联。仅当关联条件的评估结果为 true 时,CloudFormation 才会创建输出。
JSON
"Outputs" : { "VolumeId" : { "Condition" : "IsProduction", "Value" : { "Ref" : "NewVolume" } } }
YAML
Outputs: VolumeId: Condition: IsProduction Value: !Ref NewVolume
其他条件中的引用条件
在 Conditions
部分中定义条件时,可以使用 Condition
密钥引用其他条件。这使您能够通过组合多个条件来创建更复杂的条件逻辑。
在以下示例中,仅当 IsProduction
和 IsProdAndFeatureEnabled
条件的评估结果为 true 时,IsFeatureEnabled
条件才会评估为 true。
JSON
"Conditions": { "IsProduction" : {"Fn::Equals" : [{"Ref" : "Environment"}, "prod"]}, "IsFeatureEnabled" : { "Fn::Equals" : [{"Ref" : "FeatureFlag"}, "enabled"]}, "IsProdAndFeatureEnabled" : { "Fn::And" : [ {"Condition" : "IsProduction"}, {"Condition" : "IsFeatureEnabled"} ] } }
YAML
Conditions: IsProduction: !Equals [!Ref Environment, "prod"] IsFeatureEnabled: !Equals [!Ref FeatureFlag, "enabled"] IsProdAndFeatureEnabled: !And - !Condition IsProduction - !Condition IsFeatureEnabled
使用 Fn::If
有条件地返回属性值
要进行更精细的控制,您可以使用 Fn::If
内置函数有条件地返回资源或输出中的两个属性值之一。该函数会对条件进行评估,如果条件为 true,则返回一个值;如果条件为 false,则返回另一个值。
条件属性值
以下示例演示了如何根据环境条件设置 EC2 实例类型。如果 IsProduction
条件的评估结果为 true,则实例类型设置为 c5.xlarge
。否则,该值将设置为 t3.small
。
JSON
"Properties" : { "InstanceType" : { "Fn::If" : [ "IsProduction", "c5.xlarge", "t3.small" ] } }
YAML
Properties: InstanceType: !If - IsProduction - c5.xlarge - t3.small
条件属性移除
您也可以使用 AWS::NoValue
伪参数名称】作为返回值,在条件为 false 时移除对应的属性。
JSON
"DBSnapshotIdentifier" : { "Fn::If" : [ "UseDBSnapshot", {"Ref" : "DBSnapshotName"}, {"Ref" : "AWS::NoValue"} ] }
YAML
DBSnapshotIdentifier: !If - UseDBSnapshot - !Ref DBSnapshotName - !Ref "AWS::NoValue"
示例
基于环境创建资源
以下示例将预置一个 EC2 实例,并且仅当环境类型为 prod
时,才会有条件地创建和附加新的 EBS 卷。如果环境是 test
,示例则只会创建不带额外卷的 EC2 实例。
JSON
{ "AWSTemplateFormatVersion": "2010-09-09", "Parameters": { "EnvType": { "Description": "Environment type", "Default": "test", "Type": "String", "AllowedValues": [ "prod", "test" ], "ConstraintDescription": "must specify prod or test" } }, "Conditions": { "IsProduction": { "Fn::Equals": [ { "Ref": "EnvType" }, "prod" ] } }, "Resources": { "EC2Instance": { "Type": "AWS::EC2::Instance", "Properties": { "ImageId": "ami-1234567890abcdef0", "InstanceType": "c5.xlarge" } }, "MountPoint": { "Type": "AWS::EC2::VolumeAttachment", "Condition": "IsProduction", "Properties": { "InstanceId": { "Ref": "EC2Instance" }, "VolumeId": { "Ref": "NewVolume" }, "Device": "/dev/sdh" } }, "NewVolume": { "Type": "AWS::EC2::Volume", "Condition": "IsProduction", "Properties": { "Size": 100, "AvailabilityZone": { "Fn::GetAtt": [ "EC2Instance", "AvailabilityZone" ] } } } } }
YAML
AWSTemplateFormatVersion: 2010-09-09 Parameters: EnvType: Description: Environment type Default: test Type: String AllowedValues: - prod - test ConstraintDescription: must specify prod or test Conditions: IsProduction: !Equals - !Ref EnvType - prod Resources: EC2Instance: Type: AWS::EC2::Instance Properties: ImageId: ami-1234567890abcdef0 InstanceType: c5.xlarge MountPoint: Type: AWS::EC2::VolumeAttachment Condition: IsProduction Properties: InstanceId: !Ref EC2Instance VolumeId: !Ref NewVolume Device: /dev/sdh NewVolume: Type: AWS::EC2::Volume Condition: IsProduction Properties: Size: 100 AvailabilityZone: !GetAtt - EC2Instance - AvailabilityZone
多条件资源预置
如果提供了存储桶名称,则以下示例会有条件地创建 S3 存储桶,并且仅当环境设置为 prod
时,才会附加存储桶策略。如果未提供存储桶名称或环境为 test
,则不会创建任何资源。
JSON
{ "AWSTemplateFormatVersion": "2010-09-09", "Parameters": { "EnvType": { "Type": "String", "AllowedValues": [ "prod", "test" ] }, "BucketName": { "Default": "", "Type": "String" } }, "Conditions": { "IsProduction": { "Fn::Equals": [ { "Ref": "EnvType" }, "prod" ] }, "CreateBucket": { "Fn::Not": [ { "Fn::Equals": [ { "Ref": "BucketName" }, "" ] } ] }, "CreateBucketPolicy": { "Fn::And": [ { "Condition": "IsProduction" }, { "Condition": "CreateBucket" } ] } }, "Resources": { "Bucket": { "Type": "AWS::S3::Bucket", "Condition": "CreateBucket", "Properties": { "BucketName": { "Ref": "BucketName" } } }, "Policy": { "Type": "AWS::S3::BucketPolicy", "Condition": "CreateBucketPolicy", "Properties": { "Bucket": { "Ref": "Bucket" }, "PolicyDocument": { ... } } } } }
YAML
AWSTemplateFormatVersion: 2010-09-09 Parameters: EnvType: Type: String AllowedValues: - prod - test BucketName: Default: '' Type: String Conditions: IsProduction: !Equals - !Ref EnvType - prod CreateBucket: !Not - !Equals - !Ref BucketName - '' CreateBucketPolicy: !And - !Condition IsProduction - !Condition CreateBucket Resources: Bucket: Type: AWS::S3::Bucket Condition: CreateBucket Properties: BucketName: !Ref BucketName Policy: Type: AWS::S3::BucketPolicy Condition: CreateBucketPolicy Properties: Bucket: !Ref Bucket PolicyDocument: ...
在此示例中,CreateBucketPolicy
条件演示了如何使用 Condition
密钥引用其他条件。只有当 IsProduction
和 CreateBucket
条件的评估结果都为 true 时,才会创建策略。
注意
有关使用条件的更复杂的示例,请参阅《AWS CloudFormation模板参考指南》中的Condition 属性主题。