示例 模板
按条件为生产、开发或测试堆栈创建资源
在某些情况下,您可能需要创建类似但略有不同的堆栈。例如,您可能有一个用于生产应用程序的模板。您需要创建相同的生产堆栈来用于开发或测试。但是,对于开发和测试,您可能不需要生产级堆栈中包含的所有额外容量。您可以使用环境类型输入参数按条件创建特定于生产、开发或测试的堆栈资源,如以下示例所示:
例 JSON
{ "AWSTemplateFormatVersion" : "2010-09-09", "Mappings" : { "RegionMap" : { "us-east-1" : { "AMI" : "ami-0ff8a91507f77f867"}, "us-west-1" : { "AMI" : "ami-0bdb828fd58c52235"}, "us-west-2" : { "AMI" : "ami-a0cfeed8"}, "eu-west-1" : { "AMI" : "ami-047bb4163c506cd98"}, "sa-east-1" : { "AMI" : "ami-07b14488da8ea02a0"}, "ap-southeast-1" : { "AMI" : "ami-08569b978cc4dfa10"}, "ap-southeast-2" : { "AMI" : "ami-09b42976632b27e9b"}, "ap-northeast-1" : { "AMI" : "ami-06cd52961ce9f0d85"} } }, "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" : { "Fn::FindInMap" : [ "RegionMap", { "Ref" : "AWS::Region" }, "AMI" ]}, "InstanceType" : { "Fn::If" : [ "CreateProdResources", "c1.xlarge", {"Fn::If" : [ "CreateDevResources", "m1.large", "m1.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" Mappings: RegionMap: us-east-1: AMI: "ami-0ff8a91507f77f867" us-west-1: AMI: "ami-0bdb828fd58c52235" us-west-2: AMI: "ami-a0cfeed8" eu-west-1: AMI: "ami-047bb4163c506cd98" sa-east-1: AMI: "ami-07b14488da8ea02a0" ap-southeast-1: AMI: "ami-08569b978cc4dfa10" ap-southeast-2: AMI: "ami-09b42976632b27e9b" ap-northeast-1: AMI: "ami-06cd52961ce9f0d85" 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: !FindInMap [RegionMap, !Ref "AWS::Region", AMI] InstanceType: !If [CreateProdResources, c1.xlarge, !If [CreateDevResources, m1.large, m1.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
您可以为 prod
参数指定 dev
、test
或 EnvType
。对于每种环境类型,模板都指定一个不同的实例类型。实例类型范围可以从大型计算优化实例类型到小型通用实例类型。为了按条件指定实例类型,模板在模板的条件部分定义两个条件:CreateProdResources
,如果 EnvType
参数值等于 prod
,则计算为 true;CreateDevResources
,如果该参数值等于 dev
,则计算为 true。
在 InstanceType
属性中,该模板嵌套了两个 Fn::If
内部函数来确定使用哪个实例类型。如果 CreateProdResources
条件为 true,则实例类型为 c1.xlarge
。如果条件为 false,则计算 CreateDevResources
条件。如果 CreateDevResources
条件为 true,则实例类型为 m1.large
,否则实例类型为 m1.small
。
除实例类型之外,生产环境还向实例创建并附加一个 Amazon EC2 卷。MountPoint
和 NewVolume
资源与 CreateProdResources
条件相关联,目的是仅当条件计算为 true 时才创建资源。
按条件分配资源属性
在此示例中,您可以从快照创建 Amazon RDS 数据库实例。如果指定 DBSnapshotName
参数,CloudFormation 在创建数据库实例时将使用该参数值作为快照名称。如果您保留默认值(空字符串),CloudFormation 将删除 DBSnapshotIdentifier
属性并从头开始创建数据库实例。
该示例定义了 DBUser
和 DBPassword
参数并将其 NoEcho
属性设置为 true
。如果您将 NoEcho
属性设置为 true
,则对于描述堆栈或堆栈事件的任何调用,CloudFormation 返回使用星号 (*****) 遮蔽的参数值,但存储在下面指定位置的信息除外。
重要
使用 NoEcho
属性不会遮蔽在以下各区段中存储的任何信息:
-
Metadata
模板区段。CloudFormation 不会转换、修改或编辑您在Metadata
部分中包含的任何信息。有关更多信息,请参阅 CloudFormation 模板的 Metadata 部分语法参考。 -
Outputs
模板区段。有关更多信息,请参阅 CloudFormation 模板的 Outputs 部分语法参考。 -
资源定义的
Metadata
属性。有关更多信息,请参阅 Metadata 属性。
强烈建议您不要使用这些机制来包含敏感信息,例如密码。
重要
我们建议不要将敏感信息直接嵌入 CloudFormation 模板中,而应使用堆栈模板中的动态参数来引用在 CloudFormation 外部存储和管理的敏感信息,例如 Amazon Systems Manager Parameter Store 或 Amazon Secrets Manager 中的敏感信息。
有关更多信息,请参阅 请勿将凭证嵌入您的模板 最佳实践。
例 JSON
{ "AWSTemplateFormatVersion" : "2010-09-09", "Parameters": { "DBUser": { "NoEcho": "true", "Description" : "The database admin account username", "Type": "String", "MinLength": "1", "MaxLength": "16", "AllowedPattern" : "[a-zA-Z][a-zA-Z0-9]*", "ConstraintDescription" : "must begin with a letter and contain only alphanumeric characters." }, "DBPassword": { "NoEcho": "true", "Description" : "The database admin account password", "Type": "String", "MinLength": "1", "MaxLength": "41", "AllowedPattern" : "[a-zA-Z0-9]*", "ConstraintDescription" : "must contain only alphanumeric characters." }, "DBSnapshotName": { "Description": "The name of a DB snapshot (optional)", "Default": "", "Type": "String" } }, "Conditions": { "UseDBSnapshot": {"Fn::Not": [{"Fn::Equals" : [{"Ref" : "DBSnapshotName"}, ""]}]} }, "Resources" : { "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"} ] } } }, "MyRDSParamGroup" : { "Type": "AWS::RDS::DBParameterGroup", "Properties" : { "Family" : "MySQL5.5", "Description" : "CloudFormation Sample Database Parameter Group", "Parameters" : { "autocommit" : "1" , "general_log" : "1", "old_passwords" : "0" } } } } }
例 YAML
AWSTemplateFormatVersion: "2010-09-09" Parameters: DBUser: NoEcho: true Description: The database admin account username Type: String MinLength: 1 MaxLength: 16 AllowedPattern: "[a-zA-Z][a-zA-Z0-9]*" ConstraintDescription: must begin with a letter and contain only alphanumeric characters. DBPassword: NoEcho: true Description: The database admin account password Type: String MinLength: 1 MaxLength: 41 AllowedPattern: "[a-zA-Z0-9]*" ConstraintDescription: must contain only alphanumeric characters. DBSnapshotName: Description: The name of a DB snapshot (optional) Default: "" Type: String Conditions: UseDBSnapshot: !Not [!Equals [!Ref DBSnapshotName, ""]] Resources: 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"] MyRDSParamGroup: Type: "AWS::RDS::DBParameterGroup" Properties: Family: MySQL5.5 Description: CloudFormation Sample Database Parameter Group Parameters: autocommit: 1 general_log: 1 old_passwords: 0
仅当 DBSnapshotName
不是空字符串时,UseDBSnapshot
条件才计算为 true。如果 UseDBSnapshot
条件计算为 true,则 CloudFormation 对 DBSnapshotIdentifier
属性使用 DBSnapshotName
参数值。如果条件计算为 false,则 CloudFormation 删除 DBSnapshotIdentifier
属性。用作返回值时,AWS::NoValue
伪参数会删除相应的资源属性。
按条件使用现有资源
在此示例中,您可以使用已创建的 Amazon EC2 安全组或创建新的安全组,这是在模板中指定的。对于 ExistingSecurityGroup
参数,您可以指定 default
安全组名称或 NONE
。如果指定 default
,CloudFormation 将使用已经创建的名为 default
的安全组。如果指定 NONE
,则 CloudFormation 创建模板中定义的安全组。
例 JSON
{ "Parameters" : { "ExistingSecurityGroup" : { "Description" : "An existing security group ID (optional).", "Default" : "NONE", "Type" : "String", "AllowedValues" : ["default", "NONE"] } }, "Conditions" : { "CreateNewSecurityGroup" : {"Fn::Equals" : [{"Ref" : "ExistingSecurityGroup"}, "NONE"] } }, "Resources" : { "MyInstance" : { "Type" : "AWS::EC2::Instance", "Properties" : { "ImageId" : "ami-0ff8a91507f77f867", "SecurityGroups" : [{ "Fn::If" : [ "CreateNewSecurityGroup", {"Ref" : "NewSecurityGroup"}, {"Ref" : "ExistingSecurityGroup"} ] }] } }, "NewSecurityGroup" : { "Type" : "AWS::EC2::SecurityGroup", "Condition" : "CreateNewSecurityGroup", "Properties" : { "GroupDescription" : "Enable HTTP access via port 80", "SecurityGroupIngress" : [ { "IpProtocol" : "tcp", "FromPort" : 80, "ToPort" : 80, "CidrIp" : "0.0.0.0/0" } ] } } }, "Outputs" : { "SecurityGroupId" : { "Description" : "Group ID of the security group used.", "Value" : { "Fn::If" : [ "CreateNewSecurityGroup", {"Ref" : "NewSecurityGroup"}, {"Ref" : "ExistingSecurityGroup"} ] } } } }
例 YAML
Parameters: ExistingSecurityGroup: Description: An existing security group ID (optional). Default: NONE Type: String AllowedValues: - default - NONE Conditions: CreateNewSecurityGroup: !Equals [!Ref ExistingSecurityGroup, NONE] Resources: MyInstance: Type: "AWS::EC2::Instance" Properties: ImageId: "ami-0ff8a91507f77f867" SecurityGroups: !If [CreateNewSecurityGroup, !Ref NewSecurityGroup, !Ref ExistingSecurityGroup] NewSecurityGroup: Type: "AWS::EC2::SecurityGroup" Condition: CreateNewSecurityGroup Properties: GroupDescription: Enable HTTP access via port 80 SecurityGroupIngress: - IpProtocol: tcp FromPort: 80 ToPort: 80 CidrIp: 0.0.0.0/0 Outputs: SecurityGroupId: Description: Group ID of the security group used. Value: !If [CreateNewSecurityGroup, !Ref NewSecurityGroup, !Ref ExistingSecurityGroup]
为了确定是否创建 NewSecurityGroup
资源,该资源与 CreateNewSecurityGroup
条件关联。仅当条件为 true (当 ExistingSecurityGroup
参数等于 NONE
) 时,才会创建资源。
在 SecurityGroups
属性中,模板使用 Fn::If
内部函数确定要使用的安全组。如果 CreateNewSecurityGroup
条件计算为 true,则安全组属性引用 NewSecurityGroup
资源。如果 CreateNewSecurityGroup
条件计算为 false,则安全组属性引用 ExistingSecurityGroup
参数 (default
安全组)。
最后,模板按条件输出安全组 ID。如果 CreateNewSecurityGroup
条件的计算结果为 true,则 CloudFormation 输出 NewSecurityGroup
资源的安全组 ID。如果条件为 false,则 CloudFormation 输出 ExistingSecurityGroup
资源的安全组 ID。