CloudFormation StackSets 提供了在 AWS 雲端環境中跨多區域和多帳戶佈署一致性基礎設施的有效方法。對於需要在不同區域或帳戶中佈署相同應用程式堆積疊的場景,StackSets 能簡化管理流程,避免重複手動操作,並確保佈署的一致性。透過 StackSets,開發團隊可以集中管理 CloudFormation 堆積疊,降低管理成本並提升效率。同時,StackSets 的容錯機制能隔離單一區域或帳戶的佈署錯誤,避免影響整體基礎設施的穩定性,進而提升系統的可靠性。文章中的程式碼範例示範瞭如何使用 AWS CLI 和 Python SDK 建立和管理 StackSets,包含設定引數、選擇目標區域和帳戶,以及設定 Target Account Gates 等操作,方便讀者快速上手。

使用 StackSets 佈署至多區域與多帳戶

在前一章中,我們學習瞭如何使用 CloudFormation 進行持續整合與佈署(CI/CD),並建立了一個完整的 CD 管道。本章將探討另一個重要的主題:StackSets。StackSets 是 CloudFormation 的一部分,允許我們將堆積疊佈署到不同的區域和帳戶。

StackSets 簡介

StackSets 是一種管理工具,讓我們能夠跨多個區域和帳戶佈署和管理 CloudFormation 堆積疊。這對於管理大型和企業級基礎設施非常有用,無論是在全球託管軟體即服務(SaaS)平台還是在 Amazon Web Services(AWS)雲中執行分散式系統。

StackSets 的優勢

  • 跨區域佈署:能夠在多個 AWS 區域佈署相同的堆積疊。
  • 跨帳戶佈署:支援在多個 AWS 帳戶中佈署堆積疊。
  • 集中管理:提供集中式管理功能,簡化跨多個區域和帳戶的資源管理。

佈署至多個區域

使用 StackSets,我們可以輕鬆地將相同的 CloudFormation 堆積疊佈署到多個 AWS 區域。這對於需要在全球多個區域佈署應用程式或服務的場景非常有用。

步驟概述

  1. 建立 StackSet:在 AWS 管理控制檯或使用 AWS CLI 建立一個新的 StackSet。
  2. 定義範本:指定用於佈署的 CloudFormation 範本。
  3. 選擇目標區域:選擇要在哪些區域佈署堆積疊。
  4. 佈署堆積疊:StackSet 將根據指定的範本在選定的區域佈署堆積疊。

範例程式碼:建立 StackSet 並佈署至多個區域

Resources:
  MyStackSet:
    Type: 'AWS::CloudFormation::StackSet'
    Properties:
      StackSetName: !Sub 'my-stackset-${AWS::Region}'
      Description: 'My StackSet'
      TemplateURL: !Sub 'https://s3.${AWS::Region}.amazonaws.com/my-bucket/my-template.yaml'
      Parameters:
        - ParameterKey: InstanceType
          ParameterValue: t2.micro
      Capabilities:
        - CAPABILITY_IAM
      PermissionModel: SELF_MANAGED
import boto3

cloudformation = boto3.client('cloudformation')

def create_stack_set(stack_set_name, template_url):
    response = cloudformation.create_stack_set(
        StackSetName=stack_set_name,
        TemplateURL=template_url,
        Capabilities=['CAPABILITY_IAM']
    )
    return response

def deploy_to_regions(stack_set_name, regions):
    response = cloudformation.create_stack_instances(
        StackSetName=stack_set_name,
        Regions=regions
    )
    return response

# 使用範例
stack_set_name = 'my-stackset'
template_url = 'https://s3.amazonaws.com/my-bucket/my-template.yaml'
regions = ['us-east-1', 'us-west-2']

create_stack_set(stack_set_name, template_url)
deploy_to_regions(stack_set_name, regions)

內容解密:

此範例程式碼展示瞭如何使用 AWS CloudFormation 和 Python SDK(Boto3)建立 StackSet 並佈署至多個區域。首先,我們定義了一個 CloudFormation 資源 MyStackSet,指定了 StackSet 的名稱、範本 URL 和相關引數。然後,我們使用 Python SDK 建立 StackSet 並在指定的區域佈署堆積疊。

