在現代雲端維運實務中,基礎設施即程式碼(IaC)是確保環境一致性與可擴展性的核心原則。本篇技術探討將深入解析一套完整的自動化工作流程,從映像檔的標準化構建到宣告式佈建,再到最終的組態管理。透過整合 Packer、Terraform 及 Ansible 於 Azure Pipelines 之中,企業能大幅提升部署效率與可靠性,並實踐 DevOps 協同合作模式,加速價值交付週期。
Azure Pipelines 整合 Packer 進行映像自動構建
本節將延續上一部分,詳細說明如何在 Azure Pipelines 中配置和執行 Packer 管道,以自動化 Azure 虛擬機器 (VM) 映像的構建過程。
配置 Packer 管道以使用 Azure 服務主體
為了讓 Packer 在 Azure Pipelines 中能夠訪問和操作 Azure 資源,需要配置 Azure 服務主體 (Service Principal) 的憑證資訊。這些憑證將作為環境變數傳遞給 Packer。
定義環境變數: 在 YAML 管道文件中,您需要定義與 Azure 服務主體相關的環境變數。這些變數必須遵循
PKR_VAR_<variable name>的格式,以便 Packer 能夠識別並使用它們。例如:PKR_VAR_clientid: Azure 服務主體的客戶端 ID。PKR_VAR_clientsecret: Azure 服務主體的客戶端密碼。PKR_VAR_subscriptionid: Azure 訂閱 ID。PKR_VAR_tenantid: Azure 租用戶 ID。
這些變數的值通常從 Azure Pipelines 的變數組中獲取,以確保安全性,避免將敏感資訊硬編碼在管道文件中。
提交與推送管道文件: 將包含這些環境變數配置的 YAML 管道文件提交並推送到您的 Git 倉庫(例如 GitHub、Azure Repos 或 Bitbucket)。
創建與運行 Azure Pipeline:
- 在 Azure Pipelines 中,創建一個新的管道。
- 選擇包含 Packer 範本和 YAML 管道文件的 Git 倉庫。
- 選擇「Use an existing YAML pipeline file」選項,並指定文件的路徑。
- 在管道的編輯模式下,為之前定義的 Azure 服務主體環境變數(
PKR_VAR_clientid、PKR_VAR_clientsecret等)添加相應的變數值。這些值應從 Azure 服務主體的配置中獲取,並建議使用 Azure Pipelines 的 Secret 變數功能來保護敏感資訊。 - 保存並運行管道。
監控執行與驗證結果: 管道運行後,您可以查看執行日誌,確認 Packer 命令是否成功執行。最終,在 Azure 門戶的指定資源群組中,您應該能夠看到由 Packer 自動構建的 VM 映像。
執行 Terraform 和 Ansible 在 Azure Pipelines 中
在成功構建 Packer 映像後,下一步是創建一個新的 CI/CD 管道,該管道將利用 Packer 生成的映像來佈建 Azure 虛擬機器,並使用 Ansible 進行進一步的配置。
Terraform 配置: 本節將使用的 Terraform 代碼會執行以下操作:
- 創建一個新的 Azure 資源群組。
- 創建一個虛擬網絡及其子網。
- 基於 Packer 生成的映像,創建一個 Linux 虛擬機器,並打上
role: webserver的標籤。
Ansible 配置: Terraform 佈建完虛擬機器後,Ansible 將被調用,用於在該虛擬機器上安裝 Nginx 伺服器。
視覺化 Packer 管道變數配置與執行
以下圖示展示了如何在 Azure Pipelines 中配置 Packer 管道的環境變數,以及管道的執行與結果驗證。
@startuml
!define DISABLE_LINK
!define PLANTUML_FORMAT svg
!theme _none_
skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 16
skinparam minClassWidth 100
start
component "Azure Pipelines Packer Variable Integration" {
node "YAML Pipeline Definition" {
:Define Packer script steps;
:Reference environment variables (e.g., PKR_VAR_...);
}
node "Azure Service Principal Credentials" {
:Client ID;
:Client Secret;
:Subscription ID;
:Tenant ID;
}
node "Azure Pipelines Variables" {
:Store credentials securely;
:Map to PKR_VAR_ format;
}
node "Pipeline Execution" {
:Run pipeline;
:Packer commands execute with provided variables;
}
node "Result Verification" {
:Check execution logs;
:Verify VM image in Azure Portal;
}
}
YAML Pipeline Definition --> Azure Pipelines Variables : Reference Variables
Azure Service Principal Credentials --> Azure Pipelines Variables : Provide Sensitive Data
Pipeline Execution --> Result Verification : Confirm Success
Azure Pipelines Variables --> Pipeline Execution : Inject Credentials
stop
@enduml看圖說話:
此圖示展示了 Azure Pipelines 如何整合 Packer,並通過配置環境變數來實現自動化映像構建。首先,「YAML Pipeline Definition」部分定義了 Packer 的執行腳本,並引用了環境變數。
「Azure Service Principal Credentials」代表了執行操作所需的 Azure 認證資訊。這些敏感資訊被安全地存儲在「Azure Pipelines Variables」中,並映射到 Packer 所需的 PKR_VAR_ 格式。
在「Pipeline Execution」階段,管道運行時,這些變數會被注入,使得 Packer 命令能夠成功執行。最後,「Result Verification」階段,通過檢查執行日誌和在 Azure 門戶中驗證生成的 VM 映像,確認整個過程的成功。
Azure Pipelines 整合 Terraform 與 Ansible 自動化基礎設施部署
本章將聚焦於如何利用 Azure Pipelines,結合 Terraform 和 Ansible,實現基礎設施的自動化部署與配置。這個流程將利用先前通過 Packer 構建的自定義映像,創建虛擬機器,並進行必要的軟體安裝。
Terraform 部署流程
Terraform 在此場景中負責基礎設施的佈建。Azure Pipelines 將執行 Terraform 的工作流程,包括初始化、規劃和應用。
Terraform 初始化 (
terraform init):- 腳本:
script: terraform init --backend-config backend.tfvars - 顯示名稱:
Terraform init - 工作目錄:
$(Build.SourcesDirectory)/CHAP08/terraform - 環境變數:
ARM_CLIENT_ID: $(AZURE_CLIENT_ID)ARM_CLIENT_SECRET: $(AZURE_SECRET)ARM_SUBSCRIPTION_ID: $(AZURE_SUBSCRIPTION_ID)ARM_TENANT_ID: $(AZURE_TENANT)
- 說明: 此步驟初始化 Terraform 工作區,下載必要的提供者插件,並配置遠端後端(
backend.tfvars)來存儲 Terraform 狀態。環境變數(以ARM_開頭)用於 Terraform 驗證與 Azure 的連接。這些變數的值將從 Azure Pipelines 的變數組中獲取。
- 腳本:
Terraform 規劃 (
terraform plan):- 腳本:
script: terraform plan - 顯示名稱:
Terraform plan - 工作目錄:
$(Build.SourcesDirectory)/CHAP08/terraform - 環境變數:
ARM_CLIENT_ID: $(AZURE_CLIENT_ID)ARM_CLIENT_SECRET: $(AZURE_SECRET)ARM_SUBSCRIPTION_ID: $(AZURE_SUBSCRIPTION_ID)ARM_TENANT_ID: $(AZURE_TENANT)
- 說明: 此步驟生成 Terraform 執行計劃,顯示將要對基礎設施進行的變更。這是一個預覽步驟,用於確認即將發生的操作。
- 腳本:
Ansible 配置流程
在 Terraform 完成虛擬機器的佈建後,Ansible 將接管,負責配置虛擬機器上的軟體。
Ansible 劇本與動態清單:
- Ansible 劇本 (
playbookdemo.yml): 包含在CHAP08/ansible/目錄下,用於在 Linux 虛擬機器上安裝 Nginx 伺服器。 - 動態清單 (
inv.azure_rm.yml): 使用 Azure 的動態清單功能,根據指定的 Azure 資源群組和 VM 標籤自動發現目標虛擬機器,無需手動維護主機列表。
- Ansible 劇本 (
在 Azure Pipelines 中執行 Ansible: 在 YAML 管道文件中,將添加執行 Ansible 的步驟。這通常涉及:
- 指定 Ansible 劇本的路徑。
- 指定動態清單的配置。
- 配置連接到目標虛擬機器的憑證或 SSH 金鑰。
- 執行 Ansible 命令。
Azure Pipelines YAML 管道示例
以下是一個簡化的 azure-pipeline.yaml 文件結構,展示了 Terraform 和 Ansible 的執行步驟:
# ... (前置的 Packer 相關配置,若有)
jobs:
- job: DeployInfrastructure
displayName: 'Deploy Infrastructure with Terraform and Ansible'
pool:
vmImage: 'ubuntu-latest' # 或其他適合的代理機鏡像
steps:
- script: terraform init --backend-config backend.tfvars
displayName: 'Terraform init'
workingDirectory: '$(Build.SourcesDirectory)/CHAP08/terraform'
env:
ARM_CLIENT_ID: $(AZURE_CLIENT_ID)
ARM_CLIENT_SECRET: $(AZURE_SECRET)
ARM_SUBSCRIPTION_ID: $(AZURE_SUBSCRIPTION_ID)
ARM_TENANT_ID: $(AZURE_TENANT)
# 可能需要 ARM_ACCESS_KEY 或其他認證方式
- script: terraform plan
displayName: 'Terraform plan'
workingDirectory: '$(Build.SourcesDirectory)/CHAP08/terraform'
env:
ARM_CLIENT_ID: $(AZURE_CLIENT_ID)
ARM_CLIENT_SECRET: $(AZURE_SECRET)
ARM_SUBSCRIPTION_ID: $(AZURE_SUBSCRIPTION_ID)
ARM_TENANT_ID: $(AZURE_TENANT)
- script: terraform apply -auto-approve
displayName: 'Terraform apply'
workingDirectory: '$(Build.SourcesDirectory)/CHAP08/terraform'
env:
ARM_CLIENT_ID: $(AZURE_CLIENT_ID)
ARM_CLIENT_SECRET: $(AZURE_SECRET)
ARM_SUBSCRIPTION_ID: $(AZURE_SUBSCRIPTION_ID)
ARM_TENANT_ID: $(AZURE_TENANT)
# 在 Terraform apply 完成後,添加 Ansible 執行步驟
- task: Ansible@1 # 使用 Azure Pipelines 的 Ansible 任務
displayName: 'Run Ansible Playbook'
inputs:
azureSubscription: '<Your Azure Service Connection Name>' # Azure 服務連接名稱
ScriptType: 'playbook'
PlayBookPath: '$(Build.SourcesDirectory)/CHAP08/ansible/playbookdemo.yml'
InventoryPath: '$(Build.SourcesDirectory)/CHAP08/ansible/inv.azure_rm.yml'
# 可能需要配置 SSH 憑證等連接資訊
注意: 上述 Ansible 任務的配置細節(如 <Your Azure Service Connection Name> 和 SSH 憑證)需要根據您的 Azure DevOps 環境和安全策略進行調整。
視覺化 Terraform 和 Ansible 管道流程
以下圖示展示了 Terraform 和 Ansible 在 Azure Pipelines 中的協同工作流程。
@startuml
!define DISABLE_LINK
!define PLANTUML_FORMAT svg
!theme _none_
skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 16
skinparam minClassWidth 100
start
component "IaC Deployment Pipeline" {
node "Terraform Initialization" {
:Execute 'terraform init';
:Configure backend and providers;
}
node "Terraform Planning" {
:Execute 'terraform plan';
:Generate execution plan;
}
node "Terraform Application" {
:Execute 'terraform apply -auto-approve';
:Provision Azure resources (VM, Network);
}
node "Ansible Inventory" {
:Use dynamic inventory (inv.azure_rm.yml);
:Discover provisioned VM hosts;
}
node "Ansible Configuration" {
:Execute 'ansible-playbook playbookdemo.yml';
:Install Nginx on VM;
}
node "Final Infrastructure State" {
:VM with Nginx running;
}
}
Terraform Initialization --> Terraform Planning : Prepare for Deployment
Terraform Planning --> Terraform Application : Confirm and Execute
Terraform Application --> Ansible Inventory : Identify Target Hosts
Ansible Inventory --> Ansible Configuration : Target Hosts for Configuration
Ansible Configuration --> Final Infrastructure State : Deployed and Configured
stop
@enduml看圖說話:
此圖示描繪了在 Azure Pipelines 中,Terraform 和 Ansible 如何協同工作以實現基礎設施的自動化部署。流程始於「Terraform Initialization」,執行 terraform init 來準備工作環境。
接著,「Terraform Planning」階段運行 terraform plan,生成一個預覽變更的執行計劃。隨後,「Terraform Application」階段執行 terraform apply,實際在 Azure 中創建虛擬機器和網絡等資源。
Terraform 佈建完成後,「Ansible Inventory」階段利用動態清單自動發現新創建的虛擬機器。最後,「Ansible Configuration」階段執行 Ansible 劇本,在這些虛擬機器上安裝 Nginx,最終達成「Final Infrastructure State」,即一個部署完成並配置好 Nginx 的虛擬機器。
結論
縱觀現代雲端維運的多元挑戰,將 Packer、Terraform 與 Ansible 整合於 Azure Pipelines 的自動化流程,不僅是技術堆疊的組合,更是一種系統性的工程思維體現。此整合架構的核心價值在於其協同效應:Packer 預先烘焙的標準化映像,從源頭消除了環境不一致的風險,為 Terraform 的基礎設施佈建提供了穩定基石;而 Terraform 透過代碼精準定義資源後,Ansible 的動態清單無縫接軌,實現了從無到有的全自動配置。這種分層負責的模式,有效突破了傳統手動部署的效率瓶頸與人為錯誤,將「基礎設施即代碼」的理念從理論轉化為可高度重複、可稽核的日常實踐。
展望未來,此類整合管道將進一步朝向 GitOps 模式演化,讓 Git 倉儲成為驅動基礎設施生命週期的唯一真相來源。隨著實踐社群的成熟,圍繞此核心流程的監控、安全掃描與成本優化工具鏈將更趨完整,形成一個自我強化的維運生態系統。
玄貓認為,對於追求高部署頻率與系統韌性的技術團隊,採納此一分層自動化架構,不僅是提升效率的手段,更是奠定長期技術競爭力的關鍵策略投資。