我的場景
在 CloudFormation 範本中,我有一個 VPC、一個公有子網路和一個私人子網路。在公共子網路中,我的實例中有亞馬遜 NAT AMI。在私有子網路中,我在內部 LoadBalancer 後面有一個自動縮放群組。這個autoScaling群組有一個LaunchConfig來安裝有示範網頁的httpd。
問題
在此私有子網路自動擴充群組中啟動的 EC2 執行個體不會安裝 Web 伺服器。這會導致我的 ELB 失敗並回滾整個 cloudformation 堆疊。但是,我可以在創建後透過 SSH 登錄,這樣我就可以成功 wget 互聯網網頁並手動使用 yum install httpd。這透過使 ELB 檢查滿意來修復我的 cloudFormation 堆疊。 /var/log/cloudinit-output.log 表示實例在初始化期間無法解析 amazon yum 儲存庫。
我有一種感覺,這可能是由於在 NAT 執行個體完全啟動並工作之前在新的 EC2 執行個體中啟動 LaunchConfig 造成的。我嘗試將 'DependsOn' : 'NATInstance' 新增至 AutoScaling 群組,但這並沒有解決問題。
你能幫我嗎?
答案1
Cloudwatcher 的答案是正確的,但我想為將來遇到類似問題的其他人詳細說明。
當資源發出已完成訊號時,就會滿足 CloudFormation 範本中的「DependsOn」屬性。預設情況下,我相信這是亞馬遜創建資源的時間。在我的範例中,NAT 實例實際上已創建,此時實例正在發送訊號。但是,實例內部的配置和設定尚未完成,因此在其他實例嘗試使用 NAT 之前,NAT 仍處於不可操作狀態。其他實例隨後失敗,因為它們無法透過 NAT 實例獲得網路連線。
您可以自行手動覆蓋預設訊號。這意味著您可以執行您的操作,然後在完成後發出信號。然後,依賴它的所有其他資源的「DependsOn」屬性將正常運作。您可以透過在 EC2 執行個體內使用一些亞馬遜幫助程式腳本(特別是「cfn-init」和「cfn-signal」)來完成此操作。在 EC2 執行個體(或自動擴充組)的「UserData」屬性中,您可以安裝 aws-cfn-bootstrap 來取得腳本(或您正在使用的套件管理器)。然後,您可以在 UserData 內執行初始化步驟,完成後,使用 cfn-signal 發出資源已完成的訊號。這是我的例子:
"UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [
"#!/bin/bash -xe\n",
"yum update -y aws-cfn-bootstrap\n",
"wget <<URL FOR YOUR INIT BASH SCRIPT HERE>> -O - | bash\n",
"/opt/aws/bin/cfn-init -v ",
" --stack ", { "Ref" : "AWS::StackName" },
" --resource <RESOURCE TO SIGNAL HERE> ",
" --region ", { "Ref" : "AWS::Region" }, "\n",
"/opt/aws/bin/cfn-signal -e $? ",
" --stack ", { "Ref" : "AWS::StackName" },
" --resource <RESOURCE TO SIGNAL HERE> ",
" --region ", { "Ref" : "AWS::Region" }, "\n"
]]}}
我希望這可以幫助別人。
答案2
圍繞安全群組和允許流量等問題需要考慮一些事項。但具體到 NAT,請確保在 NAT 啟動配置中您沒有發出
/opt/aws/bin/cfn-signal
直到您的設定和直通腳本完成。鑑於您「依賴」NAT,在 CloudFormation 堆疊收到此訊號之前,它不會繼續。
[編輯] 如果有人在今天(2015-12-18)之後看到這個,你真的應該考慮移動 AWS 提供的 NAT 託管服務。https://aws.amazon.com/about-aws/whats-new/2015/12/introducing-amazon-vpc-nat-gateway-a-management-nat-service/