最佳實踐

在使用 StackSets 時,以下是一些最佳實踐:

  • 使用引數化範本:透過引數化範本,可以根據不同區域和帳戶的需求進行自定義。
  • 監控和稽核:定期監控 StackSets 的佈署狀態,並稽核相關日誌以確保合規性。
  • 錯誤處理:設定適當的錯誤處理機制,以應對佈署失敗或其他問題。

佈署至多個帳戶

StackSets 也支援跨多個 AWS 帳戶佈署堆積疊。這對於需要在不同帳戶之間隔離資源的企業非常有用。

步驟概述

  1. 啟用信任關係:在目標帳戶和 StackSet 管理帳戶之間建立信任關係。
  2. 建立 StackSet:在管理帳戶中建立 StackSet。
  3. 選擇目標帳戶:指定要在哪些帳戶中佈署堆積疊。
  4. 佈署堆積疊:StackSet 將根據指定的範本在選定的帳戶中佈署堆積疊。

範例程式碼:佈署至多個帳戶

def deploy_to_accounts(stack_set_name, accounts, regions):
    response = cloudformation.create_stack_instances(
        StackSetName=stack_set_name,
        Accounts=accounts,
        Regions=regions
    )
    return response

# 使用範例
accounts = ['123456789012', '210987654321']
regions = ['us-east-1', 'us-west-2']

deploy_to_accounts(stack_set_name, accounts, regions)

內容解密:

此範例程式碼展示瞭如何使用 Python SDK 在多個帳戶和區域佈署 StackSet 堆積疊。透過指定目標帳戶和區域,可以實作跨帳戶的堆積疊佈署。

使用 Target Account Gates 防止多個 StackSet 佈署失敗

Target Account Gates(TAGs)是一種機制,可以防止在目標帳戶中的 StackSet 佈署失敗。透過在目標帳戶中設定適當的 gate,可以確保只有在滿足特定條件時才允許佈署。

範例程式碼:設定 Target Account Gate

def put_target_account_gate(stack_set_name, account_id, gate_status):
    response = cloudformation.put_target_account_gate(
        StackSetName=stack_set_name,
        AccountId=account_id,
        GateStatus=gate_status
    )
    return response

# 使用範例
account_id = '123456789012'
gate_status = 'ENABLED'

put_target_account_gate(stack_set_name, account_id, gate_status)

內容解密:

此範例程式碼展示瞭如何使用 Python SDK 設定目標帳戶 gate,以控制 StackSet 在目標帳戶中的佈署。透過啟用或停用 gate,可以靈活地管理佈署流程。

問題

  1. 什麼是 StackSets?它有哪些主要功能?
  2. 如何使用 StackSets 將堆積疊佈署到多個區域?
  3. 如何使用 StackSets 將堆積疊佈署到多個帳戶?
  4. 什麼是 Target Account Gates?如何使用它來防止佈署失敗?
  5. 在使用 StackSets 時,有哪些最佳實踐需要遵循?

進一步閱讀

圖表翻譯: 此圖表展示了使用 StackSets 進行跨區域和跨帳戶佈署的流程。首先,我們需要建立 StackSet 並定義相關的 CloudFormation 範本。然後,選擇目標區域或帳戶進行佈署。佈署完成後,需要進行監控和稽核,並設定適當的錯誤處理機制。

使用StackSets佈署至多個區域和帳戶

傳統的多區域和多帳戶基礎設施管理方式

到目前為止,我們的堆積疊佈署主要集中在單一AWS帳戶和區域內組態資源。但是,如果我們需要在多個區域組態相同的堆積疊,該怎麼辦?例如,我們需要在愛爾蘭、北維吉尼亞和法蘭克福組態相同的堆積疊。

通常,預設區域(例如,我們要連線的API端點)是從環境變數或本地組態檔案中選擇的。當您透過awscli呼叫任何命令時,它將連線到該特定的預設區域。

