1. 部署堆栈
模板文件 vpc-1.yaml:
AWSTemplateFormatVersion: 2010-09-09Description: Deploy a VPCResources:VPC:Type: AWS::EC2::VPCProperties:CidrBlock: 10.0.0.0/16EnableDnsHostnames: trueTags:- Key: NameValue: Lab VPCInternetGateway:Type: AWS::EC2::InternetGatewayProperties:Tags:- Key: NameValue: Lab Internet GatewayAttachGateway:Type: AWS::EC2::VPCGatewayAttachmentProperties:VpcId: !Ref VPCInternetGatewayId: !Ref InternetGatewayPublicSubnet1:Type: AWS::EC2::SubnetProperties:VpcId: !Ref VPCCidrBlock: 10.0.0.0/24AvailabilityZone: !Select- '0'- !GetAZs ''Tags:- Key: NameValue: Public Subnet 1PrivateSubnet1:Type: AWS::EC2::SubnetProperties:VpcId: !Ref VPCCidrBlock: 10.0.1.0/24AvailabilityZone: !Select- '0'- !GetAZs ''Tags:- Key: NameValue: Private Subnet 1PublicRouteTable:Type: AWS::EC2::RouteTableProperties:VpcId: !Ref VPCTags:- Key: NameValue: Public Route TablePublicRoute:Type: AWS::EC2::RouteProperties:RouteTableId: !Ref PublicRouteTableDestinationCidrBlock: 0.0.0.0/0GatewayId: !Ref InternetGatewayPublicSubnetRouteTableAssociation1:Type: AWS::EC2::SubnetRouteTableAssociationProperties:SubnetId: !Ref PublicSubnet1RouteTableId: !Ref PublicRouteTablePrivateRouteTable:Type: AWS::EC2::RouteTableProperties:VpcId: !Ref VPCTags:- Key: NameValue: Private Route TablePrivateSubnetRouteTableAssociation1:Type: AWS::EC2::SubnetRouteTableAssociationProperties:SubnetId: !Ref PrivateSubnet1RouteTableId: !Ref PrivateRouteTableOutputs:VPC:Description: VPCValue: !Ref VPCAZ1:Description: Availability Zone 1Value: !GetAtt- PublicSubnet1- AvailabilityZone



2. 检查 VPC
在此,我们将检查创建的 VPC 资源以及创建资源的 CloudFormation 模板的代码。
以下是 CloudFormation 创建的资源:
- Amazon VPC
- Internet Gateway
- 2 个 Subnet
- 2 个 Route Table
这些资源都位于一个可用区中。可用区是区域内的一个隔离位置,由一个或多个数据中心组成。
2.1 LabVPC
VPC 是 AWS 云的一个隔离部分,它允许资源互相通信,并有选择的与 Internet 通信。
“详细信息“显示 IPv4 CIDR ,这是分配给 VPC 的 IP 地址范围。此 VPC 的 CIDR 为 10.0.0.0/16 ,这意味着它包含所有以 10.0.x.x 的开头的 IP 地址。
Resources:VPC:Type: AWS::EC2::VPCProperties:CidrBlock: 10.0.0.0/16EnableDnsHostnames: trueTags:- Key: NameValue: Lab VPC
上面代码中的 Type 声明了 CloudFormation 创建的资源的类型。然后, Properties 部分指定有关要创建的资源的信息:
CidrBlock:与 VPC 关联的 IP 地址范围;EnableDnsHostnames:为 VPC 中的 EC2 实例开启 DNS 域名功能;Tag:向资源添加一个友好名称;
2.2 Internet 网关
Internet 网关有两个目的:
- 在 VPC 路由表中为可路由 Internet 的流量提供目标;
- 对已分配了公共 IPv4 地址的 EC2 实例执行网路地址转换(NAT);
以下是创建此 Internet 网关的模板中的代码:
InternetGateway:Type: AWS::EC2::InternetGatewayProperties:Tags:- Key: NameValue: Lab Internet Gateway
在控制台中,Internet 网关显示它已连接到 VPC:
这是通过模板中的以下代码完成的:
AttachGateway:Type: AWS::EC2::VPCGatewayAttachmentProperties:VpcId: !Ref VPCInternetGatewayId: !Ref InternetGateway
VPC 的 AttachGateway 在 VPC 和网关之间创建关系。
:::info
注意:模板使用 !Ref 关键字引用模板中的其他元素,后跟另一个资源的名称。这样,仅通过引用资源名称就可以轻松构件相互链接的资源。
:::
2.3 子网
将出现两个子网:
- Public Subnet 1:通过 Internet 网关连接到 Internet,可由需要公共访问的资源使用;
- Private Subnet 1:未连接到互联网。无法从 Internet 到达此子网中的任何资源,从而为这些资源提供了额外的安全性;

