AWS CloudFormation
User Guide (API Version 2010-05-15)
AWS 服务或AWS文档中描述的功能,可能因地区/位置而异。请点击 Amazon AWS 入门,可查看中国地区的具体差异

预排:更新堆栈

借助 AWS CloudFormation,您可以在您现有的堆栈中更新资源的属性。更改范围可包括从更新 CloudWatch 警报上的警报阈值等简单配置更改到更新 Amazon EC2 实例上运行之 Amazon 系统映像 (AMI) 等较复杂的更改。模板中的很多 AWS 资源都可进行更新,我们会继续添加对更多资源的支持。

此部分将带您逐步了解更新正在运行堆栈的简单进展。此部分将向您展示,模板的使用怎样将版本控制系统像用于您正在运行的软件那样用于您的 AWS 基础设施的配置。我们将带您逐步了解以下步骤:

  1. 创建起始堆栈– 使用基础 Amazon Linux AMI 并用 AWS CloudFormation 帮助程序脚本安装 Apache Web Server 和一个简单的 PHP 应用程序以创建堆栈。

  2. 更新应用程序– 更新应用程序中的一个文件并用 AWS CloudFormation 部署软件。

  3. 更新实例类型– 更改基础 Amazon EC2 实例的实例类型。

  4. 更新 Amazon EC2 实例上的 AMI– 更改您的堆栈中的 Amazon EC2 实例的 Amazon 系统映像 (AMI)。

  5. 将密钥对添加到实例– 将 Amazon EC2 密钥对添加到实例中,然后更新安全组以允许对实例的 SSH 访问。

  6. 更改堆栈的资源– 从堆栈中添加和删除资源,通过更新模板将其转换成自动扩展、负载均衡型应用程序。

简单的应用程序

我们将从创建可在本部分剩下的所有内容中使用的堆栈开始。我们已提供了一个简单的模板来启动在 Apache Web Server 中托管并在 Amazon Linux AMI 上运行的简单实例 PHP Web 应用程序。

Apache Web Server、PHP 和简单的 PHP 应用程序全部都由默认安装在 Amazon Linux AMI 上的 AWS CloudFormation 帮助程序脚本进行安装。以下模板代码段所示为描述待安装软件包和文件的元数据,此情况下为 Amazon Linux AMI 的 Yum 存储库中的 Apache Web Server 和 PHP 基础设施。代码段还显示 Services 部分,以确保 Apache Web Server 处于运行状态。Amazon EC2 实例定义的 Properties 部分中的 UserData 属性包含调用 cfn-init 来安装软件包和文件的 CloudInit 脚本。