我們也可以手動將區域指定為引數。因此,如果我們想在不同的區域組態相同的堆積疊,我們必須重複相同的命令,並更改引數值,如下所示:

aws cloudformation deploy --region eu-west-1 --template-file foo.yaml
aws cloudformation deploy --region us-east-1 --template-file foo.yaml
aws cloudformation deploy --region eu-central-1 --template-file foo.yaml

但這給我們帶來了額外的複雜性。如果其中一個佈署失敗怎麼辦?如果一個堆積疊的組態時間超過30分鐘,那麼整個操作將耗時數小時!我們當然可以使用Linux工具(如parallel或xargs)平行執行,但這並不能保護我們免受堆積疊在一個區域建立失敗而在其他區域成功的情況。在這種情況下,我們會在基礎設施中引入不一致性。

內容解密:

上述程式碼展示瞭如何在不同的AWS區域佈署相同的CloudFormation堆積疊。透過指定不同的--region引數,我們可以在多個區域佈署相同的資源堆積疊。然而,這種方法需要多次執行相同的命令,並且容易出現因區域不同而導致的佈署不一致問題。

我們可能還需要將相同的堆積疊佈署到多個帳戶。我們必須在本地組態檔案中儲存多個憑證和組態檔案,並逐一指定組態檔案!您可以在這裡看到一個例子:

aws cloudformation deploy --profile dev
aws cloudformation deploy --profile test
aws cloudformation deploy --profile prod

同樣,我們遇到了與區域相同的問題。

以前,我們會使用巢狀堆積疊在單一堆積疊中宣告區域範圍內的堆積疊。巢狀堆積疊是CloudFormation的一個功能,允許範本開發人員在CloudFormation範本中將CloudFormation堆積疊指定為資源。最初的想法是為瞭解決AWS每個堆積疊資源數量限制的問題,但現在巢狀堆積疊也可以用於這種情況。更多資訊,您可以閱讀AWS的部落格文章:https://aws.amazon.com/blogs/infrastructure-and-automation/multiple-account-multiple-region-aws-cloudformation/。

介紹StackSets

2017年,CloudFormation開發團隊推出了一個名為StackSets的功能,可以解決所有這些問題。讓我們深入瞭解它。

StackSets的概念

CloudFormation堆積疊佈署的結果總是一堆積資源,分組在單個堆積疊中。我們可以將StackSet視為一組從相同範本佈署的堆積疊,具有相同或不同的引數,在單個帳戶的多個區域中,或在多個帳戶的單個區域中,甚至在多個帳戶的多個區域中!StackSets可以佈署到目標區域或帳戶(無論是在您的AWS組織中還是單獨的帳戶),如下圖所示:

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title CloudFormation StackSets 多區域多帳戶佈署

package "AWS 雲端架構" {
    package "網路層" {
        component [VPC] as vpc
        component [Subnet] as subnet
        component [Security Group] as sg
        component [Route Table] as rt
    }

    package "運算層" {
        component [EC2] as ec2
        component [Lambda] as lambda
        component [ECS/EKS] as container
    }

    package "儲存層" {
        database [RDS] as rds
        database [DynamoDB] as dynamo
        storage [S3] as s3
    }

    package "服務層" {
        component [API Gateway] as apigw
        component [ALB/NLB] as lb
        queue [SQS] as sqs
    }
}

apigw --> lambda
apigw --> lb
lb --> ec2
lb --> container
lambda --> dynamo
lambda --> s3
ec2 --> rds
container --> rds
vpc --> subnet
subnet --> sg
sg --> rt

@enduml

圖表翻譯: 上圖展示了StackSet的架構,一個StackSet可以包含多個堆積疊例項(Stack Instance),這些例項分佈在不同的區域和帳戶中。

正如您在前面的圖表中看到的那樣,每個StackSet由一個或多個堆積疊組成,這些堆積疊是從相同的範本組態的。這些堆積疊被稱為堆積疊例項,並分佈在不同的帳戶和區域中。這是我們需要了解的第一個概念。

