在雲端環境中,使用 CloudFormation 進行基礎設施即程式碼(IaC)的管理至關重要。為了確保 CloudFormation 範本的品質和可靠性,驗證和檢查範本是不可或缺的步驟。cfn-lint 提供了預設規則檢查,而 cloudformation-guard 則允許自定義規則,更靈活地符合特定需求。選擇合適的工具取決於專案規模和規範複雜度。佈署堆積疊時,除了基本的 create-stack 和 update-stack 指令外,deploy 子命令提供更簡潔的佈署流程,並透過變更集預覽變更,提升安全性。然而,佈署過程中仍需注意資源的刪除保護設定,避免回復失敗導致資源殘留。妥善運用這些工具和技巧,能有效提升 CloudFormation 的使用效率,降低佈署風險。
驗證、程式碼檢查及佈署堆積疊
在前面的章節中,我們已經討論瞭如何撰寫CloudFormation範本,接下來我們將探討如何驗證和檢查這些範本,以確保它們符合最佳實踐和內部規範。我們將介紹兩個重要的工具:cfn-lint和cloudformation-guard。
使用cloudformation-guard進行自定義規則檢查
cloudformation-guard使用一種專門的領域特定語言(DSL)來撰寫規則。首先,我們需要在系統上安裝cloudformation-guard。
安裝cloudformation-guard
在macOS上安裝非常簡單:
$ brew install cloudformation-guard
對於其他作業系統,如Ubuntu,我們需要使用curl指令:
$ curl --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/aws-cloudformation/cloudformation-guard/main/install-guard.sh | sh
對於Windows安裝,請參考官方:https://github.com/aws-cloudformation/cloudformation-guard#windows-10-install-rust-and-cargo。
編寫自定義規則
cloudformation-guard沒有像cfn-lint那樣預設的檢查規則,因此我們需要自行撰寫規則。下面是一個範例規則,用於檢查所有VPC子網路資源型別是否具有必要的標籤鍵:
let subnets = Resources.*[ Type == 'AWS::EC2::Subnet' ]
rule no_tags_assigned when %subnets !empty {
%subnets.Properties.Tags[*] {
Key in ["Env", "Name"]
<<
The subnet is missing Env or Name tag key
>>
}
}
執行規則檢查
執行以下指令來檢查範本:
$ cfn-guard validate \
-d core_full.yaml \
-r cfn_guard_rules/subnets_have_tags.guard
如果範本符合規則,則不會有任何輸出。讓我們針對一個故意缺少標籤的範本進行檢查:
$ cfn-guard validate \
-d core_missing_tag.yaml \
-r cfn_guard_rules/subnets_have_tags.guard
輸出將顯示不符合規範的資源和相關的錯誤訊息。
選擇適合的檢查工具
cfn-lint和cloudformation-guard都是非常強大的工具,但它們有不同的優缺點。cfn-lint具有預設的檢查規則,而cloudformation-guard需要自行撰寫規則,但其DSL更簡單易用。
我們的建議
根據實際需求選擇合適的工具。如果您執行的是小型基礎設施並希望進行基本的檢查,cfn-lint是一個不錯的選擇。如果您有一套強大的內部規範並希望更容易地撰寫自定義規則,那麼cloudformation-guard是更好的選擇。
佈署堆積疊
在第1章中,我們使用簡單的指令建立了堆積疊:
$ aws cloudformation create-stack --stack-name ... --template-body file://...
這個指令呼叫了CloudFormation的CreateStack API。當我們需要更新堆積疊時,我們會呼叫UpdateStack API:
$ aws cloudformation update-stack --stack-name ... --template-body file://...
在這兩種情況下,AWS CLI都會呼叫ListStacks API方法來檢查堆積疊是否存在。
重要考量
在佈署堆積疊之前,請確保範本已經透過驗證和檢查,以避免錯誤和不符合規範的資源被建立。
佈署前的檢查清單
- 範本驗證:使用
cfn-lint和cloudformation-guard進行範本驗證。 - 資源檢查:檢查範本中的資源是否符合內部規範和最佳實踐。
- 引數檢查:檢查範本中的引數是否正確和完整。
佈署堆積疊的最佳實踐
- 使用版本控制:將範本儲存在版本控制系統中,以便跟蹤變更。
- 自動化佈署:使用CI/CD管道自動化佈署堆積疊。
- 監控和日誌記錄:監控堆積疊的效能和日誌記錄,以便及時發現問題。
隨著雲端運算技術的不斷發展,基礎設施即程式碼(IaC)的實踐將變得越來越重要。未來,我們可以期待看到更多與IaC相關的工具和技術的發展。
參考資料
程式碼範例
import boto3
# 建立 CloudFormation 使用者端
cf_client = boto3.client('cloudformation')
# 建立堆積疊
def create_stack(stack_name, template_body):
try:
response = cf_client.create_stack(
StackName=stack_name,
TemplateBody=template_body
)
print(response)
except Exception as e:
print(e)
# 更新堆積疊
def update_stack(stack_name, template_body):
try:
response = cf_client.update_stack(
StackName=stack_name,
TemplateBody=template_body
)
print(response)
except Exception as e:
print(e)
# 刪除堆積疊
def delete_stack(stack_name):
try:
response = cf_client.delete_stack(
StackName=stack_name
)
print(response)
except Exception as e:
print(e)
內容解密:
上述 Python 程式碼範例展示瞭如何使用 Boto3 函式庫與 AWS CloudFormation 服務進行互動。程式碼中定義了三個函式:create_stack、update_stack 和 delete_stack,分別用於建立、更新和刪除 CloudFormation 堆積疊。這些函式使用了 Boto3 的 cloudformation 使用者端來呼叫相應的 CloudFormation API 操作。
-
匯入 Boto3 函式庫:首先,程式碼匯入了
boto3函式庫,這是一個 AWS 的 SDK for Python,它允許 Python 開發者撰寫軟體時使用 Amazon 服務。 -
建立 CloudFormation 使用者端:使用
boto3.client('cloudformation')建立了一個 CloudFormation 的使用者端物件cf_client,這個物件將被用來呼叫 CloudFormation 的 API。 -
定義建立堆積疊函式:
create_stack函式接受堆積疊名稱和範本內容作為引數,使用cf_client.create_stack方法建立一個新的 CloudFormation 堆積疊。如果操作成功,它將列印預出回應內容;如果發生錯誤,它將捕捉異常並列印錯誤訊息。 -
定義更新堆積疊函式:
update_stack函式同樣接受堆積疊名稱和範本內容作為引數,使用cf_client.update_stack方法更新指定的 CloudFormation 堆積疊。處理邏輯與建立堆積疊函式類別似。 -
定義刪除堆積疊函式:
delete_stack函式接受堆積疊名稱作為引數,使用cf_client.delete_stack方法刪除指定的 CloudFormation 堆積疊。同樣地,它會處理可能的異常。
這些函式為管理和維護 CloudFormation 堆積疊提供了一個基礎的 Python 介面,可以根據具體需求進行擴充套件和定製。
graph LR
A[開始] --> B{是否建立堆積疊?}
B --> |是| C[呼叫 create_stack 函式]
B --> |否| D{是否更新堆積疊?}
D --> |是| E[呼叫 update_stack 函式]
D --> |否| F{是否刪除堆積疊?}
F --> |是| G[呼叫 delete_stack 函式]
F --> |否| H[結束]
C --> H
E --> H
G --> H
圖表翻譯:
此圖表展示了一個簡單的流程控制圖,用於決定是否建立、更新或刪除 CloudFormation 堆積疊。流程從「開始」開始,然後根據條件判斷進行不同的操作:
- 如果需要建立堆積疊,則呼叫
create_stack函式。 - 如果需要更新堆積疊,則呼叫
update_stack函式。 - 如果需要刪除堆積疊,則呼叫
delete_stack函式。 流程最終都會回到「結束」。這個流程圖幫助理解在不同操作需求下,程式應該如何執行相應的函式。
使用變更集佈署堆積疊
變更集(Change Sets)是一組將在佈署期間應用於堆積疊的變更。我們可以建立、審查、執行或甚至刪除變更集,具體取決於這些變更是否符合預期。
佈署堆積疊步驟
-
建立堆積疊:首先,我們需要建立一個堆積疊。
$ aws cloudformation create-stack \ --stack-name core \ --template-body file://core_partial.yaml \ --parameters file://testing.json -
建立變更集:接下來,我們為這個堆積疊建立一個變更集,其中包含額外的資源。
$ aws cloudformation create-change-set \ --stack-name core \ --change-set-name our-change-set \ --template-body file://core_full.yaml \ --parameters file://testing.json \ --capabilities CAPABILITY_IAM執行上述命令後,我們將收到類別似以下的輸出:
{ "Id": "arn:aws:cloudformation:REGION:ACCT_ID:changeSet/our-change-set/bd04aeb3-386b-44d7-a25c-5fe626c24aed", "StackId": "arn:aws:cloudformation:REGION:ACCT_ID:stack/core/00697420-1123-11ea-9d40-02433c861a1c" } -
審查變更集:我們可以使用 AWS CLI 或 AWS 控制檯來審查這個變更集。
- 使用 AWS CLI:
輸出結果將顯示變更的詳細資訊,例如:
$ aws cloudformation describe-change-set \ --change-set-name arn:aws:cloudformation:REGION:ACCT_ID:changeSet/our-change-set/bd04aeb3-386b-44d7-a25c-5fe626c24aed{ "Changes": [ { "Type": "Resource", "ResourceChange": { "Action": "Add", "LogicalResourceId": "AdminRole", "ResourceType": "AWS::IAM::Role", "Scope": [], "Details": [] } }, { "Type": "Resource", "ResourceChange": { "Action": "Add", "LogicalResourceId": "DevRole", "ResourceType": "AWS::IAM::Role", "Scope": [], "Details": [] } } ] }內容解密:
- 在這個變更集中,我們可以看到兩個新的 IAM 角色(AdminRole 和 DevRole)將被新增到堆積疊中。
Action欄位表示將要執行的操作(新增、修改或刪除)。LogicalResourceId是資源在範本中的邏輯 ID。ResourceType表示資源的型別,例如 AWS::IAM::Role。
- 使用 AWS CLI:
-
執行變更集:審查完成後,我們可以執行這個變更集。
$ aws cloudformation execute-change-set --change-set-name our-change-set --stack-name core
使用 deploy 子命令
另一個有用的子命令是 deploy,它簡化了堆積疊的佈署過程。
$ aws cloudformation deploy --stack-name foo --template-file bar
與 create-stack 或 update-stack 不同,deploy 是不可變的。如果堆積疊不存在,它將建立堆積疊;如果堆積疊已存在,它將更新堆積疊。
主要差異
deploy使用變更集來執行堆積疊佈署。deploy使用--template-file引數而不是--template-body。deploy不支援引數檔案,而是使用--parameter-overrides來指定引數。deploy將等待堆積疊建立完成或失敗後才傳回結果。
示例
$ aws cloudformation deploy \
--stack-name core \
--template-file core_full.yaml \
--capabilities CAPABILITY_IAM \
--parameter-overrides \
VpcCidr="10.1.0.0/16" \
Environment="test"
內容解密:
- 在這個例子中,我們使用
deploy命令來佈署core堆積疊。 --template-file指定了範本檔案的路徑。--capabilities CAPABILITY_IAM表示這個堆積疊需要建立 IAM 資源。--parameter-overrides用於覆寫範本中的引數。
處理錯誤
CloudFormation 堆積疊佈署的預設行為是在發生錯誤時回復到前一個狀態。然而,這在某些情況下可能會引起問題,例如當資源啟用了終止保護而建立失敗時,CloudFormation 將無法清理這些資源。
示例:啟用刪除保護的負載平衡器
// webtier_failing.yaml
WebTierLoadBalancer:
Type: 'AWS::ElasticLoadBalancingV2::LoadBalancer'
Properties:
DeletionProtection: true
內容解密:
- 在這個例子中,我們定義了一個負載平衡器資源,並啟用了刪除保護。
- 如果這個資源建立失敗並且堆積疊回復,CloudFormation 將無法刪除這個資源,因為它啟用了刪除保護。