CloudFormation 模板 Conditions 语法 - AWS CloudFormation

CloudFormation 模板 Conditions 语法

可选的 Conditions 部分包含一些声明,以定义在哪些情况下创建或配置实体。例如,您可以创建一个条件,然后将其与某个资源或输出关联,以便 CloudFormation 仅在该条件成立时创建该资源或输出。同样,您可以将条件与一个属性关联,以便 CloudFormation 仅在该条件为 true 时将该属性设置为特定的值。如果该条件为 false,则 CloudFormation 会将该属性设置为您指定的其他值。

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

语法

Conditions 部分包括键名称 Conditions。每个条件声明均包括一个逻辑 ID 和多个内置函数。

JSON

"Conditions": { "LogicalConditionName1": { "Intrinsic function": ...[ }, "LogicalConditionName2": { "Intrinsic function": ... } }

YAML

Conditions: LogicalConditionName1: Intrinsic function: ... LogicalConditionName2: Intrinsic function: ...

条件的工作原理

要使用条件,请按照下列步骤操作:

  1. 添加参数定义:定义条件在模板 Parameters 部分中进行评估的输入。根据这些输入参数的值,条件评估结果为 true 或 false。请注意,伪参数是自动可用的,不需要在 Parameters 部分中进行明确定义。有关伪参数的更多信息,请参阅使用伪参数获取 AWS 值

  2. 添加条件定义:使用内置函数(例如 Fn::IfFn::Equals)在 Conditions 部分中定义条件。这些条件将决定 CloudFormation 何时创建关联的资源。条件可以基于:

    • 输入或伪参数值

    • 其他条件

    • 映射值

    但是,您不能在条件中引用资源逻辑 ID 或其属性。

  3. 将条件与资源或输出关联:使用 Condition 键和条件的逻辑 ID 在资源或输出中引用条件。或者,也可以在模板的其他部分(例如属性值)中使用 Fn::If 以根据条件设置值。有关更多信息,请参阅 使用 Condition 密钥

在创建或更新堆栈时,CloudFormation 会评估条件。CloudFormation 创建与成立的条件关联的实体,并忽略与不成立的条件关联的实体。在每个堆栈更新期间,CloudFormation 还会在修改任何资源之前重新评估这些条件。与 true 条件关联的实体将会更新,与 false 条件关联的实体将会删除。

重要

堆栈更新期间,您无法更新条件本身。您只能在包含添加、修改或删除资源的更改时更新条件。

条件内部函数

您可以使用以下内部函数定义条件:

注意

仅在模板的 ResourcesOutputs 部分中的元数据属性、更新策略属性和属性值中支持 Fn::If

使用 Condition 密钥

定义条件后,您可以使用 Condition 密钥将其应用于模板中的多个位置,例如 ResourcesOutputsCondition 密钥引用条件的逻辑名称并返回指定条件的评估结果。

将条件与资源关联

要有条件地创建资源,请添加 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 密钥引用其他条件。这使您能够通过组合多个条件来创建更复杂的条件逻辑。

在以下示例中,仅当 IsProductionIsProdAndFeatureEnabled 条件的评估结果为 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 密钥引用其他条件。只有当 IsProductionCreateBucket 条件的评估结果都为 true 时,才会创建策略。

注意

有关使用条件的更复杂的示例,请参阅《AWS CloudFormation模板参考指南》中的Condition 属性主题。