iT邦幫忙

2026 iThome 鐵人賽

DAY 24
0
IT Operation

AWS 架構為什麼這樣選?30 天拆解服務選型與設計取捨系列 第 24 篇

Day 24|環境越來越多,怎麼避免手動設定失控?

  • 分享至 

  • xImage
  •  

上一篇比較了 SQS、SNS 與 EventBridge,決定哪些工作需要排隊、通知或依事件內容分流。

當架構裡開始出現 VPC、ECS、資料庫、Queue 與 IAM Role 等等的服務,接下來可能會遇到另一個問題:開發環境設定好了,測試與正式環境要再手動建立一次嗎?

只靠 Console 操作,第一套環境基本上不難建立,麻煩的是後續不同環境的設定逐漸不一致、修改原因沒有留下紀錄,需要重建時才發現操作文件漏了步驟等等。

這篇會先介紹 Infrastructure as Code(IaC,基礎設施即程式碼),再用同一份 CloudFormation 範本建立兩個 Stack,模擬開發與測試環境,觀察如何管理設定差異,以及如何在更新前確認影響範圍。


IaC:把環境設定寫成可以執行的定義

使用 IaC 時,我們會將資源與設定寫進檔案,再交給工具建立或更新,例如描述「需要一個 SQS Queue,Visibility Timeout 設成 60 秒」,工具就會依設定處理資源。

將檔案放進 Git 後,團隊可以比較版本、審查修改,並留下變更原因,同一份定義也能重複部署,減少每次手動建立時的遺漏,不過使用同一份範本,不代表所有環境的設定都必須相同。

正式環境可能需要更多運算資源、更長的資料保留時間,這類設定差異可以透過參數管理,讓不同環境共用資源定義;若環境的架構差異較大,則需要進一步規劃範本的拆分與重用方式。


CloudFormation、CDK 與 Terraform 怎麼選?

先釐清兩個容易混淆的服務 CloudFormation 與 CDK。

CloudFormation 讓我們直接使用 YAML/JSON 描述 AWS 資源,再由 CloudFormation 服務負責部署。

AWS CDK 則使用 TypeScript、Python 等程式語言定義資源,一般部署流程會先產生 CloudFormation 範本,再交給 CloudFormation 執行。

例如建立 SQS Queue,直接撰寫 CloudFormation 時,資源定義會是:

OrderEmailQueue:
  Type: AWS::SQS::Queue
  Properties:
    VisibilityTimeout: 60

CDK 的 TypeScript 程式碼片段則可以寫成:

new sqs.Queue(this, 'OrderEmailQueue', {
  visibilityTimeout: Duration.seconds(60),
});

這是放在 CDK Stack 裡的程式碼片段,完整程式還需要匯入對應套件。

sqs.Queue 用來定義佇列,this 指向目前的 Stack,Duration.seconds(60) 則代表 60 秒。

兩者可以建立相同資源,差別在於如何撰寫與組合設定,當每個 Queue 都需要搭配死信佇列、告警與固定標籤時,CDK 可以將整組設定封裝成共用元件,讓團隊重複使用。

再加入 Terraform,可以從以下幾個方向比較:

工具 撰寫與部署方式 部署狀態管理 適合優先評估的情況
CloudFormation YAML/JSON 直接交由 AWS 部署 AWS 管理 Stack 狀態 主要使用 AWS,希望直接檢視資源設定
AWS CDK 程式碼產生 CloudFormation 範本後部署 一般部署由 CloudFormation 管理 團隊熟悉程式開發,需要組合與重用資源元件
Terraform 使用 HCL,透過 Provider 操作資源 團隊需安排 State 的儲存、權限與鎖定,也可採用託管方案 已有 Terraform 工具鏈,或需要整合不同平台

Terraform 的 State(狀態) 會記錄設定與實際資源的對應關係;Provider 則負責與 AWS 等平台的 API 互動。

CloudFormation 的 Stack 狀態由 AWS 管理,但團隊仍需負責部署權限與變更審查。

選工具時,也要看團隊的維護經驗,若已有成熟 Terraform Module 與部署流程,就不需要只因為新專案在 AWS 上而換工具。

這次選 CloudFormation,是因為只需要一個簡單資源,能直接從 Console 上傳範本,集中觀察參數與變更管理 ,CDK 的元件封裝與 Terraform 的工具鏈設定,這次都先不展開。


實作階段:同一份範本,建立兩個 Stack