以下是模板中创建子网的代码:
- VpcId:包含子网的 VPC;
- CidrBlock:分配给子网的 IP 地址范围;
AvailabilityZone:定义区域内的哪个物理位置应包含子网; :::info 可用区使用一个名为
!Select的函数和一个名为!GetAZs的函数,它们会检索该区域内的可用区列表,并引用该列表中的第一个元素。
以这种方式,该模板可以在任何区域中使用,因为它在运行时检索可用区列表,而不是在模板中对可用区进行硬编码。 :::PublicSubnet1:Type: AWS::EC2::SubnetProperties:VpcId: !Ref VPCCidrBlock: 10.0.0.0/24AvailabilityZone: !Select- '0'- !GetAZs ''Tags:- Key: NameValue: Public Subnet 1PrivateSubnet1:Type: AWS::EC2::SubnetProperties:VpcId: !Ref VPCCidrBlock: 10.0.1.0/24AvailabilityZone: !Select- '0'- !GetAZs ''Tags:- Key: NameValue: Private Subnet 1
2.4 路由表
路由表用于将流量路由进出子网。该路由表(Public Route Table)的配置为:
- 对 VPC(10.0.0.0/16)中的流量,将在本地路由流量;
- 对于去往 Internet(0.0.0.0/0)的流量,将流量路由到 Internet 网关(igw-*);