另一個概念是管理員和目標帳戶。管理員帳戶是管理StackSets的帳戶。每當我們想要建立或更新StackSets時,我們都需要使用管理員帳戶。這個帳戶必須被授予在其他帳戶中建立堆積疊的許可權(由身份和存取管理(IAM)處理)。正在建立堆積疊的帳戶是目標帳戶。

如果您想使用StackSets在不同的區域組態堆積疊,但只在單個帳戶中,那麼您的管理員和目標帳戶將是相同的。

如果其中一個堆積疊例項的建立失敗,那麼這不會影響其他堆積疊例項。

讓我們看一個簡單的例子:您佈署了一個具有資源的堆積疊,這些資源來自目前在AWS某些區域尚不支援的服務。在那些區域,堆積疊建立顯然會失敗。CloudFormation在設計上將開始回復更改。我們可能會認為所有其他堆積疊例項也會回復,但事實並非如此。只有受影響的堆積疊例項將被還原,而其他例項將被佈署且沒有問題。這種行為是由容錯能力維持的,我們將在下一節中介紹。

重要注意事項

如果我們刪除一個StackSet,那麼所有堆積疊例項都應該被刪除。為了保留某些堆積疊例項,我們需要從StackSet中刪除它們,並選擇保留它們的選項。這將從StackSet中刪除堆積疊例項,但堆積疊本身將保留。

這聽起來很複雜,並增加了意外刪除的風險。為了防止這種情況發生,AWS不允許您刪除StackSet。首先,您必須刪除堆積疊例項,當StackSet為空時,才能將其刪除。

關於StackSets,還有一個重要的事情需要了解,即所謂的StackSet操作選項。

雖然StackSet操作術語相當簡單(操作是建立、更新和刪除),但選項可能會很棘手。

StackSets佈署根據預設的滾動更新。要組態佈署行為,我們可以設定最大平行帳戶數、容錯能力和保留堆積疊選項,如下所述:

  • 最大平行帳戶數定義了每個帳戶的平行佈署數量。也就是說,如果我們在一個StackSet中佈署五個堆積疊例項,那麼我們可以定義平行佈署的數量或百分比。如果我們將此值設定為2(作為數字)或40(作為百分比),那麼佈署將在兩個帳戶中同時進行。增加這個數字將提高堆積疊組態的速度,但如果範本中有錯誤可能導致失敗,那麼它將影響更多的目標區域和帳戶。
  • 容錯能力是一種選項,定義了我們希望如何處理每個佈署的失敗。這僅在每個區域的基礎上工作,並定義了我們可以忽略的堆積疊佈署失敗次數。

內容解密:

上述StackSets的操作選項對於管理多區域和多帳戶的堆積疊佈署至關重要。透過調整最大平行帳戶數和容錯能力,我們可以控制佈署的速度和可靠性。例如,在多個區域佈署時,可以根據需要調整這些引數以確保佈署的順利進行。

進一步探討

在實際應用中,StackSets的佈署策略需要根據具體的業務需求和基礎設施架構進行調整。例如,在全球範圍內佈署應用程式時,可能需要在多個區域和帳戶中組態資源,以確保低延遲和高用性。透過StackSets,我們可以輕鬆地管理和維護這些資源,確保我們的應用程式始終可用並且效能最佳。

此外,StackSets還提供了豐富的錯誤處理和回復機制,確保在佈署過程中出現問題時,可以快速還原到之前的狀態,減少業務中斷的風險。這些功能使得StackSets成為管理複雜基礎設施的理想選擇。

隨著雲端計算技術的不斷發展,StackSets將繼續演進,提供更多功能和改進,以滿足不斷變化的業務需求。例如,未來可能會看到更多與其他AWS服務的整合,以及對更多佈署策略的支援。這將進一步簡化多區域和多帳戶環境中的資源管理和佈署過程。

總之,StackSets是AWS CloudFormation的一個強大功能,為管理和佈署複雜的基礎設施資源提供了靈活性和可靠性。透過深入瞭解和使用StackSets,我們可以更好地管理和最佳化我們的雲資源,滿足業務需求並推動創新。