這次在同一個 AWS 帳號、東京 Region(ap-northeast-1)中,建立兩個獨立的 Stack,分別模擬開發與測試環境:

項目 開發環境 測試環境
Stack 名稱 day24-dev day24-test
範本 同一份 day24-sqs.yaml 同一份 day24-sqs.yaml
初始 Visibility Timeout 60 秒 90 秒
更新後 120 秒 維持 90 秒

Stack(堆疊) 是 CloudFormation 管理的一組資源,本次每個 Stack 都只建立自己的 SQS Queue,用來示範設定管理,並非完整的應用程式環境。

上述秒數只用來辨識設定差異,不是不同環境的建議值。

全程使用本機文字編輯器與 AWS Console,不需要 EC2 或 CloudShell,登入身分須具備 CloudFormation Stack、Change Set 與 SQS 資源的操作權限,Console 上傳範本也需要相應的 S3 權限。

一、準備帶有參數的範本

在電腦上建立 day24-sqs.yaml,貼入以下內容並儲存:

AWSTemplateFormatVersion: '2010-09-09'
Description: SQS queue for the Day 24 multi-environment demo

Parameters:
  VisibilityTimeoutSeconds:
    Type: Number
    Default: 60
    MinValue: 0
    MaxValue: 43200
    Description: Queue visibility timeout in seconds

Resources:
  OrderEmailQueue:
    Type: AWS::SQS::Queue
    Properties:
      VisibilityTimeout: !Ref VisibilityTimeoutSeconds
      SqsManagedSseEnabled: true

Outputs:
  QueueUrl:
    Description: URL of the queue created by this stack
    Value: !Ref OrderEmailQueue

這份範本分成三個部分:

區塊 用途
Parameters 部署時可以輸入的設定,本次是 Visibility Timeout
Resources 要建立的資源,本次是一個 SQS Queue
Outputs 部署後顯示的資訊,本次是 Queue URL

!Ref VisibilityTimeoutSeconds 會取得輸入的參數值,!Ref OrderEmailQueue 則會取得這個 Queue 的 URL。

OrderEmailQueue 是範本內的 Logical ID(邏輯識別碼),這裡沒有指定 QueueName,CloudFormation 會自動產生實際名稱,因此兩個 Stack 可以使用相同範本,各自建立不同的 Queue。

SqsManagedSseEnabled: true 則明確指定使用 SQS 管理的伺服器端加密。

二、用同一份範本建立兩個 Stack

進入 CloudFormation → Stacks → Create stack → With new resources (standard),確認 Region 為東京。

  1. 選擇使用既有範本,再選 Upload a template file。
  2. 上傳 day24-sqs.yaml,點選 Next。
  3. Stack name 輸入 day24-dev。
  4. Parameters 中的 VisibilityTimeoutSeconds 輸入 60。
  5. 其餘選項維持預設,完成檢查後點選 Submit。

若公司要求使用指定的 CloudFormation service role,請依既有規範選取;未指定時,CloudFormation 會使用依目前登入身分權限取得的暫時憑證操作資源。

https://ithelp.ithome.com.tw/upload/images/20261008/20183052PZrzOC8Cmq.png

上傳後,CloudFormation 會將範本存放到帳號內的 S3 Bucket,並顯示 S3 URL,建議先記下這個 URL,方便實作結束後找到並清理範本檔案,因為刪除 Stack 不會一併刪除這個檔案。

https://ithelp.ithome.com.tw/upload/images/20261008/201830525h0u7Nr2eS.png

等待 Stack 狀態變成 CREATE_COMPLETE,如果失敗的話請查看 Events → Status reason,確認原因。

接著重複相同步驟,上傳同一份檔案,但改成:

  • Stack name:day24-test
  • VisibilityTimeoutSeconds:90

兩個 Stack 完成後,各自開啟 Resources 頁籤,找到 OrderEmailQueue 對應的 Physical ID(實體識別碼),再前往同一 Region 的 SQS Console 查看資源。

預期會看到兩個不同的 Queue:

所屬 Stack SQS Visibility Timeout
day24-dev 60 秒,或顯示為 1 分鐘
day24-test 90 秒,或顯示為 1 分 30 秒

也可以在各 Stack 的 Outputs 頁籤取得 Queue URL,確認兩者對應不同資源。

https://ithelp.ithome.com.tw/upload/images/20261008/20183052o6LTQ6iC8G.png

https://ithelp.ithome.com.tw/upload/images/20261008/201830526KxzBLdvo4.png

