使用 AWS CloudFormation Designer 修改堆栈的模板
注意
CloudFormation 控制台模式下的基础设施编辑器是对 AWS CloudFormation Designer 功能的一项改进。建议您尽可能使用基础设施编辑器,而不使用 Designer。有关更多信息,请参阅 使用基础设施编辑器直观地创建模板。
您可以使用 AWS CloudFormation Designer 修改堆栈模板,然后将其提交到 AWS CloudFormation 以更新堆栈。通常,在修改堆栈时,您需要获取其模板的副本,在文本编辑器中修改模板,然后使用 CloudFormation 更新堆栈。借助 AWS CloudFormation Designer,您可以快速获取任何正在运行的堆栈的模板副本,修改该模板,然后更新堆栈,而不必离开控制台。
在此演练中,我们从一个基本 Web 服务器堆栈开始,然后修改它,以使该 Web 服务器可扩展且持久。
在此演练中,我们将完成以下步骤:
-
我们将获取正在运行的堆栈的模板副本 - 与以下演练中的基本 Web 服务器堆栈相同:使用 AWS CloudFormation Designer 创建基本 Web 服务器。
-
我们将使用 AWS CloudFormation Designer 修改此堆栈的模板(用自动扩缩组和 Elastic Load Balancing 负载均衡器替换 EC2 实例),以使您的网站可扩展且持久。
-
保存修改后,我们将用修改的模板更新此基本 Web 服务器堆栈。
注意
CloudFormation 是一种免费服务;但是,您需要为您在堆栈使用的 AWS 资源付费,费用按每种资源的现价收取。有关 AWS 定价的详细信息,请参阅 http://aws.amazon.com
上每种产品的详细信息页。 -
我们将删除堆栈,以清理所有资源。
先决条件
本演练假定您具有 Amazon Virtual Private Cloud (Amazon VPC)、Auto Scaling、Elastic Load Balancing 和 CloudFormation 方面的工作经验。为了解上下文,每个过程提供了有关每项资源的一些基本信息。
此外,本演练还假定您已完成下面的演练:使用 AWS CloudFormation Designer 创建基本 Web 服务器。在上述演练中,您应该获得了一个名为 BasicWebServerStack
的正在运行的堆栈。
步骤 1:获取堆栈模板
在此步骤中,我们将使用 AWS CloudFormation Designer 获取正在运行的堆栈的模板副本并将其打开。
获取正在运行的堆栈的模板副本
-
通过以下网址打开 CloudFormation 控制台:https://console.aws.amazon.com/cloudformation/
。 -
从堆栈列表中,选择
BasicWebServerStack
。 -
依次选择 Actions、View/Edit template in Designer。
CloudFormation 获取 BasicWebServerStack
堆栈的模板副本并在 AWS CloudFormation Designer 中显示它,您可以在其中看到该模板的资源及其关系。在下一步中,我们将使用 AWS CloudFormation Designer 修改该模板。
步骤 2:修改模板
我们将使用 AWS CloudFormation Designer 的拖放界面和集成的 JSON 和 YAML 编辑器修改基本 Web 服务器模板,即,将单个 Amazon EC2 实例替换为自动扩缩组和负载均衡器以使网站可扩展。如果网站的流量突然增多,则使用 Auto Scaling 可快速增加 Web 服务器的数量。负载均衡器会将流量均匀地分配到多个实例上。
修改堆栈模板
-
删除
WebServerInstance
资源。-
右键单击
WebServerInstance
资源。 -
从资源菜单中选择删除(垃圾桶图标)。
-
选择 OK 确认。
-
-
从 Resource types 窗格中,将以下资源添加到
PublicSubnet
资源中:AutoScalingGroup、LaunchConfiguration 和 LoadBalancer。添加资源前,您可能需要扩展子网以包含所有资源。资源按资源类别组织。自动扩缩组和启动配置位于 AutoScaling 类别中,负载均衡器位于 ElasticLoadBalancing 类别中。
注意
这些资源不遵守容器模型,因此,AWS CloudFormation Designer 不会将它们自动关联到子网。我们会在此步骤的稍后部分创建连接。
-
从 EC2 类别的 Resource types 窗格,将 SecurityGroup 资源添加到 VPC 中的任意位置,但不要加入到子网中。
此安全组将负责控制负载均衡器的入站和出站通信。
-
重命名资源以使其更易识别:
-
将 AutoScalingGroup 重命名为
WebServerFleet
-
将 LaunchConfiguration 重命名为
WebServerLaunchConfig
-
将 LoadBalancer 重命名为
PublicElasticLoadBalancer
-
将 SecurityGroup 重命名为
PublicLoadBalancerSecurityGroup
-
-
为添加的资源创建关联。
-
将负载均衡器和自动扩缩组资源关联到公有子网:
-
从
PublicElasticLoadBalancer
资源拖动到AWS::EC2::Subnet (Property: Subnets)
资源的PublicSubnet
连接。 -
从
WebServerFleet
资源拖动到AWS::EC2::Subnet (Property: VPCZoneIdentifier)
资源的PublicSubnet
连接。
-
-
将负载均衡器关联到其安全组:
-
从
PublicElasticLoadBalancer
资源拖动到AWS::EC2::SecurityGroup (Property: SecurityGroups)
资源的PublicLoadBalancerSecurityGroup
连接。
-
-
将自动扩缩组关联到负载均衡器和启动配置:
-
从
WebServerFleet
资源拖动到AWS::ElasticLoadBalancing::LoadBalancer (Property: LoadBalancerNames)
资源的PublicElasticLoadBalancer
连接。 -
从
WebServerFleet
资源拖动到AWS::ElasticLoadBalancing::LaunchConfiguration (Property: LaunchConfigurationName)
资源的WebServerLaunchConfig
连接。
-
-
将启动配置关联到安全组:
-
从
WebServerLaunchConfig
资源拖动到AWS::EC2::SecurityGroup (Property: SecurityGroups)
资源的WebServerSecurityGroup
连接。
-
-
为自动扩缩组定义对公有路由的依赖关系:
-
从
WebServerFleet
资源拖动到DependsOn
资源的PublicRoute
连接。
该依赖关系意味着,在公有路由完成之前,CloudFormation 不会创建
WebServerFleet
资源。否则,如果公有路由在 Web 服务器实例启动时不可用,这些实例将无法在配置和应用程序部署完成时发送信号 (使用 cfn-signal 帮助程序脚本) 通知 CloudFormation。 -
-
-
为添加的资源指定属性。
-
在 AWS CloudFormation Designer 画布上,选择
PublicElasticLoadBalancer
资源。 -
在集成编辑器窗格中,选择属性选项卡,然后复制以下代码段并将其粘贴到属性 大括号 (
{}
) 之间。AWS CloudFormation Designer 会自动添加安全组和子网关联,因此,您只需要添加
Listeners
和HealthCheck
属性。Listeners
属性指定侦听位置及侦听何种类型的流量,HealthCheck
属性描述确定负载均衡器运行状况的设置。JSON
"Listeners": [ { "LoadBalancerPort": "80", "InstancePort": "80", "Protocol": "HTTP" } ], "HealthCheck": { "Target": "HTTP:80/", "HealthyThreshold": "3", "UnhealthyThreshold": "5", "Interval": "90", "Timeout": "60" }, "SecurityGroups": [ { "Ref": "PublicLoadBalancerSecurityGroup" } ], "Subnets": [ { "Ref": "PublicSubnet" } ]
YAML
Listeners: - LoadBalancerPort: '80' InstancePort: '80' Protocol: HTTP HealthCheck: Target: 'HTTP:80/' HealthyThreshold: '3' UnhealthyThreshold: '5' Interval: '90' Timeout: '60' SecurityGroups: - !Ref PublicLoadBalancerSecurityGroup Subnets: - !Ref PublicSubnet
-
为以下资源重复这一过程:
WebServerFleet
-
添加
MaxSize
、MinSize
和DesiredCapacity
属性。这些属性指定您可在自动扩缩组中启动的最大、最小实例数及初始启动的实例数。所需容量值通过一个新的参数指定,我们将在此过程的稍后部分添加该参数。JSON
"MinSize": "1", "MaxSize": "10", "DesiredCapacity": { "Ref": "WebServerCount" }, "VPCZoneIdentifier": [ { "Ref": "PublicSubnet" } ], "LaunchConfigurationName": { "Ref": "WebServerLaunchConfig" }, "LoadBalancerNames": [ { "Ref": "PublicElasticLoadBalancer" } ]
YAML
MinSize: '1' MaxSize: '10' DesiredCapacity: !Ref WebServerCount VPCZoneIdentifier: - !Ref PublicSubnet LaunchConfigurationName: !Ref WebServerLaunchConfig LoadBalancerNames: - !Ref PublicElasticLoadBalancer
PublicLoadBalancerSecurityGroup
-
添加以下入站和出站规则,用以确定可到达和离开负载均衡器的流量。这些规则允许所有 HTTP 流量到达和离开负载均衡器。
JSON
"GroupDescription": "Public Elastic Load Balancing security group with HTTP access on port 80 from the Internet", "SecurityGroupIngress": [ { "IpProtocol": "tcp", "FromPort": 80, "ToPort": 80, "CidrIp": "0.0.0.0/0" } ], "SecurityGroupEgress": [ { "IpProtocol": "tcp", "FromPort": 80, "ToPort": 80, "CidrIp": "0.0.0.0/0" } ], "VpcId": { "Ref": "VPC" }
YAML
GroupDescription: >- Public Elastic Load Balancing security group with HTTP access on port 80 from the Internet SecurityGroupIngress: - IpProtocol: tcp FromPort: 80 ToPort: 80 CidrIp: 0.0.0.0/0 SecurityGroupEgress: - IpProtocol: tcp FromPort: 80 ToPort: 80 CidrIp: 0.0.0.0/0 VpcId: !Ref VPC
WebServerSecurityGroup
-
修改 HTTP 入站规则,仅允许来自负载均衡器的流量。
JSON
"GroupDescription": "Allow access from load balancer and SSH traffic", "SecurityGroupIngress": [ { "IpProtocol": "tcp", "FromPort": 80, "ToPort": 80, "SourceSecurityGroupId": { "Ref": "PublicLoadBalancerSecurityGroup" } }, { "IpProtocol": "tcp", "FromPort": 22, "ToPort": 22, "CidrIp": { "Ref": "SSHLocation" } } ], "VpcId": { "Ref": "VPC" }
YAML
VpcId: !Ref VPC GroupDescription: Allow access from load balancer and SSH traffic SecurityGroupIngress: - IpProtocol: tcp FromPort: 80 ToPort: 80 SourceSecurityGroupId: !Ref PublicLoadBalancerSecurityGroup - IpProtocol: tcp FromPort: 22 ToPort: 22 CidrIp: !Ref SSHLocation
WebServerLaunchConfig
-
启动配置有很多需要指定的不同属性,我们只重点介绍其中几个属性。
InstanceType
和ImageId
属性使用已在模板中指定的参数和映射值。创建堆栈时,需要以参数值的形式指定实例类型。ImageId
值是基于堆栈区域和指定的实例类型的映射。在
UserData
属性中,我们指定在实例启动并运行后运行的配置脚本。配置信息均在实例的元数据中定义 (我们将在下一步中添加)。JSON
"InstanceType": { "Ref": "InstanceType" }, "ImageId": { "Fn::FindInMap": [ "AWSRegionArch2AMI", { "Ref": "AWS::Region" }, { "Fn::FindInMap": [ "AWSInstanceType2Arch", { "Ref": "InstanceType" }, "Arch" ] } ] }, "KeyName": { "Ref": "KeyName" }, "AssociatePublicIpAddress": "true", "UserData": { "Fn::Base64": { "Fn::Join": [ "", [ "#!/bin/bash -xe\n", "yum install -y aws-cfn-bootstrap\n", "# Install the files and packages from the metadata\n", "/opt/aws/bin/cfn-init -v ", " --stack ", { "Ref": "AWS::StackName" }, " --resource WebServerLaunchConfig ", " --configsets All ", " --region ", { "Ref": "AWS::Region" }, "\n", "# Signal the status from cfn-init\n", "/opt/aws/bin/cfn-signal -e $? ", " --stack ", { "Ref": "AWS::StackName" }, " --resource WebServerFleet ", " --region ", { "Ref": "AWS::Region" }, "\n" ] ] } }, "SecurityGroups": [ { "Ref": "WebServerSecurityGroup" } ]
YAML
InstanceType: !Ref InstanceType ImageId: !FindInMap - AWSRegionArch2AMI - !Ref 'AWS::Region' - !FindInMap - AWSInstanceType2Arch - !Ref InstanceType - Arch KeyName: !Ref KeyName AssociatePublicIpAddress: 'true' UserData: !Base64 'Fn::Join': - '' - - | #!/bin/bash -xe - | yum install -y aws-cfn-bootstrap - | # Install the files and packages from the metadata - '/opt/aws/bin/cfn-init -v ' - ' --stack ' - !Ref 'AWS::StackName' - ' --resource WebServerLaunchConfig ' - ' --configsets All ' - ' --region ' - !Ref 'AWS::Region' - |+ - | # Signal the status from cfn-init - '/opt/aws/bin/cfn-signal -e $? ' - ' --stack ' - !Ref 'AWS::StackName' - ' --resource WebServerFleet ' - ' --region ' - !Ref 'AWS::Region' - |+ SecurityGroups: - !Ref WebServerSecurityGroup
-
-
将启动配置元数据添加到
WebServerLaunchConfig
资源,指示 cfn-init 帮助程序脚本启动 Web 服务器并创建基本网页。-
选择
WebServerLaunchConfig
资源,然后在集成编辑器中选择元数据选项卡。 -
如果以 JSON 格式编写模板:在
Metadata
括号 ({}
) 内、AWS::CloudFormation::Designer
右括号后面添加一个逗号 (,
)。 -
在
AWS::CloudFormation::Designer
属性后添加下面的代码段,指示 cfn-init 帮助程序脚本启动 Web 服务器并创建基本网页。JSON
"AWS::CloudFormation::Init" : { "configSets" : { "All" : [ "ConfigureSampleApp" ] }, "ConfigureSampleApp" : { "packages" : { "yum" : { "httpd" : [] } }, "files" : { "/var/www/html/index.html" : { "content" : { "Fn::Join" : ["\n", [ "<h1>Congratulations, you have successfully launched the AWS CloudFormation sample.</h1>" ]]}, "mode" : "000644", "owner" : "root", "group" : "root" } }, "services" : { "sysvinit" : { "httpd" : { "enabled" : "true", "ensureRunning" : "true" } } } } }
YAML
'AWS::CloudFormation::Init': configSets: All: - ConfigureSampleApp ConfigureSampleApp: packages: yum: httpd: [] files: /var/www/html/index.html: content: !Join - |+ - - >- <h1>Congratulations, you have successfully launched the AWS CloudFormation sample.</h1> mode: '000644' owner: root group: root services: sysvinit: httpd: enabled: 'true' ensureRunning: 'true'
-
-
添加
WebServerCount
参数。该参数指定在 CloudFormation 创建自动扩缩组时要创建多少个实例。-
选择 AWS CloudFormation Designer 画布上的空白区域。
-
在集成编辑器窗格中,选择参数选项卡。
-
在 集成编辑器 中添加以下参数。如果以 JSON 格式编写模板,请根据需要添加逗号。
JSON
"WebServerCount": { "Description": "Number of Amazon EC2 instances to launch for the WebServer server", "Type": "Number", "Default": "1" }
YAML
WebServerCount: Description: Number of Amazon EC2 instances to launch for the WebServer server Type: Number Default: '1'
-
-
修改模板输出以显示负载均衡器的 DNS 名称。
-
在集成编辑器窗格中,选择输出选项卡。
-
修改 JSON 以使用负载均衡器 DNS 名称,如下面的代码段所示。
JSON
{ "Outputs": { "URL": { "Value": { "Fn::GetAtt": [ "PublicElasticLoadBalancer", "DNSName" ] }, "Description": "Newly created application URL" } } }
如果以 YAML 格式编写模板,请使用下面的代码段。
Outputs: URL: Value: !GetAtt - PublicElasticLoadBalancer - DNSName Description: Newly created application URL
-
-
在 AWS CloudFormation Designer 工具栏上,选择验证模板(复选框图标)以检查模板中的语法错误。
查看并修复 Messages 窗格中的错误,然后再次验证模板。如果未看到错误,则说明您的模板语法上是有效的。
-
从 AWS CloudFormation Designer 工具栏中,选择文件菜单(文件图标),然后选择保存,以将模板保存到本地。
现在,您已获得一个可用于更新基本 Web 服务器堆栈的修改的 CloudFormation 模板。在下一步中,我们将使用此模板更新基本 Web 服务器堆栈。
步骤 3:更新堆栈
要实施模板更改,我们需要更新基本 Web 服务器堆栈。您可以从 AWS CloudFormation Designer 中直接启动 CloudFormation 更新堆栈向导。
更新堆栈
-
在 AWS CloudFormation Designer 工具栏上,选择创建堆栈(带向上箭头的云图标)。
AWS CloudFormation Designer 将打开的模板保存到 S3 存储桶中,然后启动 CloudFormation 更新堆栈向导。由于我们修改了
BasicWebServerStack
堆栈的模板,因此,CloudFormation 会为此堆栈启动更新堆栈向导。 -
CloudFormation 会自动填充模板 URL;选择 Next。
-
在 Stack 部分的 Name 字段中,确认堆栈名称为
BasicWebServerStack
。 -
在 Parameters 部分中,使用现有的值;选择 Next。
-
在本演练中,您无需添加标记或指定高级设置,因此请选择 Next。
-
确保堆栈名称正确,然后选择 Update。
CloudFormation 可能需要几分钟时间更新堆栈。要监控进度,可查看堆栈事件。有关更多信息,请参阅 从 CloudFormation 控制台查看堆栈信息。堆栈更新后,查看堆栈输出并前往网站 URL,确认网站正在运行。有关更多信息,请参阅 从 CloudFormation 控制台查看堆栈信息。您使用 AWS CloudFormation Designer 成功地更新了模板和堆栈。
要确保不因任何不必要的服务而产生费用,您可以删除此堆栈。
步骤 4:清理资源
要确保不因不必要的服务而产生费用,请删除您的堆栈及其资源。
删除堆栈
-
从 CloudFormation 控制台,选择 BasicWebServerStack 堆栈。
-
选择 Delete Stack。
-
在确认消息中,选择 Yes, Delete。
CloudFormation 可能需要几分钟时间删除堆栈。要监控进度,可查看堆栈事件。堆栈删除后,您创建的所有资源都被删除。现在,您已明白如何使用 AWS CloudFormation Designer,您可以使用它构建和修改自己的模板了。