本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
更新堆疊
使用 CloudFormation,您可以更新現有堆疊中資源的屬性。更改的範圍可以從簡單的組態變更 (如更新 CloudWatch 警示上的警示閾值),一直到更新 Amazon EC2 執行個體上執行的 Amazon Machine Image (AMI) 等較為複雜的變更項目。範本中的許多 AWS 資源都可以更新,而且我們會繼續新增對更多資源的支援。
本節會逐步講解更新運作中堆疊的簡易程序,它顯示如何使用 範本來使用版本控制系統來設定您的 AWS 基礎設施,就像您針對執行中的軟體使用版本控制一樣。我們將逐步解說以下步驟:
-
建立初始堆疊 – 使用基本 Amazon Linux AMI 建立堆疊,並使用 CloudFormation 協助程式指令碼安裝 Apache Web Server 和簡單的 PHP 應用程式。
-
更新應用程式 – 更新應用程式中的任一檔案,並使用 CloudFormation 部署軟體。
-
更新執行個體類型 – 變更基礎 Amazon EC2 執行個體的執行個體類型。
-
更新 Amazon EC2 執行個體上的 AMI – 變更堆疊中 Amazon EC2 執行個體的 Amazon Machine Image (AMI)。
-
將金鑰對新增至執行個體 – 將 Amazon EC2 金鑰對新增至執行個體,接著更新安全群組以允許 SSH 存取該執行個體。
-
變更堆疊的資源 – 從堆疊中新增與移除資源,並更新範本以將其轉換成可自動調整規模、負載平衡的應用程式。
簡易的應用程式
我們將開始建立堆疊,而本節其餘的部分皆可使用此堆疊。我們所提供的簡易範本能啟動 Apache Web 伺服器上託管的單一執行個體 PHP Web 應用程式,並在 Amazon Linux AMI 上執行該應用程式。
Amazon Linux AMI 會預設安裝 CloudFormation 協助程式指令碼,進而透過該指令碼來安裝 Apache Web 伺服器、PHP 與簡易的 PHP 應用程式。下列範本程式碼片段所顯示的中繼資料會說明要安裝的套件與檔案,此處將以來自 Amazon Linux AMI Yum 儲存庫的 Apache Web 伺服器與 PHP 基礎設施為例。而藉由出現在該程式碼片段中的 Services 區段,可確保系統正在執行 Apache Web 伺服器。在 Amazon EC2 執行個體定義的 Properties 區段中,UserData 屬性所包含的 CloudInit 指令碼會呼叫 cfn-init 以安裝套件與檔案。
"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 或其他儲存庫上,並參考範本的內容。CloudFormation 能夠下載 RPM 或 RubyGems 等套件、參考個別檔案以及解壓縮 .zip
與 .tar
檔案,藉此在 Amazon EC2 執行個體上建立應用程式成品。
範本會啟用並設定 cfn-hup 常駐程式,以便偵聽 Amazon EC2 執行個體中繼資料內針對組態所定義的變更。透過使用 cfn-hup 協助程式,您可以更新應用程式軟體,例如 Apache 或 PHP 的版本,也可以從 CloudFormation 更新 PHP 應用程式檔案本身。範本中相同的 Amazon EC2 資源會提供下列程式碼片段,藉此說明設定 cfn-hup 以呼叫 cfn-init 更新軟體的必要部分,進而因應系統所偵測到的任何中繼資料變更:
"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 安全群組,以便完成堆疊建立作業。
{ "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" : "t2.small", "AllowedValues" : [ "t1.micro", "t2.nano", "t2.micro", "t2.small", "t2.medium", "t2.large", "m1.small", "m1.medium", "m1.large", "m1.xlarge", "m2.xlarge", "m2.2xlarge", "m2.4xlarge", "m3.medium", "m3.large", "m3.xlarge", "m3.2xlarge", "m4.large", "m4.xlarge", "m4.2xlarge", "m4.4xlarge", "m4.10xlarge", "c1.medium", "c1.xlarge", "c3.large", "c3.xlarge", "c3.2xlarge", "c3.4xlarge", "c3.8xlarge", "c4.large", "c4.xlarge", "c4.2xlarge", "c4.4xlarge", "c4.8xlarge", "g2.2xlarge", "g2.8xlarge", "r3.large", "r3.xlarge", "r3.2xlarge", "r3.4xlarge", "r3.8xlarge", "i2.xlarge", "i2.2xlarge", "i2.4xlarge", "i2.8xlarge", "d2.xlarge", "d2.2xlarge", "d2.4xlarge", "d2.8xlarge", "hi1.4xlarge", "hs1.8xlarge", "cr1.8xlarge", "cc2.8xlarge", "cg1.4xlarge" ], "ConstraintDescription" : "must be a valid EC2 instance type." } }, "Mappings" : { "AWSInstanceType2Arch" : { "t1.micro" : { "Arch" : "HVM64" }, "t2.nano" : { "Arch" : "HVM64" }, "t2.micro" : { "Arch" : "HVM64" }, "t2.small" : { "Arch" : "HVM64" }, "t2.medium" : { "Arch" : "HVM64" }, "t2.large" : { "Arch" : "HVM64" }, "m1.small" : { "Arch" : "HVM64" }, "m1.medium" : { "Arch" : "HVM64" }, "m1.large" : { "Arch" : "HVM64" }, "m1.xlarge" : { "Arch" : "HVM64" }, "m2.xlarge" : { "Arch" : "HVM64" }, "m2.2xlarge" : { "Arch" : "HVM64" }, "m2.4xlarge" : { "Arch" : "HVM64" }, "m3.medium" : { "Arch" : "HVM64" }, "m3.large" : { "Arch" : "HVM64" }, "m3.xlarge" : { "Arch" : "HVM64" }, "m3.2xlarge" : { "Arch" : "HVM64" }, "m4.large" : { "Arch" : "HVM64" }, "m4.xlarge" : { "Arch" : "HVM64" }, "m4.2xlarge" : { "Arch" : "HVM64" }, "m4.4xlarge" : { "Arch" : "HVM64" }, "m4.10xlarge" : { "Arch" : "HVM64" }, "c1.medium" : { "Arch" : "HVM64" }, "c1.xlarge" : { "Arch" : "HVM64" }, "c3.large" : { "Arch" : "HVM64" }, "c3.xlarge" : { "Arch" : "HVM64" }, "c3.2xlarge" : { "Arch" : "HVM64" }, "c3.4xlarge" : { "Arch" : "HVM64" }, "c3.8xlarge" : { "Arch" : "HVM64" }, "c4.large" : { "Arch" : "HVM64" }, "c4.xlarge" : { "Arch" : "HVM64" }, "c4.2xlarge" : { "Arch" : "HVM64" }, "c4.4xlarge" : { "Arch" : "HVM64" }, "c4.8xlarge" : { "Arch" : "HVM64" }, "g2.2xlarge" : { "Arch" : "HVMG2" }, "g2.8xlarge" : { "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" }, "d2.xlarge" : { "Arch" : "HVM64" }, "d2.2xlarge" : { "Arch" : "HVM64" }, "d2.4xlarge" : { "Arch" : "HVM64" }, "d2.8xlarge" : { "Arch" : "HVM64" }, "hi1.4xlarge" : { "Arch" : "HVM64" }, "hs1.8xlarge" : { "Arch" : "HVM64" }, "cr1.8xlarge" : { "Arch" : "HVM64" }, "cc2.8xlarge" : { "Arch" : "HVM64" } }, "AWSRegionArch2AMI" : { "us-east-1" : {"HVM64" : "ami-0ff8a91507f77f867", "HVMG2" : "ami-0a584ac55a7631c0c"}, "us-west-2" : {"HVM64" : "ami-a0cfeed8", "HVMG2" : "ami-0e09505bc235aa82d"}, "us-west-1" : {"HVM64" : "ami-0bdb828fd58c52235", "HVMG2" : "ami-066ee5fd4a9ef77f1"}, "eu-west-1" : {"HVM64" : "ami-047bb4163c506cd98", "HVMG2" : "ami-0a7c483d527806435"}, "eu-west-2" : {"HVM64" : "ami-f976839e", "HVMG2" : "NOT_SUPPORTED"}, "eu-west-3" : {"HVM64" : "ami-0ebc281c20e89ba4b", "HVMG2" : "NOT_SUPPORTED"}, "eu-central-1" : {"HVM64" : "ami-0233214e13e500f77", "HVMG2" : "ami-06223d46a6d0661c7"}, "ap-northeast-1" : {"HVM64" : "ami-06cd52961ce9f0d85", "HVMG2" : "ami-053cdd503598e4a9d"}, "ap-northeast-2" : {"HVM64" : "ami-0a10b2721688ce9d2", "HVMG2" : "NOT_SUPPORTED"}, "ap-northeast-3" : {"HVM64" : "ami-0d98120a9fb693f07", "HVMG2" : "NOT_SUPPORTED"}, "ap-southeast-1" : {"HVM64" : "ami-08569b978cc4dfa10", "HVMG2" : "ami-0be9df32ae9f92309"}, "ap-southeast-2" : {"HVM64" : "ami-09b42976632b27e9b", "HVMG2" : "ami-0a9ce9fecc3d1daf8"}, "ap-south-1" : {"HVM64" : "ami-0912f71e06545ad88", "HVMG2" : "ami-097b15e89dbdcfcf4"}, "us-east-2" : {"HVM64" : "ami-0b59bfac6be064b78", "HVMG2" : "NOT_SUPPORTED"}, "ca-central-1" : {"HVM64" : "ami-0b18956f", "HVMG2" : "NOT_SUPPORTED"}, "sa-east-1" : {"HVM64" : "ami-07b14488da8ea02a0", "HVMG2" : "NOT_SUPPORTED"}, "cn-north-1" : {"HVM64" : "ami-0a4eaf6c4454eda75", "HVMG2" : "NOT_SUPPORTED"}, "cn-northwest-1" : {"HVM64" : "ami-6b6a7d09", "HVMG2" : "NOT_SUPPORTED"} } }, "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 Balancing 和 Amazon EC2 Auto Scaling 群組來管理應用程式伺服器的集合。不過,使用 Auto Scaling 群組時需注意部分特殊考量。如需詳細資訊,請參閱更新 Auto Scaling 群組。
建立初始堆疊
基於此範例的目的,我們將使用 從範例範本 AWS Management Console 建立初始堆疊。
警告
完成此程序將部署即時 AWS 服務。只要持續執行這些服務,您便必須按照標準使用費率付費。
從 AWS Management Console建立堆疊
-
複製先前的範本,並在本機系統上將該範本儲存為文字檔案。請記下檔案位置,因為後續步驟仍需使用到該檔案。
-
前往 https://console.aws.amazon.com/cloudformation
,登入 CloudFormation 主控台。 -
選擇 Create new stack (建立新堆疊)。
-
在 Create New Stack (建立新堆疊) 精靈的 Select Template (選取範本) 畫面上,將
UpdateTutorial
輸入至 Name (名稱) 欄位。在相同的頁面上,選取 Upload a template to Amazon S3 (將範本上傳到 Amazon S3),並瀏覽至您在第一個步驟中下載的檔案,然後選擇 Next (下一步)。 -
在 Specify Parameters (指定參數) 畫面的 Instance Type (執行個體類型) 方塊中,輸入
t1.micro
。然後選擇下一步。 -
在 Options (選項) 畫面上,選擇 Next (下一步)。
-
確認 Review (檢閱) 畫面上的所有設定皆符合需求,接著選擇 Create (建立)。
堆疊狀態變成 CREATE_COMPLETE 之後,輸出標籤將顯示網站的 URL。選擇 WebsiteURL 的輸出值,即可看見新的 PHP 應用程式開始運作。
更新應用程式
既然我們已經將堆疊部署完成,接下來便要更新應用程式。我們會簡單地更改應用程式所印出的文字。若要執行此作業,便需要將 echo 命令新增至 index.php 檔案,如下列範本程式碼片段所示:
"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 '<p>Updated version via UpdateStack</p>';\n ",
"?>\n" ]]}, "mode" : "000644", "owner" : "apache", "group" : "apache" }, : } },
透過文字編輯器,即可手動編輯儲存在本機上的範本檔案。
現在,我們將更新堆疊。
從 更新堆疊 AWS Management Console
-
登入 CloudFormation 主控台,網址為:https://https://console.aws.amazon.com/cloudformation
。 -
在 CloudFormation 儀表板上,選擇您先前建立的堆疊,然後選擇 Update Stack (更新堆疊)。
-
在 Update Stack (更新堆疊) 精靈的 Select Template (選取範本) 畫面上,選取 Upload a template to Amazon S3 (將範本上傳到 Amazon S3) 並選擇修改後的範本,然後選擇 Next (下一步)。
-
在 Options (選項) 畫面上,選擇 Next (下一步)。
-
堆疊沒有堆疊政策,因此請選擇 Next (下一步)。在沒有覆寫政策的情況下,所有資源皆可進行更新。
-
確認 Review (檢閱) 畫面上的所有設定皆符合需求,接著選擇 Update (更新)。
如果您從 更新堆疊 AWS Management Console,您會注意到用於建立初始堆疊的參數已預先填入更新堆疊精靈的參數頁面上。如果您是使用 update-stack 命令,輸入的值請務必與原先用來建立堆疊的參數相同。
當堆疊的狀態變成 UPDATE_COMPLETE 時,即可再選擇 WebsiteURL 輸出值,藉此確認應用程式的變更已經生效。在預設情況下,系統每 15 分鐘會執行 cfn-hup 常駐程式一次;因此堆疊更新後,應用程式最多可能需要 15 分鐘才能完成變更。
若要查看已更新的資源集,請前往 CloudFormation 主控台。您可以在 Events (事件) 標籤上檢視堆疊事件。在此情況下,Amazon EC2 執行個體 WebServerInstance 的中繼資料已更新,這會導致 CloudFormation 也重新評估其他資源 (WebServerSecurityGroup
),以確保沒有其他變更。其他堆疊資源都未修改。CloudFormation 只會更新堆疊中受到堆疊任何變更影響的資源。這類變更可能是由系統直接進行 (例如更改屬性或中繼資料),亦可能是因依存項目或資料流入 Ref、GetAtt 或其他內部範本函數而導致。
此處透過這項簡單的更新來說明程序;然而,您還可以針對部署至 Amazon EC2 執行個體的檔案和套件進行更加複雜的變更。例如,您可能會認為需要將 MySQL 與 MySQL 的 PHP 支援新增至執行個體。若要執行此作業,只需將其他套件、檔案與任何其他服務一併新增至組態,接著更新堆疊,即可部署變更。在下列範本程式碼片段中,變更內容會用紅色醒目提示:
"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 應該安裝最新版本的套件。
"packages" : { "yum" : { "httpd" : [], "php" : [] }
您可以選擇指定套件的版本字串;若您在後續的更新堆疊呼叫中更改該版本字串,則系統將部署新版本的套件。下方為使用 RubyGems 套件版本編號的範例。而支援版本控制的任何套件皆可擁有特定版本。
"packages" : { "rubygems" : { "mysql" : [], "rubygems-update" : ["1.6.2"], "rake" : ["0.8.7"], "rails" : ["2.3.11"] } }
更新 Auto Scaling 群組
如果您在範本中使用 Auto Scaling 群組,而不是 Amazon EC2 執行個體資源,更新應用程式的運作方式將完全相同;不過,CloudFormation 不會在 Auto Scaling 群組中跨 Amazon EC2 執行個體提供任何同步或序列化。每部主機上的 cfn-hup 常駐程式均會獨立運作,並按照自身排程來更新應用程式。當您藉由 cfn-hup 來更新執行個體上的組態時,每個執行個體皆會依照自身排程執行 cfn-hup 勾點;而堆疊中的執行個體之間沒有協調性。因此,您應該考量下列事項:
-
如果 Auto Scaling 群組中的所有 Amazon EC2 執行個體同時執行 cfn-hup 變更,更新期間可能無法使用服務。
-
如果系統在不同時間執行 cfn-hup 變更,舊版本與新版本的軟體可能會同時運作。
請考慮強制輪流更新 Auto Scaling 群組中的執行個體,以避免上述問題。如需詳細資訊,請參閱UpdatePolicy 屬性。
變更資源屬性
使用 CloudFormation,您可以變更堆疊中現有資源的屬性。下列小節會說明能解決特定問題的各種更新作業;但您仍可根據自身需求,在堆疊中針對支援更新的任何資源修改任何屬性。
更新執行個體類型
到目前為止,我們所建置的堆疊是採用 t1.micro Amazon EC2 執行個體。假設新建立網站所接收的流量超過 t1.micro 執行個體的處理範圍,而現在您想移至 m1.small Amazon EC2 執行個體類型。一旦執行個體類型的架構有所變更,系統將會使用不同的 AMI 來建立執行個體。當您查看範本中的映射時,則會發現 t1.micro 與 m1.small 的架構別無二致,亦採用相同的 Amazon Linux AMI。
"Mappings" : { "AWSInstanceType2Arch" : { "t1.micro" : { "Arch" : "HVM64" }, "t2.nano" : { "Arch" : "HVM64" }, "t2.micro" : { "Arch" : "HVM64" }, "t2.small" : { "Arch" : "HVM64" }, "t2.medium" : { "Arch" : "HVM64" }, "t2.large" : { "Arch" : "HVM64" }, "m1.small" : { "Arch" : "HVM64" }, "m1.medium" : { "Arch" : "HVM64" }, "m1.large" : { "Arch" : "HVM64" }, "m1.xlarge" : { "Arch" : "HVM64" }, "m2.xlarge" : { "Arch" : "HVM64" }, "m2.2xlarge" : { "Arch" : "HVM64" }, "m2.4xlarge" : { "Arch" : "HVM64" }, "m3.medium" : { "Arch" : "HVM64" }, "m3.large" : { "Arch" : "HVM64" }, "m3.xlarge" : { "Arch" : "HVM64" }, "m3.2xlarge" : { "Arch" : "HVM64" }, "m4.large" : { "Arch" : "HVM64" }, "m4.xlarge" : { "Arch" : "HVM64" }, "m4.2xlarge" : { "Arch" : "HVM64" }, "m4.4xlarge" : { "Arch" : "HVM64" }, "m4.10xlarge" : { "Arch" : "HVM64" }, "c1.medium" : { "Arch" : "HVM64" }, "c1.xlarge" : { "Arch" : "HVM64" }, "c3.large" : { "Arch" : "HVM64" }, "c3.xlarge" : { "Arch" : "HVM64" }, "c3.2xlarge" : { "Arch" : "HVM64" }, "c3.4xlarge" : { "Arch" : "HVM64" }, "c3.8xlarge" : { "Arch" : "HVM64" }, "c4.large" : { "Arch" : "HVM64" }, "c4.xlarge" : { "Arch" : "HVM64" }, "c4.2xlarge" : { "Arch" : "HVM64" }, "c4.4xlarge" : { "Arch" : "HVM64" }, "c4.8xlarge" : { "Arch" : "HVM64" }, "g2.2xlarge" : { "Arch" : "HVMG2" }, "g2.8xlarge" : { "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" }, "d2.xlarge" : { "Arch" : "HVM64" }, "d2.2xlarge" : { "Arch" : "HVM64" }, "d2.4xlarge" : { "Arch" : "HVM64" }, "d2.8xlarge" : { "Arch" : "HVM64" }, "hi1.4xlarge" : { "Arch" : "HVM64" }, "hs1.8xlarge" : { "Arch" : "HVM64" }, "cr1.8xlarge" : { "Arch" : "HVM64" }, "cc2.8xlarge" : { "Arch" : "HVM64" } }, "AWSRegionArch2AMI" : { "us-east-1" : {"HVM64" : "ami-0ff8a91507f77f867", "HVMG2" : "ami-0a584ac55a7631c0c"}, "us-west-2" : {"HVM64" : "ami-a0cfeed8", "HVMG2" : "ami-0e09505bc235aa82d"}, "us-west-1" : {"HVM64" : "ami-0bdb828fd58c52235", "HVMG2" : "ami-066ee5fd4a9ef77f1"}, "eu-west-1" : {"HVM64" : "ami-047bb4163c506cd98", "HVMG2" : "ami-0a7c483d527806435"}, "eu-west-2" : {"HVM64" : "ami-f976839e", "HVMG2" : "NOT_SUPPORTED"}, "eu-west-3" : {"HVM64" : "ami-0ebc281c20e89ba4b", "HVMG2" : "NOT_SUPPORTED"}, "eu-central-1" : {"HVM64" : "ami-0233214e13e500f77", "HVMG2" : "ami-06223d46a6d0661c7"}, "ap-northeast-1" : {"HVM64" : "ami-06cd52961ce9f0d85", "HVMG2" : "ami-053cdd503598e4a9d"}, "ap-northeast-2" : {"HVM64" : "ami-0a10b2721688ce9d2", "HVMG2" : "NOT_SUPPORTED"}, "ap-northeast-3" : {"HVM64" : "ami-0d98120a9fb693f07", "HVMG2" : "NOT_SUPPORTED"}, "ap-southeast-1" : {"HVM64" : "ami-08569b978cc4dfa10", "HVMG2" : "ami-0be9df32ae9f92309"}, "ap-southeast-2" : {"HVM64" : "ami-09b42976632b27e9b", "HVMG2" : "ami-0a9ce9fecc3d1daf8"}, "ap-south-1" : {"HVM64" : "ami-0912f71e06545ad88", "HVMG2" : "ami-097b15e89dbdcfcf4"}, "us-east-2" : {"HVM64" : "ami-0b59bfac6be064b78", "HVMG2" : "NOT_SUPPORTED"}, "ca-central-1" : {"HVM64" : "ami-0b18956f", "HVMG2" : "NOT_SUPPORTED"}, "sa-east-1" : {"HVM64" : "ami-07b14488da8ea02a0", "HVMG2" : "NOT_SUPPORTED"}, "cn-north-1" : {"HVM64" : "ami-0a4eaf6c4454eda75", "HVMG2" : "NOT_SUPPORTED"}, "cn-northwest-1" : {"HVM64" : "ami-6b6a7d09", "HVMG2" : "NOT_SUPPORTED"} }
現在,讓我們使用先前一節所修改的範本來變更執行個體類型。InstanceType 屬於範本的輸入參數,所以我們不需要修改範本,只需在 Stack Update (更新堆疊) 精靈的 Specify Parameters (指定參數) 頁面上變更參數值即可。
從 AWS Management Console更新堆疊
-
前往 https://console.aws.amazon.com/cloudformation
,登入 CloudFormation 主控台。 -
在 CloudFormation 儀表板上,選擇您先前建立的堆疊,然後選擇 Update Stack (更新堆疊)。
-
在 Update Stack (更新堆疊) 精靈的 Select Template (選取範本) 畫面上,選取 Use current template (使用目前的範本),然後選擇 Next (下一步)。
Specify Details (指定詳細資訊) 頁面即會顯示,其中 Specify Parameters (指定參數) 區段會預先填入要用來建立初始堆疊的參數。
-
將 InstanceType 文字方塊的
t1.micro
值變更為m1.small
。然後選擇下一步。 -
在 Options (選項) 畫面上,選擇 Next (下一步)。
-
堆疊沒有堆疊政策,因此請選擇 Next (下一步)。在沒有覆寫政策的情況下,所有資源皆可進行更新。
-
確認 Review (檢閱) 畫面上的所有設定皆符合需求,接著選擇 Update (更新)。
您可以透過啟動和停止執行個體,動態變更 EBS 支援的 Amazon EC2 執行個體的執行個體類型。CloudFormation 會更新執行個體類型並重新啟動執行個體,嘗試最佳化變更,因此執行個體 ID 不會變更。然而,重新啟動執行個體時,該執行個體的公有 IP 地址會隨之變更。為了確保彈性 IP 地址在變更後正確繫結,CloudFormation 也會更新彈性 IP 地址。您可以在 CloudFormation 主控台的事件索引標籤上查看變更。
若要從 檢查執行個體類型 AWS Management Console,請開啟 Amazon EC2 主控台,並在該處找到您的執行個體。
更新 Amazon EC2 執行個體上的 AMI
現在,讓我們看看如何變更執行個體上所執行的 Amazon Machine Image (AMI)。我們會更新堆疊以啟動 AMI 變更作業,藉此使用新的 Amazon EC2 執行個體類型,例如屬於 HVM64 執行個體類型的 t2.medium。
如先前一節所述,我們將透過現有的範本來變更範例堆疊所使用的執行個體類型。請在 Stack Update (更新堆疊) 精靈的 Specify Parameters (指定參數) 頁面上,變更執行個體類型的值。
在此情況下,我們無法直接啟動和停止執行個體來修改 AMI;CloudFormation 會將此視為資源的不可變屬性的變更。為了變更不可變的屬性,CloudFormation 必須啟動替代資源,在此情況下,新的 Amazon EC2 執行個體會執行新的 AMI。
新執行個體執行後,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
-
建立新的 AMI,其包含應用程式或作業系統變更內容。如需詳細資訊,請參閱《Amazon EC2 使用者指南》中的建立 Amazon EBS 後端 AMI。 Amazon EC2
-
更新範本,以便採納新的 AMI ID。
-
更新堆疊, AWS Management Console 如 中所述,或使用 AWS 命令 ,從 更新應用程式更新堆疊update-stack。
更新堆疊時,CloudFormation 即會偵測到 AMI ID 有所變更,然後啟動堆疊更新作業 (與上述更新的觸發方式相同)。
更新 Auto Scaling 群組的 Amazon EC2 啟動組態
如果您是使用 Auto Scaling 群組,而非 Amazon EC2 執行個體,則更新執行中的執行個體的程序會稍有不同。您可以透過 Auto Scaling 資源,將 Amazon EC2 執行個體的組態 (如執行個體類型或 AMI ID) 封裝在 Auto Scaling 啟動組態中。您可以採用先前各節所示的 Amazon EC2 執行個體資源變更方式,以便變更啟動組態。不過,變更啟動組態並不會影響 Auto Scaling 群組中任何正在運作的 Amazon EC2 執行個體;而更新的啟動組態僅適用於更新後所建立的新執行個體。
透過更新屬性,即可將變更傳播至 Auto Scaling 群組中所有執行個體的啟動組態。如需詳細資訊,請參閱UpdatePolicy 屬性。
新增資源屬性
到目前為止,我們已經了解範本中資源現有屬性的變更方式。除此之外,您還可以在範本中新增原本沒有指定的屬性。為了說明這項操作,我們會將 Amazon EC2 金鑰對新增至現有的 EC2 執行個體,接著在 Amazon EC2 安全群組中開啟連接埠 22,即可使用 Secure Shell (SSH) 來存取該執行個體。
將金鑰對新增至執行個體
在現有的 Amazon EC2 執行個體中新增 SSH 存取
-
將兩個額外參數新增至範本,藉此傳遞現有的 Amazon EC2 金鑰對名稱與 SSH 位置。
"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." } : },
-
將 KeyName 屬性新增至 Amazon EC2 執行個體。
"WebServerInstance": { "Type" : "AWS::EC2::Instance", : "Properties": { :
"KeyName" : { "Ref" : "KeyName" },
: } }, -
將連接埠 22 與 SSH 位置新增至 Amazon EC2 安全群組的輸入規則。
"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"} ] } },
-
更新堆疊, AWS Management Console 如 中所述,或使用 AWS 命令 ,從 更新應用程式更新堆疊update-stack。
變更堆疊的資源
應用程式需求可能會隨著時間而變更,CloudFormation 可讓您變更構成堆疊的資源集。我們會從新增資源屬性取得單一執行個體應用程式,接著更新堆疊以將其轉換成可自動調整規模、負載平衡的應用程式,藉此說明這項操作。
此操作會使用彈性 IP 地址來建立簡易的單一執行個體 PHP 應用程式。我們現在會在更新期間變更該應用程式的資源,進而將其轉換為具備高可用性、可自動調整規模且負載平衡的應用程式。
-
新增 Elastic Load Balancer 資源。
"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" } } }
-
將範本中的 EC2 執行個體轉換成 Auto Scaling 啟動組態。兩者屬性完全相同,因此僅需變更類型名稱,從:
"WebServerInstance"
: { "Type" :"AWS::EC2::Instance"
,至:
"LaunchConfig"
: { "Type" :"AWS::AutoScaling::LaunchConfiguration"
,為了讓範本清晰好讀,我們會將資源名稱從 WebServerInstance 變更為 LaunchConfig;而您必須更新 cfn-init 與 cfn-hup 所參考的資源名稱 (僅需搜尋 WebServerInstance 並用 LaunchConfig 取而代之即可,但 cfn-signal 除外)。如果是 cfn-signal,您便必須向 Auto Scaling 群組 (WebServerGroup) 傳送訊號,而非發送至執行個體;如下列程式碼片段所示:
"# Signal the status from cfn-init\n", "/opt/aws/bin/cfn-signal -e $? ", " --stack ", { "Ref" : "AWS::StackName" }, " --resource
WebServerGroup
", " --region ", { "Ref" : "AWS::Region" }, "\n" -
新增 Auto Scaling 群組資源。
"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" } } }
-
更新安全群組定義,藉此鎖定負載平衡器傳入執行個體的流量。
"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,進而傳回 Elastic Load Balancer 的 DNS 名稱,並將該名稱作為應用程式的位置;從:
"WebsiteURL" : { "Value" : { "Fn::Join" : ["", ["http://", { "Fn::GetAtt" : [ "
WebServerInstance
", "PublicDnsName
" ]}]]}, "Description" : "Application URL" }至:
"WebsiteURL" : { "Value" : { "Fn::Join" : ["", ["http://", { "Fn::GetAtt" : [ "
ElasticLoadBalancer
", "DNSName
" ]}]]}, "Description" : "Application URL" }
下列範例顯示完整範本,以供參考。若您使用此範本更新堆疊,則可將簡易的單一執行個體應用程式轉換為具備高可用性、支援多個可用區域、可自動調整規模且負載平衡的應用程式。系統僅會修改需要更新的資源,所以此應用程式所存放的任何資料將不會受到影響。現在,您可以隨著需求變更,使用 CloudFormation 來增加或增強您的堆疊。
{ "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" : "t2.small", "AllowedValues" : [ "t1.micro", "t2.nano", "t2.micro", "t2.small", "t2.medium", "t2.large", "m1.small", "m1.medium", "m1.large", "m1.xlarge", "m2.xlarge", "m2.2xlarge", "m2.4xlarge", "m3.medium", "m3.large", "m3.xlarge", "m3.2xlarge", "m4.large", "m4.xlarge", "m4.2xlarge", "m4.4xlarge", "m4.10xlarge", "c1.medium", "c1.xlarge", "c3.large", "c3.xlarge", "c3.2xlarge", "c3.4xlarge", "c3.8xlarge", "c4.large", "c4.xlarge", "c4.2xlarge", "c4.4xlarge", "c4.8xlarge", "g2.2xlarge", "g2.8xlarge", "r3.large", "r3.xlarge", "r3.2xlarge", "r3.4xlarge", "r3.8xlarge", "i2.xlarge", "i2.2xlarge", "i2.4xlarge", "i2.8xlarge", "d2.xlarge", "d2.2xlarge", "d2.4xlarge", "d2.8xlarge", "hi1.4xlarge", "hs1.8xlarge", "cr1.8xlarge", "cc2.8xlarge", "cg1.4xlarge" ], "ConstraintDescription" : "must be a valid EC2 instance type." } }, "Mappings" : { "AWSInstanceType2Arch" : { "t1.micro" : { "Arch" : "HVM64" }, "t2.nano" : { "Arch" : "HVM64" }, "t2.micro" : { "Arch" : "HVM64" }, "t2.small" : { "Arch" : "HVM64" }, "t2.medium" : { "Arch" : "HVM64" }, "t2.large" : { "Arch" : "HVM64" }, "m1.small" : { "Arch" : "HVM64" }, "m1.medium" : { "Arch" : "HVM64" }, "m1.large" : { "Arch" : "HVM64" }, "m1.xlarge" : { "Arch" : "HVM64" }, "m2.xlarge" : { "Arch" : "HVM64" }, "m2.2xlarge" : { "Arch" : "HVM64" }, "m2.4xlarge" : { "Arch" : "HVM64" }, "m3.medium" : { "Arch" : "HVM64" }, "m3.large" : { "Arch" : "HVM64" }, "m3.xlarge" : { "Arch" : "HVM64" }, "m3.2xlarge" : { "Arch" : "HVM64" }, "m4.large" : { "Arch" : "HVM64" }, "m4.xlarge" : { "Arch" : "HVM64" }, "m4.2xlarge" : { "Arch" : "HVM64" }, "m4.4xlarge" : { "Arch" : "HVM64" }, "m4.10xlarge" : { "Arch" : "HVM64" }, "c1.medium" : { "Arch" : "HVM64" }, "c1.xlarge" : { "Arch" : "HVM64" }, "c3.large" : { "Arch" : "HVM64" }, "c3.xlarge" : { "Arch" : "HVM64" }, "c3.2xlarge" : { "Arch" : "HVM64" }, "c3.4xlarge" : { "Arch" : "HVM64" }, "c3.8xlarge" : { "Arch" : "HVM64" }, "c4.large" : { "Arch" : "HVM64" }, "c4.xlarge" : { "Arch" : "HVM64" }, "c4.2xlarge" : { "Arch" : "HVM64" }, "c4.4xlarge" : { "Arch" : "HVM64" }, "c4.8xlarge" : { "Arch" : "HVM64" }, "g2.2xlarge" : { "Arch" : "HVMG2" }, "g2.8xlarge" : { "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" }, "d2.xlarge" : { "Arch" : "HVM64" }, "d2.2xlarge" : { "Arch" : "HVM64" }, "d2.4xlarge" : { "Arch" : "HVM64" }, "d2.8xlarge" : { "Arch" : "HVM64" }, "hi1.4xlarge" : { "Arch" : "HVM64" }, "hs1.8xlarge" : { "Arch" : "HVM64" }, "cr1.8xlarge" : { "Arch" : "HVM64" }, "cc2.8xlarge" : { "Arch" : "HVM64" } }, "AWSRegionArch2AMI" : { "us-east-1" : {"HVM64" : "ami-0ff8a91507f77f867", "HVMG2" : "ami-0a584ac55a7631c0c"}, "us-west-2" : {"HVM64" : "ami-a0cfeed8", "HVMG2" : "ami-0e09505bc235aa82d"}, "us-west-1" : {"HVM64" : "ami-0bdb828fd58c52235", "HVMG2" : "ami-066ee5fd4a9ef77f1"}, "eu-west-1" : {"HVM64" : "ami-047bb4163c506cd98", "HVMG2" : "ami-0a7c483d527806435"}, "eu-west-2" : {"HVM64" : "ami-f976839e", "HVMG2" : "NOT_SUPPORTED"}, "eu-west-3" : {"HVM64" : "ami-0ebc281c20e89ba4b", "HVMG2" : "NOT_SUPPORTED"}, "eu-central-1" : {"HVM64" : "ami-0233214e13e500f77", "HVMG2" : "ami-06223d46a6d0661c7"}, "ap-northeast-1" : {"HVM64" : "ami-06cd52961ce9f0d85", "HVMG2" : "ami-053cdd503598e4a9d"}, "ap-northeast-2" : {"HVM64" : "ami-0a10b2721688ce9d2", "HVMG2" : "NOT_SUPPORTED"}, "ap-northeast-3" : {"HVM64" : "ami-0d98120a9fb693f07", "HVMG2" : "NOT_SUPPORTED"}, "ap-southeast-1" : {"HVM64" : "ami-08569b978cc4dfa10", "HVMG2" : "ami-0be9df32ae9f92309"}, "ap-southeast-2" : {"HVM64" : "ami-09b42976632b27e9b", "HVMG2" : "ami-0a9ce9fecc3d1daf8"}, "ap-south-1" : {"HVM64" : "ami-0912f71e06545ad88", "HVMG2" : "ami-097b15e89dbdcfcf4"}, "us-east-2" : {"HVM64" : "ami-0b59bfac6be064b78", "HVMG2" : "NOT_SUPPORTED"}, "ca-central-1" : {"HVM64" : "ami-0b18956f", "HVMG2" : "NOT_SUPPORTED"}, "sa-east-1" : {"HVM64" : "ami-07b14488da8ea02a0", "HVMG2" : "NOT_SUPPORTED"}, "cn-north-1" : {"HVM64" : "ami-0a4eaf6c4454eda75", "HVMG2" : "NOT_SUPPORTED"}, "cn-northwest-1" : {"HVM64" : "ami-6b6a7d09", "HVMG2" : "NOT_SUPPORTED"} } }, "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" ]}]] } } } }
可用性與影響考量事項
不同屬性會對堆疊中的資源造成不同影響。您可以善用 CloudFormation 來更新任何屬性;但進行任何變更之前,應考量下列問題:
-
更新作業對資源本身有何影響? 舉例來說,更新警示閾值會導致警示在更新期間處於非作用中狀態。如我們所見,變更執行個體類型需要停止並重新啟動執行個體。CloudFormation 會使用基礎資源的更新或修改動作來變更資源。如需了解更新造成的影響,請查閱特定資源的文件。
-
更改內容屬於可變或不可變項目? 基礎服務並不支援部分資源屬性變更操作,例如:更改 Amazon EC2 執行個體上的 AMI。如果更改內容屬於可變項目,CloudFormation 將針對基礎資源使用 Update (更新) 或 Modify (修改) 類型的 API。如果屬性更改屬於不可變項目,則 CloudFormation 會使用更新後的屬性來建立新資源,並將這些資源連結至堆疊,接著刪除舊資源。雖然 CloudFormation 會嘗試縮短堆疊資源的停機時間,但替換資源屬於多步驟程序,需要一些時間才能完成。重新設定堆疊期間,應用程式將無法完全正常運作。例如,應用程式可能無法處理請求或存取資料庫;
相關資源
如需使用 CloudFormation 啟動應用程式及整合其他組態與部署服務 (如 Puppet 和 Opscode Chef) 的詳細資訊,請參閱下列白皮書:
本節中所使用的範本為 "Hello World" PHP 應用程式。範本程式庫亦提供 Amazon ElastiCache 範例範本,說明如何善用 cfn-hup 與 cfn-init 來整合 PHP 應用程式與 ElasticCache,藉此回應 Amazon ElastiCache 快取叢集組態的變更;您可以透過 Update Stack (更新堆疊) 精靈執行所有操作。