在現代雲端應用開發中,快速且可靠的交付是維持競爭力的關鍵。Azure Container Instances (ACI) 提供無伺服器容器平台,讓開發團隊無需管理底層架構即可運行 Docker 容器,大幅簡化部署。然而,手動管理雲端資源效率低落且易出錯。為此,導入基礎設施即程式碼 (IaC) 工具 Terraform,能以程式碼定義並標準化 ACI 實例的配置。本文將深入探討如何將 Terraform 的聲明式配置與 Azure Pipelines 的 CI/CD 自動化能力結合,建構一個從程式碼提交到容器部署的完整自動化管道,確保部署過程的一致性、可追溯性與高效率。

將 Docker 映像部署至 Azure Container Instances (ACI) 並整合 CI/CD

本節將探討如何利用 Docker 映像,透過持續整合 (CI) 與持續部署 (CD) 的管道,將應用程式自動化部署到 Azure Container Instances (ACI)。ACI 是一個由 Azure 管理的服務,能夠讓開發者無需管理底層基礎設施,即可快速運行容器化應用。我們將結合 Terraform 進行基礎設施即程式碼 (IaC) 的管理,並以 Azure Pipelines 作為 CI/CD 管道的實現工具。

ACI 簡介與 Terraform 整合

Azure Container Instances (ACI) 提供了一種無需管理虛擬機器或容器編排平台的簡單方式來運行 Docker 容器。它非常適合用於簡單的應用程式、批次處理任務或作為 CI/CD 流程中的部署目標。

Terraform 是一種熱門的基礎設施即程式碼 (IaC) 工具,能夠以聲明式的方式定義和管理雲端資源。我們將使用 Terraform 來配置 Azure 資源組和 ACI 實例,並將其與我們之前構建的 Docker 映像進行整合。

撰寫 Terraform 代碼以配置 ACI

為了使用 Terraform 創建 ACI 資源,我們需要在一個新的目錄(例如 terraform-aci)下創建一個 Terraform 配置文件,通常命名為 main.tf

main.tf 文件將包含創建資源組和 ACI 實例的 Terraform 代碼。我們將使用 azurerm_container_group 這個 Terraform 資源對象來定義 ACI。

  1. 定義資源組: 首先,聲明一個 Azure 資源組。

    resource "azurerm_resource_group" "acidemobook" {
      name     = "demoBook"
      location = "westus2"
    }
    

    這段代碼定義了一個名為 demoBook 的資源組,位於 westus2 區域。

  2. 聲明變數: 為了使 Terraform 配置更具彈性,我們將聲明一些變數,例如映像的版本和 Docker Hub 用戶名。

    variable "imageversion" {
      description = "Tag of the image to deploy"
      type        = string
    }
    
    variable "dockerhub-username" {
      description = "Your Docker Hub username"
      type        = string
    }
    

    這些變數可以在 Terraform 執行時提供,例如通過命令行參數或變量文件,從而動態地指定要部署的 Docker 映像。

  3. 配置 ACI 容器組: 接下來,我們將定義 azurerm_container_group 資源,用於創建 ACI 實例。這包括指定容器的映像、端口、CPU 和記憶體需求等。

    resource "azurerm_container_group" "appcontainer" {
      name                = "my-app-container-group"
      location            = azurerm_resource_group.acidemobook.location
      resource_group_name = azurerm_resource_group.acidemobook.name
    
      os_type             = "Linux"
      ip_address {
        type  = "Public"
        ports {
          port     = 80
          protocol = "TCP"
        }
      }
    
      container {
        name  = "my-app-container"
        image = "${var.dockerhub-username}/demobook:${var.imageversion}" # 使用變數構建映像名稱
        cpu   = "0.5"
        memory = "1.0" # GB
    
        ports {
          port = 80
        }
      }
    
      # 根據需要配置 DNS 標籤等
      dns_name_label = "my-app-demo-${random_string.suffix.result}"
    }
    
    # 生成一個隨機字符串作為 DNS 名稱的一部分,確保唯一性
    resource "random_string" "suffix" {
      length  = 8
      special = false
      upper   = false
    }
    
    • image: 此處使用 Terraform 變數 var.dockerhub-usernamevar.imageversion 來動態構建完整的 Docker 映像名稱,例如 yourusername/demobook:v1
    • ip_address: 配置容器的公共 IP 地址和暴露的端口(80)。
    • dns_name_label: 為 ACI 實例生成一個唯一的 DNS 名稱,方便訪問。

視覺化 Terraform 配置 ACI 的架構

以下圖示展示了 Terraform 如何配置 Azure 資源組和 ACI 實例。

