Resources - AWS CloudFormation

Resources

Resources 部分是 CloudFormation 模板中必需具备的一个顶级部分,用于声明您希望 CloudFormation 在堆栈中预置和配置的 AWS 资源。

语法

Resources 部分使用以下语法:

JSON

"Resources" : { "LogicalResourceName1" : { "Type" : "AWS::ProductIdentifier::ResourceType", "Properties" : { "PropertyName1" : "PropertyValue1", ... } }, "LogicalResourceName2" : { "Type" : "AWS::ProductIdentifier::ResourceType", "Properties" : { "PropertyName1" : "PropertyValue1", ... } } }

YAML

Resources: LogicalResourceName1: Type: AWS::ProductIdentifier::ResourceType Properties: PropertyName1: PropertyValue1 ... LogicalResourceName2: Type: AWS::ProductIdentifier::ResourceType Properties: PropertyName1: PropertyValue1 ...

逻辑 ID(也称为逻辑名称

在 CloudFormation 模板中,资源由其逻辑资源名称来标识。这些名称必须为字母数字字符(A-Za-z0-9),并且在模板中必须唯一。逻辑名称用于引用模板其他部分中的资源。

资源类型

每个资源必须有一个 Type 属性,用于定义 AWS 资源的类型。Type 属性的格式为 AWS::ProductIdentifier::ResourceType。例如,Amazon S3 存储桶的 Type 属性为 AWS::S3::Bucket

有关受支持的资源类型的完整列表,请参阅 AWS 资源和属性类型参考

资源属性

资源属性是可以指定的附加选项,用于定义特定资源类型的详细配置。某些属性是必需的,而另一些属性则是可选的。有些属性具有默认值,因此指定这些属性是可选的。

要详细了解对于每个资源类型支持的属性,请参阅 AWS 资源和属性类型参考中的相关主题。

属性值可以是文本字符串、字符串列表、布尔值、动态引用、参数引用、伪引用或者函数返回的值。以下示例演示了如何声明不同的属性值类型:

JSON

"Properties" : { "String" : "A string value", "Number" : 123, "LiteralList" : [ "first-value", "second-value" ], "Boolean" : true }

YAML

Properties: String: A string value Number: 123 LiteralList: - first-value - second-value Boolean: true

物理 ID

除了逻辑 ID 外,某些资源还有物理 ID,这是资源的实际分配名称,如 EC2 实例 ID 或 S3 存储桶名称。使用物理 ID 来标识 CloudFormation 模板外部的资源,但只能在创建了资源之后进行。例如,假设您为一个 EC2 实例资源指定 MyEC2Instance 的逻辑 ID。当 CloudFormation 创建实例时,CloudFormation 会自动生成物理 ID(如 i-1234567890abcdef0)并将其分配给该实例。您可以使用该物理 ID 来标识实例,可以使用 Amazon EC2 控制台查看其属性 (如 DNS 名称)。

对于 Amazon S3 存储桶和许多其他资源,如果您没有明确指定实体名称,CloudFormation 会自动为该资源生成唯一的实体名称。该实体名称基于 CloudFormation 堆栈的名称、在 CloudFormation 模板中指定的资源逻辑名称和唯一 ID 的组合。例如,假设您在名为 MyStack 的堆栈中有一个逻辑名称为 MyBucket 的 Amazon S3 存储桶,CloudFormation 可能会使用如下物理名称 MyStack-MyBucket-abcdefghijk1 来命名该存储桶。

对于支持自定义名称的资源,您可以分配自己的物理名称来帮助快速标识资源。例如,您可以将存储日志的 S3 存储桶命名为 MyPerformanceLogs。有关更多信息,请参阅 名称类型

引用资源

您经常会需要根据一个资源的名称或属性来设置另一个资源的属性。例如,您可以创建一个使用 EC2 安全组的 EC2 实例,或由 S3 存储桶支持的 CloudFront 分配。所有这些资源都可在同一 CloudFormation 模板中创建。

CloudFormation 提供了内置函数,您可以使用这些函数来引用其他资源及其属性。这些函数让您可以在资源之间创建依赖关系,并将一个资源的值传递到另一个资源。

Ref 函数

Ref 函数通常用于检索在同一 CloudFormation 模板中定义的资源的标识属性。具体返回的值取决于资源的类型。对于大多数资源,该函数会返回资源的实体名称。不过对于某些资源类型,该函数可能会返回其他的值,例如 AWS::EC2::EIP 资源的 IP 地址或 Amazon SNS 主题的 Amazon 资源名称(ARN)。

以下示例演示了如何在属性中使用 Ref 函数。在以下的每个示例中,Ref 函数都将返回模板中其他部分声明的 LogicalResourceName 资源的实际名称。YAML 示例中的 !Ref 语法示例只是编写 Ref 函数的较简单方法。

JSON

"Properties" : { "PropertyName" : { "Ref" : "LogicalResourceName" } }

YAML

Properties: PropertyName1: Ref: LogicalResourceName PropertyName2: !Ref LogicalResourceName

有关 Ref 函数的更多详细信息,请参阅 Ref 函数。

Fn::GetAtt 函数

如果参数或为资源返回的值正是您需要的,则 Ref 函数会非常实用。不过,您可能需要资源的其他属性。例如,如果您想创建一个具有 S3 起始地址的 CloudFront 分配,就需要使用 DNS 样式的地址来指定存储桶的位置。很多资源都具有附加属性,您可以在模板中使用这些属性的值。要获取这些属性,请使用 Fn::GetAtt 函数。

以下示例演示了如何在属性中使用 GetAtt 函数。Fn::GetAtt 函数有两个参数,分别是资源的逻辑名称和要检索的属性名称。YAML 示例中的 !GetAtt 语法示例只是编写 GetAtt 函数的较简单方法。

JSON

"Properties" : { "PropertyName" : { "Fn::GetAtt" : [ "LogicalResourceName", "AttributeName" ] } }

YAML

Properties: PropertyName1: !GetAtt LogicalResourceName.AttributeName PropertyName2: Fn::GetAtt: - LogicalResourceName - AttributeName

有关使用 GetAtt 函数的更多详细信息,请参阅 Fn::GetAtt

示例

以下示例演示了如何声明资源以及 CloudFormation 模板会如何引用在同一模板中定义的其他资源以及现有的 AWS 资源。

使用自定义名称声明单个资源

以下示例声明了 AWS::S3::Bucket 类型的单个资源,逻辑名称为 MyBucketBucketName 属性设置为 amzn-s3-demo-bucket,因此应替换为您的 S3 存储桶所需的名称。

如果您使用此资源声明创建堆栈,CloudFormation 将使用默认设置创建 Amazon S3 存储桶。对于 Amazon EC2 实例或自动扩缩组等其他资源,CloudFormation 需要更多信息。

JSON

{ "Resources": { "MyBucket": { "Type": "AWS::S3::Bucket", "Properties": { "BucketName": "amzn-s3-demo-bucket" } } } }

YAML

Resources: MyBucket: Type: 'AWS::S3::Bucket' Properties: BucketName: amzn-s3-demo-bucket

使用 Ref 函数引用其他资源

以下示例演示的资源声明定义了一个 EC2 实例和安全组。Ec2Instance 资源使用 Ref 函数引用 InstanceSecurityGroup 资源,以作为其 SecurityGroupIds 属性的一部分。此外还包括未在模板中声明的一个现有安全组 (sg-12a4c434)。您可以使用文字字符串来指代现有 AWS 资源。

JSON

{ "Resources": { "Ec2Instance": { "Type": "AWS::EC2::Instance", "Properties": { "SecurityGroupIds": [ { "Ref": "InstanceSecurityGroup" }, "sg-12a4c434" ], "KeyName": "MyKey", "ImageId": "ami-1234567890abcdef0" } }, "InstanceSecurityGroup": { "Type": "AWS::EC2::SecurityGroup", "Properties": { "GroupDescription": "Enable SSH access via port 22", "SecurityGroupIngress": [ { "IpProtocol": "tcp", "FromPort": 22, "ToPort": 22, "CidrIp": "0.0.0.0/0" } ] } } } }

YAML

Resources: Ec2Instance: Type: 'AWS::EC2::Instance' Properties: SecurityGroupIds: - !Ref InstanceSecurityGroup - sg-12a4c434 KeyName: MyKey ImageId: ami-1234567890abcdef0 InstanceSecurityGroup: Type: 'AWS::EC2::SecurityGroup' Properties: GroupDescription: Enable SSH access via port 22 SecurityGroupIngress: - IpProtocol: tcp FromPort: 22 ToPort: 22 CidrIp: 0.0.0.0/0

使用 Fn::GetAtt 函数引用资源属性

以下示例演示的资源声明定义了一个 CloudFront 分配资源和一个 S3 存储桶。MyDistribution 资源指定了 MyBucket 资源的 DNS 名称,后者使用 Fn::GetAtt 函数来获取存储桶的 DomainName 属性。Fn::GetAtt 函数会在一个数组中列出这两个参数。对于采用多个参数的函数,可以使用数组来指定其参数。

JSON

{ "Resources": { "MyBucket": { "Type": "AWS::S3::Bucket" }, "MyDistribution": { "Type": "AWS::CloudFront::Distribution", "Properties": { "DistributionConfig": { "Origins": [ { "DomainName": { "Fn::GetAtt": [ "MyBucket", "DomainName" ] }, "Id": "MyS3Origin", "S3OriginConfig": {} } ], "Enabled": "true", "DefaultCacheBehavior": { "TargetOriginId": "MyS3Origin", "ForwardedValues": { "QueryString": "false" }, "ViewerProtocolPolicy": "allow-all" } } } } } }

YAML

Resources: MyBucket: Type: 'AWS::S3::Bucket' MyDistribution: Type: 'AWS::CloudFront::Distribution' Properties: DistributionConfig: Origins: - DomainName: !GetAtt - MyBucket - DomainName Id: MyS3Origin S3OriginConfig: {} Enabled: 'true' DefaultCacheBehavior: TargetOriginId: MyS3Origin ForwardedValues: QueryString: 'false' ViewerProtocolPolicy: allow-all