以下时模板中创建 Public Route Table 的代码:
PublicRouteTable:Type: AWS::EC2::RouteTableProperties:VpcId: !Ref VPCTags:- Key: NameValue: Public Route Table
Private Route Table 也有类似的代码。
以下是在 Public Route Table 中定义到 Internet 的路由的代码:
PublicRoute:Type: AWS::EC2::RouteProperties:RouteTableId: !Ref PublicRouteTableDestinationCidrBlock: 0.0.0.0/0GatewayId: !Ref InternetGateway
路由的配置为:
- RouteTableId:表示拥有路由的路由表;
- DestinationCidrBlock:定义此路由规则的 IP 地址范围(其中0.0.0.0/0表示绑定到 Internet 的流量);
- GatewayId:定义将流量路由到何处,这种情况下,它是模板前面定义的 Internet 网关;
仅为 Public Route Table 配置了此路由,这就是使它成为 public 的原因。
2.5 子网关联
控制台中显示 Public Route Table 与 Public Subnet 1 关联。
路由表可以与多个子网关联,每个关联都需要有明确的链接。
以下是定义此链接的代码:
PublicSubnetRouteTableAssociation1:Type: AWS::EC2::SubnetRouteTableAssociationProperties:SubnetId: !Ref PublicSubnet1RouteTableId: !Ref PublicRouteTable
2.6 Outputs
模板在 Outputs 部分返回了有关其创建的资源的信息:
- VPC 是已创建的 VPC 的 ID;
AZ1 显示了在其中创建子网的可用区;
Outputs:VPC:Description: VPCValue: !Ref VPCAZ1:Description: Availability Zone 1Value: !GetAtt- PublicSubnet1- AvailabilityZone
VPC 输出只是对 VPC 的引用,从而显示 VPC ID;
AZ1 输出使用!GetAtt函数检索资源的属性。在这种情况下,它将从 Public Subnet 1 检索 AvaiabilityZone 属性。
3. 更新堆栈
部署堆栈后,建议对资源的任何更改都应通过 CloudFormation 进行,而不是直接修改资源。
在此部分将使用新的模板,更新堆栈,该模板定义了以下资源:
第二个 Public 和 Private Subnet 已添加到另一个可用区中。这也是最佳做法,确保你的资源可以在多个可用区(数据中心)中运行,以确保系统出现故障时具有高可用性。
模板文件 vpc-2.yaml:
AWSTemplateFormatVersion: 2010-09-09Description: Deploy a VPCResources:VPC:Type: AWS::EC2::VPCProperties:CidrBlock: 10.0.0.0/16EnableDnsHostnames: trueTags:- Key: NameValue: Lab VPCInternetGateway:Type: AWS::EC2::InternetGatewayProperties:Tags:- Key: NameValue: Lab Internet GatewayAttachGateway:Type: AWS::EC2::VPCGatewayAttachmentProperties:VpcId: !Ref VPCInternetGatewayId: !Ref InternetGatewayPublicSubnet1:Type: AWS::EC2::SubnetProperties:VpcId: !Ref VPCCidrBlock: 10.0.0.0/24AvailabilityZone: !Select- '0'- !GetAZs ''Tags:- Key: NameValue: Public Subnet 1PrivateSubnet1:Type: AWS::EC2::SubnetProperties:VpcId: !Ref VPCCidrBlock: 10.0.1.0/24AvailabilityZone: !Select- '0'- !GetAZs ''Tags:- Key: NameValue: Private Subnet 1PublicSubnet2:Type: AWS::EC2::SubnetProperties:VpcId: !Ref VPCCidrBlock: 10.0.2.0/24AvailabilityZone: !Select [1, !GetAZs '']Tags:- Key: NameValue: Public Subnet 2PrivateSubnet2:Type: AWS::EC2::SubnetProperties:VpcId: !Ref VPCCidrBlock: 10.0.3.0/24AvailabilityZone: !Select [1, !GetAZs '']Tags:- Key: NameValue: Private Subnet 2PublicRouteTable:Type: AWS::EC2::RouteTableProperties:VpcId: !Ref VPCTags:- Key: NameValue: Public Route TablePublicRoute:Type: AWS::EC2::RouteProperties:RouteTableId: !Ref PublicRouteTableDestinationCidrBlock: 0.0.0.0/0GatewayId: !Ref InternetGatewayPublicSubnetRouteTableAssociation1:Type: AWS::EC2::SubnetRouteTableAssociationProperties:SubnetId: !Ref PublicSubnet1RouteTableId: !Ref PublicRouteTablePublicSubnetRouteTableAssociation2:Type: AWS::EC2::SubnetRouteTableAssociationProperties:SubnetId: !Ref PublicSubnet2RouteTableId: !Ref PublicRouteTablePrivateRouteTable:Type: AWS::EC2::RouteTableProperties:VpcId: !Ref VPCTags:- Key: NameValue: Private Route TablePrivateSubnetRouteTableAssociation1:Type: AWS::EC2::SubnetRouteTableAssociationProperties:SubnetId: !Ref PrivateSubnet1RouteTableId: !Ref PrivateRouteTablePrivateSubnetRouteTableAssociation2:Type: AWS::EC2::SubnetRouteTableAssociationProperties:SubnetId: !Ref PrivateSubnet2RouteTableId: !Ref PrivateRouteTableOutputs:VPC:Description: VPCValue: !Ref VPCAZ1:Description: Availability Zone 1Value: !GetAtt- PublicSubnet1- AvailabilityZoneAZ2:Description: Availability Zone 2Value: !GetAtt- PublicSubnet2- AvailabilityZone

预览更改集:
它将创建两个新的子网,此外,将添加两个路由表关联,以将这些子网与其响应的路由表关联。

现在显示有 VPC 中有四个子网了。VPC 现在已更新以支持高可用性能的应用程序。
4. CloudFormation Designer 中查看堆栈
Designer 是用于创建,查看和修改 AWS CloudFormation 模板的图形工具。使用 Designer,可以使用拖放界面来绘制模板资源图,然后使用集成的 JSON 或 YAML 编辑器来编辑其详细信息。

在组成部分选项卡,单击图中的一些元素:
- 窗口的下部显示模板中定义资源的代码;
- 箭头显示资源之间的关系,例如与子网关联的路由表;
5. 删除堆栈
删除堆栈,会删除堆栈中所有创建的资源,但是 CloudFormation 自动创建的用于上传模板的 S3 Bucket 是需要另外手动删除的。