@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 minClassَWidth 100

title Terraform Configuration for Azure ACI

component "Terraform Configuration (main.tf)" {
  artifact "azurerm_resource_group resource" as RG_RESOURCE
  artifact "azurerm_container_group resource" as ACG_RESOURCE
  artifact "Variables (imageversion, dockerhub-username)" as VARIABLES
  artifact "random_string resource" as RANDOM_STR
}

component "Azure Cloud Infrastructure" {
  artifact "Resource Group (demoBook)" as RG_AZURE
  artifact "Azure Container Instance (ACI)" as ACI_AZURE
  artifact "Docker Image\n(e.g., yourusername/demobook:v1)" as DOCKER_IMG
}

RG_RESOURCE --> RG_AZURE : Provisions
VARIABLES --> ACG_RESOURCE : Provides Input (Image Name, Version)
RANDOM_STR --> ACG_RESOURCE : Provides Input (DNS Suffix)
ACG_RESOURCE --> ACI_AZURE : Provisions ACI Instance
ACG_RESOURCE --> DOCKER_IMG : Specifies Image to Deploy

RG_AZURE --> ACI_AZURE : Associates ACI with RG

stop

@enduml

看圖說話:

此圖示展示了 Terraform 配置如何與 Azure 雲端基礎設施互動。在「Terraform Configuration (main.tf)」中,我們定義了幾個關鍵資源。azurerm_resource_group 資源負責在 Azure 中創建一個「Resource Group (demoBook)」。

azurerm_container_group 資源是核心,它利用了「Variables」中提供的映像名稱和版本信息,以及「random_string」資源生成的隨機後綴,來配置將要創建的「Azure Container Instance (ACI)」。Terraform 會將這些配置信息轉換為 API 調用,最終在 Azure 中實際創建一個 ACI 實例。

這個 ACI 實例將被指定部署一個特定的「Docker Image」(例如,yourusername/demobook:v1)。同時,ACI 實例會被關聯到之前創建的「Resource Group」,確保資源的組織和管理。 Terraform 的聲明式語法使得定義這些依賴關係和配置變得直觀且易於維護。

Terraform 部署配置與 CI/CD 管道整合

本節將延續前述內容,深入探討 Terraform 配置的細節,特別是如何將 Docker 映像資訊動態整合到 ACI 的部署中。隨後,我們將著手創建一個 CI/CD 管道,以自動化 Terraform 代碼的執行,進而實現 Docker 映像到 Azure Container Instances (ACI) 的部署。

Terraform 配置細節與變數運用

main.tf 文件中,除了資源組的定義,我們進一步完善了 azurerm_container_group 資源的配置。

  1. ACI 資源配置:

    resource "azurerm_container_group" "aci-myapp" {
      name                = "aci-agent"
      location            = "West Europe" # 部署區域
      resource_group_name = azurerm_resource_group.acidemobook.name # 關聯到之前定義的資源組
    
      os_type             = "linux" # 作業系統類型
    
      # 容器定義
      container {
        name  = "myappdemo"
        # 動態構建映像名稱,結合用戶名和版本變數
        image = "${var.dockerhub-username}/${var.imageversion}"
        cpu   = "0.5" # CPU 核心數
        memory = "1.5" # 記憶體大小 (GB)
    
        # 暴露容器端口
        ports {
          port     = 80
          protocol = "TCP"
        }
      }
      # 可選:配置 DNS 標籤以方便訪問
      # dns_name_label = "my-app-demo-${random_string.suffix.result}"
    }
    
    • image 屬性: 這裡的關鍵在於如何動態指定要部署的 Docker 映像。我們使用了 Terraform 的變數 var.dockerhub-usernamevar.imageversion,將它們組合起來構建出完整的映像名稱,例如 yourusername/demobook:v1。這使得我們可以在 CI/CD 管道中輕鬆地傳遞不同的用戶名和映像版本,實現靈活部署。
    • CPU 和記憶體: cpumemory 參數定義了容器所需的計算資源。
    • 端口暴露: ports 塊聲明了容器將監聽 80 端口,並使用 TCP 協議。
  2. 變數的實例化: 在 CI/CD 管道執行時,這些 Terraform 變數(imageversiondockerhub-username)將被實例化。這意味著我們可以在管道的執行階段,動態地指定要部署的 Docker 映像的具體用戶名和標籤,從而實現自動化部署。

  3. 狀態文件保護: 為了安全地管理 Terraform 的狀態文件(其中記錄了基礎設施的當前狀態),強烈建議配置 Terraform 的遠程後端。這可以防止狀態文件丟失或被未授權訪問。

創建 CI/CD 管道以自動化部署