Copy
"WebServerInstance": { "Type" : "AWS::EC2::Instance", "Metadata" : { "AWS::CloudFormation::Init" : { "config" : { "packages" : { "yum" : { "httpd" : [], "php" : [] } }, "files" : { "/var/www/html/index.php" : { "content" : { "Fn::Join" : ["", [ "<?php\n", "echo '<h1>AWS CloudFormation sample PHP application</h1>';\n", "echo '<p>", { "Ref" : "WelcomeMessage" }, "</p>';\n", "?>\n" ]]}, "mode" : "000644", "owner" : "apache", "group" : "apache" }, }, : "services" : { "sysvinit" : { "httpd" : { "enabled" : "true", "ensureRunning" : "true" } } } } } }, "Properties": { : "UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [ "#!/bin/bash\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 WebServerInstance ", " --region ", { "Ref" : "AWS::Region" }, "\n", : ]]}} } },

应用程序本身是非常简单的两行字 "Hello, World" 示例,在模板中进行了完整定义。对于现实工作中的应用程序,文件可存储在 Amazon S3、GitHub 或另一个存储库中,并通过模板进行参考。AWS CloudFormation 可下载软件包 (如 RPM 或 RubyGem),并能引用单个的文件和展开 .zip.tar 文件,以在 Amazon EC2 实例上创建应用程序项目。

模板用于启用和配置 cfn-hup 守护程序以侦听 Amazon EC2 实例元数据中所定义配置的更改。您可以使用 cfn-hup 后台程序更新应用程序软件,如 Apache 或 PHP 的版本,或可更新 AWS CloudFormation 中的 PHP 应用程序文件。来自模板中同一个 Amazon EC2 资源的以下代码段显示的是,在检测到元数据的任何更改时配置 cfn-hup 以调用 cfn-init 来更新软件所需的部件:

Copy
"WebServerInstance": { "Type" : "AWS::EC2::Instance", "Metadata" : { "AWS::CloudFormation::Init" : { "config" : { : "files" : { : "/etc/cfn/cfn-hup.conf" : { "content" : { "Fn::Join" : ["", [ "[main]\n", "stack=", { "Ref" : "AWS::StackName" }, "\n", "region=", { "Ref" : "AWS::Region" }, "\n" ]]}, "mode" : "000400", "owner" : "root", "group" : "root" }, "/etc/cfn/hooks.d/cfn-auto-reloader.conf" : { "content": { "Fn::Join" : ["", [ "[cfn-auto-reloader-hook]\n", "triggers=post.update\n", "path=Resources.WebServerInstance.Metadata.AWS::CloudFormation::Init\n", "action=/opt/aws/bin/cfn-init -s ", { "Ref" : "AWS::StackId" }, " -r WebServerInstance ", " --region ", { "Ref" : "AWS::Region" }, "\n", "runas=root\n" ]]} } }, : }, "Properties": { : "UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [ : "# Start up the cfn-hup daemon to listen for changes to the Web Server metadata\n", "/opt/aws/bin/cfn-hup || error_exit 'Failed to start cfn-hup'\n", : ]]}} } },

为了完成堆栈,模板创建了一个 Amazon EC2 安全组。

Copy
{ "AWSTemplateFormatVersion" : "2010-09-09", "Description" : "AWS CloudFormation Sample Template: Sample template that can be used to test EC2 updates. **WARNING** This template creates an Amazon Ec2 Instance. You will be billed for the AWS resources used if you create a stack from this template.", "Parameters" : { "InstanceType" : { "Description" : "WebServer EC2 instance type", "Type" : "String", "Default" : "m1.small", "AllowedValues" : [ "t1.micro", "t2.micro", "t2.small", "t2.medium", "m1.small", "m1.medium", "m1.large", "m1.xlarge", "m2.xlarge", "m2.2xlarge", "m2.4xlarge", "m3.medium", "m3.large", "m3.xlarge", "m3.2xlarge", "c1.medium", "c1.xlarge", "c3.large", "c3.xlarge", "c3.2xlarge", "c3.4xlarge", "c3.8xlarge", "g2.2xlarge", "r3.large", "r3.xlarge", "r3.2xlarge", "r3.4xlarge", "r3.8xlarge", "i2.xlarge", "i2.2xlarge", "i2.4xlarge", "i2.8xlarge", "hi1.4xlarge", "hs1.8xlarge", "cr1.8xlarge", "cc2.8xlarge", "cg1.4xlarge"], "ConstraintDescription" : "must be a valid EC2 instance type." } }, "Mappings" : { "AWSInstanceType2Arch" : { "t1.micro" : { "Arch" : "PV64" }, "t2.micro" : { "Arch" : "HVM64" }, "t2.small" : { "Arch" : "HVM64" }, "t2.medium" : { "Arch" : "HVM64" }, "m1.small" : { "Arch" : "PV64" }, "m1.medium" : { "Arch" : "PV64" }, "m1.large" : { "Arch" : "PV64" }, "m1.xlarge" : { "Arch" : "PV64" }, "m2.xlarge" : { "Arch" : "PV64" }, "m2.2xlarge" : { "Arch" : "PV64" }, "m2.4xlarge" : { "Arch" : "PV64" }, "m3.medium" : { "Arch" : "HVM64" }, "m3.large" : { "Arch" : "HVM64" }, "m3.xlarge" : { "Arch" : "HVM64" }, "m3.2xlarge" : { "Arch" : "HVM64" }, "c1.medium" : { "Arch" : "PV64" }, "c1.xlarge" : { "Arch" : "PV64" }, "c3.large" : { "Arch" : "HVM64" }, "c3.xlarge" : { "Arch" : "HVM64" }, "c3.2xlarge" : { "Arch" : "HVM64" }, "c3.4xlarge" : { "Arch" : "HVM64" }, "c3.8xlarge" : { "Arch" : "HVM64" }, "g2.2xlarge" : { "Arch" : "HVMG2" }, "r3.large" : { "Arch" : "HVM64" }, "r3.xlarge" : { "Arch" : "HVM64" }, "r3.2xlarge" : { "Arch" : "HVM64" }, "r3.4xlarge" : { "Arch" : "HVM64" }, "r3.8xlarge" : { "Arch" : "HVM64" }, "i2.xlarge" : { "Arch" : "HVM64" }, "i2.2xlarge" : { "Arch" : "HVM64" }, "i2.4xlarge" : { "Arch" : "HVM64" }, "i2.8xlarge" : { "Arch" : "HVM64" }, "hi1.4xlarge" : { "Arch" : "HVM64" }, "hs1.8xlarge" : { "Arch" : "HVM64" }, "cr1.8xlarge" : { "Arch" : "HVM64" }, "cc2.8xlarge" : { "Arch" : "HVM64" } }, "AWSRegionArch2AMI" : { "us-east-1" : { "PV64" : "ami-50842d38", "HVM64" : "ami-08842d60", "HVMG2" : "ami-3a329952" }, "us-west-2" : { "PV64" : "ami-af86c69f", "HVM64" : "ami-8786c6b7", "HVMG2" : "ami-47296a77" }, "us-west-1" : { "PV64" : "ami-c7a8a182", "HVM64" : "ami-cfa8a18a", "HVMG2" : "ami-331b1376" }, "eu-west-1" : { "PV64" : "ami-aa8f28dd", "HVM64" : "ami-748e2903", "HVMG2" : "ami-00913777" }, "ap-southeast-1" : { "PV64" : "ami-20e1c572", "HVM64" : "ami-d6e1c584", "HVMG2" : "ami-fabe9aa8" }, "ap-northeast-1" : { "PV64" : "ami-21072820", "HVM64" : "ami-35072834", "HVMG2" : "ami-5dd1ff5c" }, "ap-southeast-2" : { "PV64" : "ami-8b4724b1", "HVM64" : "ami-fd4724c7", "HVMG2" : "ami-e98ae9d3" }, "sa-east-1" : { "PV64" : "ami-9d6cc680", "HVM64" : "ami-956cc688", "HVMG2" : "NOT_SUPPORTED" }, "cn-north-1" : { "PV64" : "ami-a857c591", "HVM64" : "ami-ac57c595", "HVMG2" : "NOT_SUPPORTED" }, "eu-central-1" : { "PV64" : "ami-a03503bd", "HVM64" : "ami-b43503a9", "HVMG2" : "ami-b03503ad" } } }, "Resources" : { "WebServerInstance": { "Type" : "AWS::EC2::Instance", "Metadata" : { "Comment" : "Install a simple PHP application", "AWS::CloudFormation::Init" : { "config" : { "packages" : { "yum" : { "httpd" : [], "php" : [] } }, "files" : { "/var/www/html/index.php" : { "content" : { "Fn::Join" : ["", [ "<?php\n", "echo '<h1>AWS CloudFormation sample PHP application</h1>';\n", "?>\n" ]]}, "mode" : "000644", "owner" : "apache", "group" : "apache" }, "/etc/cfn/cfn-hup.conf" : { "content" : { "Fn::Join" : ["", [ "[main]\n", "stack=", { "Ref" : "AWS::StackId" }, "\n", "region=", { "Ref" : "AWS::Region" }, "\n" ]]}, "mode" : "000400", "owner" : "root", "group" : "root" }, "/etc/cfn/hooks.d/cfn-auto-reloader.conf" : { "content": { "Fn::Join" : ["", [ "[cfn-auto-reloader-hook]\n", "triggers=post.update\n", "path=Resources.WebServerInstance.Metadata.AWS::CloudFormation::Init\n", "action=/opt/aws/bin/cfn-init -s ", { "Ref" : "AWS::StackId" }, " -r WebServerInstance ", " --region ", { "Ref" : "AWS::Region" }, "\n", "runas=root\n" ]]} } }, "services" : { "sysvinit" : { "httpd" : { "enabled" : "true", "ensureRunning" : "true" }, "cfn-hup" : { "enabled" : "true", "ensureRunning" : "true", "files" : ["/etc/cfn/cfn-hup.conf", "/etc/cfn/hooks.d/cfn-auto-reloader.conf"]} } } } } }, "Properties": { "ImageId" : { "Fn::FindInMap" : [ "AWSRegionArch2AMI", { "Ref" : "AWS::Region" }, { "Fn::FindInMap" : [ "AWSInstanceType2Arch", { "Ref" : "InstanceType" }, "Arch" ] } ] }, "InstanceType" : { "Ref" : "InstanceType" }, "SecurityGroups" : [ {"Ref" : "WebServerSecurityGroup"} ], "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 WebServerInstance ", " --region ", { "Ref" : "AWS::Region" }, "\n", "# Start up the cfn-hup daemon to listen for changes to the Web Server metadata\n", "/opt/aws/bin/cfn-hup || error_exit 'Failed to start cfn-hup'\n", "# Signal the status from cfn-init\n", "/opt/aws/bin/cfn-signal -e $? ", " --stack ", { "Ref" : "AWS::StackName" }, " --resource WebServerInstance ", " --region ", { "Ref" : "AWS::Region" }, "\n" ]]}} }, "CreationPolicy" : { "ResourceSignal" : { "Timeout" : "PT5M" } } }, "WebServerSecurityGroup" : { "Type" : "AWS::EC2::SecurityGroup", "Properties" : { "GroupDescription" : "Enable HTTP access via port 80", "SecurityGroupIngress" : [ {"IpProtocol" : "tcp", "FromPort" : "80", "ToPort" : "80", "CidrIp" : "0.0.0.0/0"} ] } } }, "Outputs" : { "WebsiteURL" : { "Description" : "Application URL", "Value" : { "Fn::Join" : ["", ["http://", { "Fn::GetAtt" : [ "WebServerInstance", "PublicDnsName" ]}]] } } } }

此示例中采用的是单个 Amazon EC2 实例,但您可以在使用 Elastic Load Balancer 和 Auto Scaling 组管理应用程序服务器集合的更复杂解决方案上使用相同的机制。但是,Auto Scaling 组有很多特殊注意事项。有关更多信息,请参阅 更新 Auto Scaling 组

创建起始堆栈

我们将使用 AWS 管理控制台从示例模板中创建起始堆栈以实现此示例的目的。

警告

此程序完成后将会部署实时的 AWS 服务。只要这些服务在运行,您就要按照标准使用费率付费。

要通过 AWS 管理控制台创建堆栈

  1. 复制上一个模板并将其作为文本文件本地保存到您的系统中。注意保存位置,因为您需要在后续步骤中使用此文件。

  2. 通过以下网址登录 AWS CloudFormation 控制台: https://console.amazonaws.cn/cloudformation

  3. 单击 Create New Stack (创建新堆栈)

  4. 创建新堆栈向导中的选择模板屏幕上,在名称字段中键入 UpdateTutorial。在同一页上,选择将模板上传到 Amazon S3 并浏览到在第一步中下载的文件,然后单击下一步

  5. Specify Parameters 屏幕上的 Instance Type 框中,键入 t1.micro。然后单击 Next (下一步)

  6. 选项屏幕上,单击下一步

  7. Review (审核) 屏幕上,确认所有设置都符合您的要求,然后单击 Create (创建)

当您的堆栈状态变成 CREATE_COMPLETE 后,输出选项卡会显示网站的 URL。如果您单击 WebsiteURL 的输出值,您将看到新 PHP 应用程序在工作。

更新应用程序

现在您已部署好堆栈,接下来更新应用程序吧。我们将对应用程序所打印出的文本进行简单更改。要执行此操作,我们将添加回显命令至 index.php 文件,如此模板代码段所示:

Copy
"WebServerInstance": { "Type" : "AWS::EC2::Instance", "Metadata" : { "AWS::CloudFormation::Init" : { "config" : { : "files" : { "/var/www/html/index.php" : { "content" : { "Fn::Join" : ["", [ "<?php\n", "echo '<h1>AWS CloudFormation sample PHP application</h1>';\n", "echo 'Updated version via UpdateStack';\n ", "?>\n" ]]}, "mode" : "000644", "owner" : "apache", "group" : "apache" }, : } },

使用文本编辑器手动编辑您保存在本地的模板文件。

现在,我们将更新堆栈。

要通过 AWS 管理控制台更新堆栈

  1. 从以下网址登录 AWS CloudFormation 控制台: https://console.amazonaws.cn/cloudformation

  2. 在 AWS CloudFormation 控制面板中,单击您之前创建的堆栈,然后单击“Update Stack”。

  3. 更新堆栈向导中的选择模板屏幕上,选择将模板上传到 Amazon S3,选择修改后的模板,然后单击下一步

  4. 选项屏幕上,单击下一步

  5. 因为堆栈没有堆栈策略,所以单击 Next。在没有覆盖策略的情况下,所有资源均可更新。

  6. Review (审核) 屏幕上,确认所有设置都符合您的要求,然后单击 Update (更新)

如果您通过 AWS 管理控制台更新堆栈,您将会注意到创建起始堆栈所用参数已预填充到“Update Stack”向导的“Parameters”页面上。如果您使用 aws cloudformation update-stack 命令,请务必键入与您原先用于创建堆栈的参数相同的值。

当您的堆栈处于 UPDATE_COMPLETE 状态时,您可以再次单击 WebsiteURL 输出值以验证应用程序的更改已生效。默认状态下,cfn-hup 后台程序每 15 分钟运行一次,因此最多能花 15 分钟在堆栈更新后更改应用程序。

要查看已更新资源集,请转至 AWS CloudFormation 控制台。在“Events”选项卡上,查看堆栈事件。在这种特殊情况下,Amazon EC2 实例 WebServerInstance 的元数据已更新,这导致 AWS CloudFormation 也会重新评估其他资源 (WebServerSecurityGroup) 以确保没有其他更改。其它堆栈资源都没有被修改。AWS CloudFormation 只会更新堆栈中那些受堆栈的更改影响到的资源。此类更改可直接进行,如属性或元数据更改,也可由依赖性或 Ref 和 GetAtt 中的数据流或其它内部模板函数导致。

这一简单更新对此过程进行了阐述;但是,您可以对您的 Amazon EC2 实例中所部署文件和软件包进行更复杂的更改。例如,您可能会确定需要将 MySQL 与 MySQL 的 PHP 支持一起添加到实例中。要执行此操作,只需要将附加软件包和文件与任何附加服务一起添加到配置中,然后更新堆栈以部署更改。在以下模板代码段中,更改被红色高亮显示:

Copy
"WebServerInstance": { "Type" : "AWS::EC2::Instance", "Metadata" : { "Comment" : "Install a simple PHP application", "AWS::CloudFormation::Init" : { "config" : { "packages" : { "yum" : { "httpd" : [], "php" : [], "php-mysql" : [], "mysql-server" : [], "mysql-libs" : [], "mysql" : [] } }, : "services" : { "sysvinit" : { "httpd" : { "enabled" : "true", "ensureRunning" : "true" }, "cfn-hup" : { "enabled" : "true", "ensureRunning" : "true", "files" : ["/etc/cfn/cfn-hup.conf", "/etc/cfn/hooks.d/cfn-auto-reloader.conf"]}, "mysqld" : { "enabled" : "true", "ensureRunning" : "true" } } } } } }, "Properties": { : } }

您可以更新 CloudFormation 元数据,将应用程序所使用的软件包更新到新版本。前述示例中,每个软件包的版本属性都为空,这表示 cfn-init 应安装最新版的软件包。

Copy
"packages" : { "yum" : { "httpd" : [], "php" : [] }

您可以视需要指定软件包的版本字符串。如果您在后续更新堆栈调用中更改版本字符串,则会部署新版软件包。此处所示为 RubyGems 软件包版本号的使用示例。支持版本化的任何软件包都可以有特定版本。

Copy
"packages" : { "rubygems" : { "mysql" : [], "rubygems-update" : ["1.6.2"], "rake" : ["0.8.7"], "rails" : ["2.3.11"] } }

更新 Auto Scaling 组

如果您在模板中使用与 Amazon EC2 实例资源截然相反的 Auto Scaling 组,应用程序将会以完全相同的方式更新;但是,AWS CloudFormation 在 Auto Scaling 组中的所有 Amazon EC2 实例上都不会提供任何同步或序列化。每个主机上的 cfn-hup 后台程序都将独立运行且会按其自己的计划更新应用程序。当您使用 cfn-hup 更新实例上的配置时,每个实例都将按其自己的计划运行 cfn-hup 挂接;堆栈中的实例之间不协调。您应该考虑以下各项:

  • 如果 Auto Scaling 组中所有 Amazon EC2 实例的 cfn-hup 更改都同时运行,更新期间您的服务可能不可用。

  • 如果 cfn-hup 更改在不同时间运行,则新旧版软件可能会同时运行。

要避免这些问题,请考虑在 Auto Scaling 组中强制滚动更新您的实例。有关更多信息,请参阅 UpdatePolicy

更改资源属性

借助 AWS CloudFormation,您可以更改堆栈中现有资源的属性。以下部分描述了解决特定问题的各种更新;但是,堆栈中支持更新的任何资源的任何属性都可视需要进行修改。

更新实例类型

我们到目前为止所建立的堆栈使用 t1.micro Amazon EC2 实例。假设您新建的网站获取的流量比 t1.micro 实例能处理的流量多,且您现在想移动到 m1.small Amazon EC2 实例类型中。如果实例类型的架构发生变化,则会使用不同的 AMI 创建实例。在检验模板中的映射时,您将会看到 t1.micro 和 m1.small 实例的架构相同且它们使用相同的 Amazon Linux AMI。

Copy
"Mappings" : { "AWSInstanceType2Arch" : { "t1.micro" : { "Arch" : "PV64" }, "t2.micro" : { "Arch" : "HVM64" }, "t2.small" : { "Arch" : "HVM64" }, "t2.medium" : { "Arch" : "HVM64" }, "m1.small" : { "Arch" : "PV64" }, "m1.medium" : { "Arch" : "PV64" }, "m1.large" : { "Arch" : "PV64" }, "m1.xlarge" : { "Arch" : "PV64" }, "m2.xlarge" : { "Arch" : "PV64" }, "m2.2xlarge" : { "Arch" : "PV64" }, "m2.4xlarge" : { "Arch" : "PV64" }, "m3.medium" : { "Arch" : "HVM64" }, "m3.large" : { "Arch" : "HVM64" }, "m3.xlarge" : { "Arch" : "HVM64" }, "m3.2xlarge" : { "Arch" : "HVM64" }, "c1.medium" : { "Arch" : "PV64" }, "c1.xlarge" : { "Arch" : "PV64" }, "c3.large" : { "Arch" : "HVM64" }, "c3.xlarge" : { "Arch" : "HVM64" }, "c3.2xlarge" : { "Arch" : "HVM64" }, "c3.4xlarge" : { "Arch" : "HVM64" }, "c3.8xlarge" : { "Arch" : "HVM64" }, "g2.2xlarge" : { "Arch" : "HVMG2" }, "r3.large" : { "Arch" : "HVM64" }, "r3.xlarge" : { "Arch" : "HVM64" }, "r3.2xlarge" : { "Arch" : "HVM64" }, "r3.4xlarge" : { "Arch" : "HVM64" }, "r3.8xlarge" : { "Arch" : "HVM64" }, "i2.xlarge" : { "Arch" : "HVM64" }, "i2.2xlarge" : { "Arch" : "HVM64" }, "i2.4xlarge" : { "Arch" : "HVM64" }, "i2.8xlarge" : { "Arch" : "HVM64" }, "hi1.4xlarge" : { "Arch" : "HVM64" }, "hs1.8xlarge" : { "Arch" : "HVM64" }, "cr1.8xlarge" : { "Arch" : "HVM64" }, "cc2.8xlarge" : { "Arch" : "HVM64" } }, "AWSRegionArch2AMI" : { "us-east-1" : { "PV64" : "ami-50842d38", "HVM64" : "ami-08842d60", "HVMG2" : "ami-3a329952" }, "us-west-2" : { "PV64" : "ami-af86c69f", "HVM64" : "ami-8786c6b7", "HVMG2" : "ami-47296a77" }, "us-west-1" : { "PV64" : "ami-c7a8a182", "HVM64" : "ami-cfa8a18a", "HVMG2" : "ami-331b1376" }, "eu-west-1" : { "PV64" : "ami-aa8f28dd", "HVM64" : "ami-748e2903", "HVMG2" : "ami-00913777" }, "ap-southeast-1" : { "PV64" : "ami-20e1c572", "HVM64" : "ami-d6e1c584", "HVMG2" : "ami-fabe9aa8" }, "ap-northeast-1" : { "PV64" : "ami-21072820", "HVM64" : "ami-35072834", "HVMG2" : "ami-5dd1ff5c" }, "ap-southeast-2" : { "PV64" : "ami-8b4724b1", "HVM64" : "ami-fd4724c7", "HVMG2" : "ami-e98ae9d3" }, "sa-east-1" : { "PV64" : "ami-9d6cc680", "HVM64" : "ami-956cc688", "HVMG2" : "NOT_SUPPORTED" }, "cn-north-1" : { "PV64" : "ami-a857c591", "HVM64" : "ami-ac57c595", "HVMG2" : "NOT_SUPPORTED" }, "eu-central-1" : { "PV64" : "ami-a03503bd", "HVM64" : "ami-b43503a9", "HVMG2" : "ami-b03503ad" } } }

让我们使用在前述部分中进行修改的模板更改实例类型。由于 InstanceType 是模板的输入参数,我们不需要修改模板;我们只能在“Stack Update”向导的“Specify Parameters”页面上更改参数值。

要通过 AWS 管理控制台更新堆栈

  1. 从以下网址登录 AWS CloudFormation 控制台: https://console.amazonaws.cn/cloudformation

  2. 在“AWS CloudFormation”控制面板中,单击您先前创建的堆栈,然后单击 Update Stack (更新堆栈)

  3. Update Stack 向导中的 Select Template 屏幕上,选择 Use current template,然后单击 Next

    此时将显示“Specify Details”页,其中的 Specify Parameters 部分预填充了创建初始堆栈所用的参数。

  4. InstanceType 文本框的值从 t1.micro 更改为 t2.small。然后单击下一步

  5. 选项屏幕上,单击下一步

  6. 因为堆栈没有堆栈策略,所以单击 Next。在没有覆盖策略的情况下,所有资源均可更新。

  7. Review (审核) 屏幕上,确认所有设置都符合您的要求,然后单击 Update (更新)

您可以通过启动和停止实例来动态更改 EBS 支持型 Amazon EC2 实例的实例类型。AWS CloudFormation 尝试通过更新实例类型和重启实例来优化更改,所以实例 ID 不会更改。但是,实例重启时,实例的公用 IP 地址会更改。为了确保弹性 IP 地址在更改后被正确捆绑,AWS CloudFormation 还会更新弹性 IP 地址。您可以在“Events”选项卡上的 AWS CloudFormation 控制台中看到更改。

要通过 AWS 管理控制台检查实例类型,请打开 Amazon EC2 控制台并在其中查找您的实例。

更新 Amazon EC2 实例上的 AMI

现在让我们来看看如何更改实例上所运行的 Amazon 系统映像 (AMI)。我们将通过更新堆栈来触发 AMI 更改从而使用新的 Amazon EC2 实例类型,如实例类型为 HVM64 的 t2.medium。

如之前部分所述,我们将使用现有模板更改示例堆栈所使用的实例类型。在“堆栈更新”向导中的“指定参数”页上,更改实例类型的值。

在这种情况下,您不能只通过启动和停止实例来修改 AMI; AWS CloudFormation 将其视为对资源不可变属性的更改。为了对不可变属性进行更改,AWS CloudFormation 必须启动替代资源,此情况下为运行新 AMI 的新 Amazon EC2 实例。

在新实例运行之后,AWS CloudFormation 将更新堆栈中的其他资源以指向新资源。所有新资源被创建且旧资源被删除的过程被称为 UPDATE_CLEANUP。此时,您将注意到堆栈中实例的实例 ID 和应用程序 URL 已随着更新而更改。“Event”表中的事件包含描述“Requested update has a change to an immutable property and hence creating a new physical resource”,以指示资源已被替代。

如果您已将应用程序代码写入您想更新的 AMI 中,您可以使用同一堆栈更新机制更新 AMI 以加载您的新应用程序。

要更新您的堆栈中的实例之 AMI

  1. 创建含有应用程序或操作系统更改的新 AMI。有关更多信息,请转至 Amazon EC2 用户指南(适用于 Linux 实例) 中的 Creating Your Own AMIs

  2. 更新您的模板以合并新 AMI ID。

  3. 通过 AWS 管理控制台(如更新应用程序中所述)或使用 AWS 命令 aws cloudformation update-stack 更新堆栈。

在您更新堆栈时,AWS CloudFormation 侦测到 AMI ID 已更改,然后用我们触发前一个更新所使用的方法触发堆栈更新。

更新 Auto Scaling 组的 Amazon EC2 启动配置

如果您使用的是 Auto Scaling 组而不是 Amazon EC2 实例,更新正在运行实例的过程会有点不同。借助 Auto Scaling 资源,可将实例类型或 AMI ID 等 Amazon EC2 实例配置封装到 Auto Scaling 启动配置中。您可以用我们在前述部分中对 Amazon EC2 实例资源进行更改时所用的方法对启动配置进行更改。但是,启动配置的更改不会影响 Auto Scaling 组中任何正在运行的 Amazon EC2 实例。更新后的启动配置只适用于更新之后创建的新实例。

如果要将更改传播到 Auto Scaling 组中所有实例的启动配置,则可以使用更新属性。有关更多信息,请参阅 UpdatePolicy

添加资源属性

到目前为止,我们已在模板中查看了资源现有属性的更改。您还可以添加原先未在模板中指定的属性。为了阐明上述操作,我们将会添加 Amazon EC2 密钥对到现有 EC2 实例中然后在 Amazon EC2 安全组中打开端口 22,从而使您可以使用安全外壳 (SSH) 访问实例。

将密钥对添加到实例

向现有 Amazon EC2 实例添加 SSH 访问权限

  1. 向模板额外添加两个参数,从而以现有 Amazon EC2 密钥对和 SSH 位置的名称进行传递。

    Copy
    "Parameters" : { "KeyName" : { "Description" : "Name of an existing Amazon EC2 key pair for SSH access", "Type": "AWS::EC2::KeyPair::KeyName" }, "SSHLocation" : { "Description" : " The IP address range that can be used to SSH to the EC2 instances", "Type": "String", "MinLength": "9", "MaxLength": "18", "Default": "0.0.0.0/0", "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})", "ConstraintDescription": "must be a valid IP CIDR range of the form x.x.x.x/x." } : },
  2. 将 KeyName 属性添加到 Amazon EC2 实例。

    Copy
    "WebServerInstance": { "Type" : "AWS::EC2::Instance", : "Properties": { : "KeyName" : { "Ref" : "KeyName" }, : } },
  3. 将端口 22 和 SSH 位置添加到 Amazon EC2 安全组的入口规则。

    Copy
    "WebServerSecurityGroup" : { "Type" : "AWS::EC2::SecurityGroup", "Properties" : { "GroupDescription" : "Enable HTTP and SSH", "SecurityGroupIngress" : [ {"IpProtocol" : "tcp", "FromPort" : "22", "ToPort" : "22", "CidrIp" : { "Ref" : "SSHLocation"}}, {"IpProtocol" : "tcp", "FromPort" : "80", "ToPort" : "80", "CidrIp" : "0.0.0.0/0"} ] } },
  4. 通过 AWS 管理控制台(如更新应用程序中所述)或使用 AWS 命令 aws cloudformation update-stack 更新堆栈。

更改堆栈的资源

自从能随着时间变化更改应用程序需求后,AWS CloudFormation 就允许您更改构成堆栈的资源集。为了进行演示,我们从 添加资源属性 中获取单个实例应用程序并通过更新堆栈将其转换成自动扩展型负载均衡应用程序。

这一操作会使用弹性 IP 地址创建简单的单实例 PHP 应用程序。现在,我们将在更新时更改应用程序资源以将应用程序转变成可用性高、可自动扩展的负载均衡型应用程序。

  1. 添加 Elastic Load Balancer 资源。

    Copy
    "ElasticLoadBalancer" : { "Type" : "AWS::ElasticLoadBalancing::LoadBalancer", "Properties" : { "CrossZone" : "true", "AvailabilityZones" : { "Fn::GetAZs" : "" }, "LBCookieStickinessPolicy" : [ { "PolicyName" : "CookieBasedPolicy", "CookieExpirationPeriod" : "30" } ], "Listeners" : [ { "LoadBalancerPort" : "80", "InstancePort" : "80", "Protocol" : "HTTP", "PolicyNames" : [ "CookieBasedPolicy" ] } ], "HealthCheck" : { "Target" : "HTTP:80/", "HealthyThreshold" : "2", "UnhealthyThreshold" : "5", "Interval" : "10", "Timeout" : "5" } } }
  2. 将模板中的 EC2 实例转换成 Auto Scaling 启动配置。由于属性都相同,所以我们只需要更改类型名称,从:

    Copy
    "WebServerInstance": { "Type" : "AWS::EC2::Instance",

    到:

    Copy
    "LaunchConfig": { "Type" : "AWS::AutoScaling::LaunchConfiguration",

    为了使模板更清楚,我们已将资源名称从 WebServerInstance 更改为 LaunchConfig,因此您将需要更新由 cfn-init 和 cfn-hup 引用的资源名称(只需搜索 WebServerInstance 并将其替换为 LaunchConfig(cfn-signal 除外))。对于 cfn-signal,您需要向 Auto Scaling 组 (WebServerGroup) 而非实例发送信号,如以下代码段所示:

    Copy
    "# Signal the status from cfn-init\n", "/opt/aws/bin/cfn-signal -e $? ", " --stack ", { "Ref" : "AWS::StackName" }, " --resource WebServerGroup ", " --region ", { "Ref" : "AWS::Region" }, "\n"
  3. 添加 Auto Scaling 组资源。

    Copy
    "WebServerGroup" : { "Type" : "AWS::AutoScaling::AutoScalingGroup", "Properties" : { "AvailabilityZones" : { "Fn::GetAZs" : "" }, "LaunchConfigurationName" : { "Ref" : "LaunchConfig" }, "MinSize" : "1", "DesiredCapacity" : "1", "MaxSize" : "5", "LoadBalancerNames" : [ { "Ref" : "ElasticLoadBalancer" } ] }, "CreationPolicy" : { "ResourceSignal" : { "Timeout" : "PT15M" } }, "UpdatePolicy": { "AutoScalingRollingUpdate": { "MinInstancesInService": "1", "MaxBatchSize": "1", "PauseTime" : "PT15M", "WaitOnResourceSignals": "true" } } }
  4. 更新安全组定义以锁定通过负载均衡器分配至实例的流量。

    Copy
    "WebServerSecurityGroup" : { "Type" : "AWS::EC2::SecurityGroup", "Properties" : { "GroupDescription" : "Enable HTTP access via port 80 locked down to the ELB and SSH access", "SecurityGroupIngress" : [ {"IpProtocol" : "tcp", "FromPort" : "80", "ToPort" : "80", "SourceSecurityGroupOwnerId" : {"Fn::GetAtt" : ["ElasticLoadBalancer", "SourceSecurityGroup.OwnerAlias"]}, "SourceSecurityGroupName" : {"Fn::GetAtt" : ["ElasticLoadBalancer", "SourceSecurityGroup.GroupName"]}}, {"IpProtocol" : "tcp", "FromPort" : "22", "ToPort" : "22", "CidrIp" : { "Ref" : "SSHLocation"}} ] } }
  5. 更新 Outputs 以返回 Elastic Load Balancer 的 DNS 名称,以作为应用程序的位置,从:

    Copy
    "WebsiteURL" : { "Value" : { "Fn::Join" : ["", ["http://", { "Fn::GetAtt" : [ "WebServerInstance", "PublicDnsName" ]}]]}, "Description" : "Application URL" }

    到:

    Copy
    "WebsiteURL" : { "Value" : { "Fn::Join" : ["", ["http://", { "Fn::GetAtt" : [ "ElasticLoadBalancer", "DNSName" ]}]]}, "Description" : "Application URL" }

为方便参考,以下示例显示了完整模板。如果您使用此模板更新堆栈,您会将您的单实例简单应用程序转换成可用性高、可自动扩展的、多可用区负载均衡型应用程序。只有需要更新的资源会被修改,所以,如果此应用程序有任何数据存储,该数据都会保持原样。现在,您可以使用 AWS CloudFormation 在您的要求更改时增大或增强您的堆栈。

Copy
{ "AWSTemplateFormatVersion" : "2010-09-09", "Description" : "AWS CloudFormation Sample Template: Sample template that can be used to test EC2 updates. **WARNING** This template creates an Amazon Ec2 Instance. You will be billed for the AWS resources used if you create a stack from this template.", "Parameters" : { "KeyName": { "Description" : "Name of an existing EC2 KeyPair to enable SSH access to the instance", "Type": "AWS::EC2::KeyPair::KeyName", "ConstraintDescription" : "must be the name of an existing EC2 KeyPair." }, "SSHLocation" : { "Description" : " The IP address range that can be used to SSH to the EC2 instances", "Type": "String", "MinLength": "9", "MaxLength": "18", "Default": "0.0.0.0/0", "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})", "ConstraintDescription": "must be a valid IP CIDR range of the form x.x.x.x/x." }, "InstanceType" : { "Description" : "WebServer EC2 instance type", "Type" : "String", "Default" : "m1.small", "AllowedValues" : [ "t1.micro", "t2.micro", "t2.small", "t2.medium", "m1.small", "m1.medium", "m1.large", "m1.xlarge", "m2.xlarge", "m2.2xlarge", "m2.4xlarge", "m3.medium", "m3.large", "m3.xlarge", "m3.2xlarge", "c1.medium", "c1.xlarge", "c3.large", "c3.xlarge", "c3.2xlarge", "c3.4xlarge", "c3.8xlarge", "g2.2xlarge", "r3.large", "r3.xlarge", "r3.2xlarge", "r3.4xlarge", "r3.8xlarge", "i2.xlarge", "i2.2xlarge", "i2.4xlarge", "i2.8xlarge", "hi1.4xlarge", "hs1.8xlarge", "cr1.8xlarge", "cc2.8xlarge", "cg1.4xlarge"], "ConstraintDescription" : "must be a valid EC2 instance type." } }, "Mappings" : { "AWSInstanceType2Arch" : { "t1.micro" : { "Arch" : "PV64" }, "t2.micro" : { "Arch" : "HVM64" }, "t2.small" : { "Arch" : "HVM64" }, "t2.medium" : { "Arch" : "HVM64" }, "m1.small" : { "Arch" : "PV64" }, "m1.medium" : { "Arch" : "PV64" }, "m1.large" : { "Arch" : "PV64" }, "m1.xlarge" : { "Arch" : "PV64" }, "m2.xlarge" : { "Arch" : "PV64" }, "m2.2xlarge" : { "Arch" : "PV64" }, "m2.4xlarge" : { "Arch" : "PV64" }, "m3.medium" : { "Arch" : "HVM64" }, "m3.large" : { "Arch" : "HVM64" }, "m3.xlarge" : { "Arch" : "HVM64" }, "m3.2xlarge" : { "Arch" : "HVM64" }, "c1.medium" : { "Arch" : "PV64" }, "c1.xlarge" : { "Arch" : "PV64" }, "c3.large" : { "Arch" : "HVM64" }, "c3.xlarge" : { "Arch" : "HVM64" }, "c3.2xlarge" : { "Arch" : "HVM64" }, "c3.4xlarge" : { "Arch" : "HVM64" }, "c3.8xlarge" : { "Arch" : "HVM64" }, "g2.2xlarge" : { "Arch" : "HVMG2" }, "r3.large" : { "Arch" : "HVM64" }, "r3.xlarge" : { "Arch" : "HVM64" }, "r3.2xlarge" : { "Arch" : "HVM64" }, "r3.4xlarge" : { "Arch" : "HVM64" }, "r3.8xlarge" : { "Arch" : "HVM64" }, "i2.xlarge" : { "Arch" : "HVM64" }, "i2.2xlarge" : { "Arch" : "HVM64" }, "i2.4xlarge" : { "Arch" : "HVM64" }, "i2.8xlarge" : { "Arch" : "HVM64" }, "hi1.4xlarge" : { "Arch" : "HVM64" }, "hs1.8xlarge" : { "Arch" : "HVM64" }, "cr1.8xlarge" : { "Arch" : "HVM64" }, "cc2.8xlarge" : { "Arch" : "HVM64" } }, "AWSRegionArch2AMI" : { "us-east-1" : { "PV64" : "ami-50842d38", "HVM64" : "ami-08842d60", "HVMG2" : "ami-3a329952" }, "us-west-2" : { "PV64" : "ami-af86c69f", "HVM64" : "ami-8786c6b7", "HVMG2" : "ami-47296a77" }, "us-west-1" : { "PV64" : "ami-c7a8a182", "HVM64" : "ami-cfa8a18a", "HVMG2" : "ami-331b1376" }, "eu-west-1" : { "PV64" : "ami-aa8f28dd", "HVM64" : "ami-748e2903", "HVMG2" : "ami-00913777" }, "ap-southeast-1" : { "PV64" : "ami-20e1c572", "HVM64" : "ami-d6e1c584", "HVMG2" : "ami-fabe9aa8" }, "ap-northeast-1" : { "PV64" : "ami-21072820", "HVM64" : "ami-35072834", "HVMG2" : "ami-5dd1ff5c" }, "ap-southeast-2" : { "PV64" : "ami-8b4724b1", "HVM64" : "ami-fd4724c7", "HVMG2" : "ami-e98ae9d3" }, "sa-east-1" : { "PV64" : "ami-9d6cc680", "HVM64" : "ami-956cc688", "HVMG2" : "NOT_SUPPORTED" }, "cn-north-1" : { "PV64" : "ami-a857c591", "HVM64" : "ami-ac57c595", "HVMG2" : "NOT_SUPPORTED" }, "eu-central-1" : { "PV64" : "ami-a03503bd", "HVM64" : "ami-b43503a9", "HVMG2" : "ami-b03503ad" } } }, "Resources" : { "ElasticLoadBalancer" : { "Type" : "AWS::ElasticLoadBalancing::LoadBalancer", "Properties" : { "CrossZone" : "true", "AvailabilityZones" : { "Fn::GetAZs" : "" }, "LBCookieStickinessPolicy" : [ { "PolicyName" : "CookieBasedPolicy", "CookieExpirationPeriod" : "30" } ], "Listeners" : [ { "LoadBalancerPort" : "80", "InstancePort" : "80", "Protocol" : "HTTP", "PolicyNames" : [ "CookieBasedPolicy" ] } ], "HealthCheck" : { "Target" : "HTTP:80/", "HealthyThreshold" : "2", "UnhealthyThreshold" : "5", "Interval" : "10", "Timeout" : "5" } } }, "WebServerGroup" : { "Type" : "AWS::AutoScaling::AutoScalingGroup", "Properties" : { "AvailabilityZones" : { "Fn::GetAZs" : "" }, "LaunchConfigurationName" : { "Ref" : "LaunchConfig" }, "MinSize" : "1", "DesiredCapacity" : "1", "MaxSize" : "5", "LoadBalancerNames" : [ { "Ref" : "ElasticLoadBalancer" } ] }, "CreationPolicy" : { "ResourceSignal" : { "Timeout" : "PT15M" } }, "UpdatePolicy": { "AutoScalingRollingUpdate": { "MinInstancesInService": "1", "MaxBatchSize": "1", "PauseTime" : "PT15M", "WaitOnResourceSignals": "true" } } }, "LaunchConfig": { "Type" : "AWS::AutoScaling::LaunchConfiguration", "Metadata" : { "Comment" : "Install a simple PHP application", "AWS::CloudFormation::Init" : { "config" : { "packages" : { "yum" : { "httpd" : [], "php" : [] } }, "files" : { "/var/www/html/index.php" : { "content" : { "Fn::Join" : ["", [ "<?php\n", "echo '<h1>AWS CloudFormation sample PHP application</h1>';\n", "echo 'Updated version via UpdateStack';\n ", "?>\n" ]]}, "mode" : "000644", "owner" : "apache", "group" : "apache" }, "/etc/cfn/cfn-hup.conf" : { "content" : { "Fn::Join" : ["", [ "[main]\n", "stack=", { "Ref" : "AWS::StackId" }, "\n", "region=", { "Ref" : "AWS::Region" }, "\n" ]]}, "mode" : "000400", "owner" : "root", "group" : "root" }, "/etc/cfn/hooks.d/cfn-auto-reloader.conf" : { "content": { "Fn::Join" : ["", [ "[cfn-auto-reloader-hook]\n", "triggers=post.update\n", "path=Resources.LaunchConfig.Metadata.AWS::CloudFormation::Init\n", "action=/opt/aws/bin/cfn-init -s ", { "Ref" : "AWS::StackId" }, " -r LaunchConfig ", " --region ", { "Ref" : "AWS::Region" }, "\n", "runas=root\n" ]]} } }, "services" : { "sysvinit" : { "httpd" : { "enabled" : "true", "ensureRunning" : "true" }, "cfn-hup" : { "enabled" : "true", "ensureRunning" : "true", "files" : ["/etc/cfn/cfn-hup.conf", "/etc/cfn/hooks.d/cfn-auto-reloader.conf"]} } } } } }, "Properties": { "ImageId" : { "Fn::FindInMap" : [ "AWSRegionArch2AMI", { "Ref" : "AWS::Region" }, { "Fn::FindInMap" : [ "AWSInstanceType2Arch", { "Ref" : "InstanceType" }, "Arch" ] } ] }, "InstanceType" : { "Ref" : "InstanceType" }, "KeyName" : { "Ref" : "KeyName" }, "SecurityGroups" : [ {"Ref" : "WebServerSecurityGroup"} ], "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 LaunchConfig ", " --region ", { "Ref" : "AWS::Region" }, "\n", "# Start up the cfn-hup daemon to listen for changes to the Web Server metadata\n", "/opt/aws/bin/cfn-hup || error_exit 'Failed to start cfn-hup'\n", "# Signal the status from cfn-init\n", "/opt/aws/bin/cfn-signal -e $? ", " --stack ", { "Ref" : "AWS::StackName" }, " --resource WebServerGroup ", " --region ", { "Ref" : "AWS::Region" }, "\n" ]]}} } }, "WebServerSecurityGroup" : { "Type" : "AWS::EC2::SecurityGroup", "Properties" : { "GroupDescription" : "Enable HTTP access via port 80 locked down to the ELB and SSH access", "SecurityGroupIngress" : [ {"IpProtocol" : "tcp", "FromPort" : "80", "ToPort" : "80", "SourceSecurityGroupOwnerId" : {"Fn::GetAtt" : ["ElasticLoadBalancer", "SourceSecurityGroup.OwnerAlias"]},"SourceSecurityGroupName" : {"Fn::GetAtt" : ["ElasticLoadBalancer", "SourceSecurityGroup.GroupName"]}}, {"IpProtocol" : "tcp", "FromPort" : "22", "ToPort" : "22", "CidrIp" : { "Ref" : "SSHLocation"}} ] } } }, "Outputs" : { "WebsiteURL" : { "Description" : "Application URL", "Value" : { "Fn::Join" : ["", ["http://", { "Fn::GetAtt" : [ "ElasticLoadBalancer", "DNSName" ]}]] } } } }

可用性和影响注意事项

不同的属性会对堆栈中的资源造成不同的影响。您可以使用 AWS CloudFormation 更新任何属性;但是您应该在进行任何更改之前考虑以下问题:

  1. 更新会如何影响资源本身?例如,更新警报阈值会使警报在更新期间处于非活动状态。正如我们所见,更改实例类型时需要停止和重启实例。AWS CloudFormation 使用适用于基础资源的“Update”或“Modify”操作对资源进行更改。要了解更改的影响,您应该查看特定资源的文档。

  2. 更改可变还是不可变?对资源属性的某些更改,如更改 Amazon EC2 实例上的 AMI,不受基础服务的支持。如果更改可变,AWS CloudFormation 将使用适用于基础资源的“Update”或“Modify”类型 API。对于不可变的属性更改,AWS CloudFormation 将用更新后的属性创建新资源,然后再删除旧资源之前将此资源链接至堆栈。虽然 AWS CloudFormation 尝试减少堆栈资源的停机时间,但替代资源是一个多步骤过程,需要时间。重新配置堆栈期间,您的应用程序不能全面运行。例如,它可能不能为请求提供服务或访问数据库。

相关资源

有关使用 AWS CloudFormation 启动应用程序的更多信息以及集成其它配置与 Puppet 和 Opscode Chef 等部署服务的更多信息,请参阅以下白皮书:

此部分使用的模板为 "Hello, World" PHP 应用程序。模板库中还有一个 Amazon ElastiCache 示例模板,该模板显示如何使用 cfn-hup 和 cfn-init 集成 PHP 应用程序和 ElasticCache,以响应 Amazon ElastiCache 缓存群集配置中的更改,这所有的操作都可通过更新堆栈执行。