到這裡可以發現共同的資源定義只有一份,環境差異由建立 Stack 時輸入的參數決定。

三、只修改開發環境,先檢查 Change Set

假設開發環境的消費者需要更長時間處理訊息,為了減少工作尚未完成、訊息就重新變成可見狀態的情況,這次將 Visibility Timeout 調整成 120 秒。

Visibility Timeout 不會限制程式執行時間,也不能完全避免 Standard Queue 的重複傳遞;消費者仍需具備冪等性。

回到 CloudFormation → day24-dev:

  1. 選擇 Stack actions → Create a change set。
  2. 選擇 Use existing template,因為這次只修改參數。
  3. Change Set 名稱填入 increase-visibility-timeout。
  4. 將 VisibilityTimeoutSeconds 改成 120;若勾選了 Use existing value,先取消。
  5. 保留其他設定,檢查後提交。

Change Set(變更集) 用來預覽這次部署預計新增、修改或刪除哪些資源,建立完成後先不要執行,查看 Changes。

本次預期結果如下,請以實際產生的 Change Set 核對:

檢查項目 預期結果
資源 OrderEmailQueue
Action Modify
Replacement False,不需要替換 Queue
修改的屬性 VisibilityTimeout,由參數值 60 調整為 120

更新前要一起確認受影響的資源、修改的屬性與 Replacement 判定,若出現預期以外的新增、刪除或替換,先釐清原因,再執行 Change Set。

https://ithelp.ithome.com.tw/upload/images/20261008/20183052v3p4QdsH6t.png

VisibilityTimeout 支援原地更新,因此這次預期不需要重建 Queue。

此時實際 Queue 應維持 60 秒,Change Set 建立完成,只代表預覽完成,尚未套用修改。

四、執行更新、比較結果,再清理資源

確認內容正確後,選擇 Execute change set,依畫面確認執行。

等待 day24-dev 的狀態變成 UPDATE_COMPLETE,再回到 SQS 重新整理。若仍看到舊設定,稍候再確認。

預期結果如下:

檢查項目 day24-dev day24-test
Visibility Timeout 120 秒 維持 90 秒
Queue URL 與更新前相同 與更新前相同
是否被本次更新影響 是 否

https://ithelp.ithome.com.tw/upload/images/20261008/201830529VX7NtSDjn.png

https://ithelp.ithome.com.tw/upload/images/20261008/20183052jqPS8kCb6P.png

這次只更新 day24-dev,所以即使兩個 Stack 使用同一份範本,CloudFormation 也不會自動把修改同步到另一個 Stack,如果同一項修改需要套用到多個環境,仍要安排各環境的部署順序與審核流程。

另外這次透過 Console 修改參數,本機 YAML 並沒有改變,Git 也不會自動記錄這次參數調整。

CloudFormation 中可以查看 Stack 目前的參數與部署事件,但這和程式碼版本管理是兩件事,正式使用時,應將各環境的非機密參數與範本一併納入版本管理,並讓部署流程讀取這些設定,才能審查與追蹤完整的環境差異。

測試完成後,到 CloudFormation 分別刪除 day24-dev 與 day24-test,並確認兩個 Queue 都已移除,本次沒有設定保留規則,因此刪除 Stack 時會刪除 Queue,裡面的訊息也會一併刪除。

最後可依先前記下的 S3 URL,刪除本次上傳的範本檔案。


有了範本,還需要管理什麼?

部署前仍要確認 AWS 帳號、Region 與 Stack,避免將正確的設定套用到錯誤的環境。

如果有人直接到 Console 修改資源,實際設定就可能與範本產生 Drift(漂移),CloudFormation 能偵測支援範圍內的差異,團隊仍需判斷要將修改納入程式碼,或恢復原本設定。

另外,範本能重新建立資料庫或 Queue,不等於能還原原本的資料,要恢復完整服務,還需要準備外部相依設定、機密取得方式,以及資料備份與還原流程。


下一篇

基礎設施可以透過程式碼部署之後,接下來要處理的是應用程式的新版本。

下一篇會比較滾動部署、藍綠部署與漸進式發布,看看如何控制上線影響,以及出問題時該怎麼退回。

參考資料


上一篇
Day 23|每個請求都要同步完成嗎?SQS、SNS 與 EventBridge 怎麼選?
系列文
AWS 架構為什麼這樣選?30 天拆解服務選型與設計取捨 共 24 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言