接下來,我們將使用 Azure Pipelines 來創建一個 CI/CD 管道,該管道能夠自動執行 Terraform 代碼,從而將 Docker 映像部署到 ACI。

我們將重點關注與容器部署相關的關鍵管道階段,而不深入探討 Azure Pipelines 的所有通用配置細節(這些細節已在先前章節中詳細介紹)。

CI/CD 管道的主要步驟:

  1. 創建新的構建定義: 在 Azure Pipelines 中,創建一個新的構建定義。
    • 源代碼配置: 將構建定義的源代碼指向您的代碼倉庫(例如,一個 fork 的代碼庫)。這將允許管道訪問您的 Terraform 文件和 Dockerfile(如果需要重新構建映像)。

視覺化 CI/CD 管道與 Terraform 的整合

以下圖示展示了 CI/CD 管道如何協調 Terraform 來部署 Docker 映像到 ACI。

@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

title CI/CD Pipeline for Deploying Docker Image to ACI

start

component "Source Code Repository\n(e.g., Git)" {
  artifact "Terraform Files (main.tf, variables.tf)" as TF_FILES
  artifact "Dockerfile" as DOCKERFILE
}

component "Azure Pipelines\n(CI/CD)" {
  artifact "Build Pipeline Definition" as PIPELINE_DEF
  artifact "Stage 1: Build Image\n(Optional)" as BUILD_STAGE
  artifact "Stage 2: Deploy Infrastructure\n(Terraform Apply)" as DEPLOY_STAGE
}

component "Azure Cloud" {
  artifact "Azure Container Registry (ACR)" as ACR
  artifact "Azure Container Instances (ACI)" as ACI
}

TF_FILES --> PIPELINE_DEF : Configures Pipeline
DOCKERFILE --> BUILD_STAGE : (Optional) Builds Docker Image
BUILD_STAGE --> ACR : Pushes Image to ACR (if built)

PIPELINE_DEF --> DEPLOY_STAGE : Orchestrates Execution

DEPLOY_STAGE --> TF_FILES : Reads Terraform Code
DEPLOY_STAGE --> VARIABLES : Passes Image Info (Username, Version)
DEPLOY_STAGE --> ACR : Pulls Image for Deployment (if not built in pipeline)
DEPLOY_STAGE --> ACI : Provisions/Updates ACI Instance via Terraform

ACR --> ACI : Provides Docker Image

stop

@enduml

看圖說話:

此圖示描繪了一個典型的 CI/CD 管道,用於將 Docker 映像自動部署到 Azure Container Instances (ACI)。管道的起點是「Source Code Repository」,其中包含了「Terraform Files」(如 main.tf)和「Dockerfile」。

「Azure Pipelines」是 CI/CD 的執行引擎。它包含一個「Build Pipeline Definition」,該定義協調整個流程。管道可能包含一個「Stage 1: Build Image」(可選),負責構建 Docker 映像並將其推送到「Azure Container Registry (ACR)」。

隨後,「Stage 2: Deploy Infrastructure (Terraform Apply)」階段被執行。這個階段讀取 Terraform 代碼,並將必要的變數(如 Docker 用戶名和映像版本)傳遞給 Terraform。Terraform 接著會與 Azure 互動,創建或更新 ACI 實例。如果映像是在管道中構建的,則 ACI 會從 ACR 拉取該映像;否則,ACI 會嘗試從指定的倉庫(例如 Docker Hub 或 ACR)拉取映像。最終,ACI 實例被配置為運行指定的 Docker 容器。

結論

縱觀現代管理者的多元挑戰,將技術部署流程「程式碼化」的實踐,不僅是工程效率的躍升,更揭示了一種高階的個人管理哲學。此方法的核心價值,在於將隱性的、依賴個人經驗的部署工作,轉化為顯性的、可版本控制且能自動執行的「基礎設施即程式碼」。對應到管理者自身,這相當於將個人的領導原則、決策模型與團隊溝通模式,系統化地「編碼」成一套可重複、可優化、可擴展的個人作業系統。

然而,其真正的瓶頸並非技術掌握,而是從「親力親為的執行者」轉變為「高效能系統設計者」的思維躍遷。這要求管理者投入深度反思,識別並固化自身成功的管理模式,同時剝離那些無效或僅適用於特定情境的臨時策略。

玄貓預見,未來的領導力競爭,將不再僅僅是個人能力的較量,更是其所建構的「管理框架」品質與韌性的比拼。從個人發展演進角度,這種將內隱知識顯性化、流程化的修養,代表了未來高階管理者的核心方向,值得投入心力提前養成,以應對日益複雜的組織環境。