Infrastructure as Code(IaC)

是什麼?

Infrastructure as Code(IaC)是用宣告式或程序式的程式碼定義和管理雲端基礎設施。透過 Terraform、Bicep、Pulumi 等工具,把「點按 Azure Portal」變成「寫程式碼 + git push」。

ℹ️宣告式 vs 程序式

宣告式(Declarative):你描述「想要什麼」,工具負責達到目標狀態(Terraform、Bicep)。程序式(Imperative):你描述「怎麼做」,一步步執行命令(Pulumi、AWS CDK)。大多數 IaC 工具採用宣告式。

核心觀念

常見誤區

⚠️常見誤區

  • State 檔案存在 Git 裡:State 可能包含密碼等敏感資訊,必須存在 Remote Backend(如 Azure Storage、S3、Terraform Cloud)
  • 不做 Plan 直接 Apply:跳過 Plan 可能意外刪除生產環境的資源。永遠先 Plan 再 Apply
  • 一個大檔案管所有資源:應該按環境(dev/staging/prod)和服務拆分,避免一次變更影響所有環境

流程/步驟

1

撰寫 IaC 程式碼

用 Terraform HCL 或 Bicep 定義基礎設施

2

Init(初始化)

下載 Provider Plugin、設定 Remote Backend

3

Plan(預覽)

比較程式碼和現狀,列出新增/修改/刪除的資源

4

Review(審查)

團隊 Review Plan 結果,確認變更合理

5

Apply(執行)

向雲端 API 發送請求,建立/更新/刪除資源

6

版控 + CI/CD

IaC 程式碼提 PR,Pipeline 自動 Plan,Merge 後 Apply

流程解讀:IaC 的工作流程和寫程式碼相同 — 寫 code、commit、PR、review、merge。Init 設定環境,Plan 預覽變更避免意外,Apply 才真正執行。CI/CD Pipeline 自動化整個流程。

程式碼範例

C# 版本

csharp
// Bicep — Azure 原生 IaC(適合 .NET 團隊)
// main.bicep
bicep
// main.bicep — 定義 Azure Web App + SQL Database
param location string = resourceGroup().location
param appName string = 'myapp-prod'
 
// App Service Plan
resource appServicePlan 'Microsoft.Web/serverfarms@2023-01-01' = {
  name: '${appName}-plan'
  location: location
  sku: {
    name: 'B1'
    tier: 'Basic'
  }
}
 
// Web App
resource webApp 'Microsoft.Web/sites@2023-01-01' = {
  name: appName
  location: location
  properties: {
    serverFarmId: appServicePlan.id
    siteConfig: {
      netFrameworkVersion: 'v8.0'
      alwaysOn: true
    }
  }
}
 
// SQL Server + Database
resource sqlServer 'Microsoft.Sql/servers@2023-05-01-preview' = {
  name: '${appName}-sql'
  location: location
  properties: {
    administratorLogin: 'sqladmin'
    administratorLoginPassword: sqlPassword // 從 Key Vault 取得
  }
}

TypeScript 版本

hcl
# Terraform — 跨雲 IaC
# main.tf — AWS 版本
 
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
 
  # Remote Backend — State 存在 S3
  backend "s3" {
    bucket = "my-terraform-state"
    key    = "prod/terraform.tfstate"
    region = "us-east-1"
  }
}
 
# VPC
resource "aws_vpc" "main" {
  cidr_block = "10.0.0.0/16"
  tags = { Name = "main-vpc" }
}
 
# EC2 Instance
resource "aws_instance" "web" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t3.micro"
  subnet_id     = aws_subnet.public.id
 
  tags = { Name = "web-server" }
}
 
# RDS Database
resource "aws_db_instance" "main" {
  engine         = "postgres"
  engine_version = "16"
  instance_class = "db.t3.micro"
  db_name        = "myapp"
  username       = "admin"
  password       = var.db_password  # 從變數或 Secret Manager 取得
}

Python 版本

python
# Pulumi — 用真正的程式語言寫 IaC
import pulumi
import pulumi_azure_native as azure
 
# Resource Group
resource_group = azure.resources.ResourceGroup("myapp-rg")
 
# App Service Plan
plan = azure.web.AppServicePlan(
    "myapp-plan",
    resource_group_name=resource_group.name,
    kind="Linux",
    reserved=True,
    sku=azure.web.SkuDescriptionArgs(name="B1", tier="Basic"),
)
 
# Web App
app = azure.web.WebApp(
    "myapp",
    resource_group_name=resource_group.name,
    server_farm_id=plan.id,
    site_config=azure.web.SiteConfigArgs(
        linux_fx_version="PYTHON|3.12",
        always_on=True,
    ),
)
 
# 輸出 URL
pulumi.export("url", app.default_host_name.apply(lambda h: f"https://{h}"))

架構圖/概念圖

IaC Code (Git)
PR triggers
CI/CD Pipeline
terraform plan
Plan (Preview)
approved
Apply (Execute)
create/update
Remote State
compares
Cloud Resources

IaC 程式碼提交後觸發 Pipeline。Pipeline 執行 Plan 比較程式碼和 Remote State 的差異,產出變更預覽。經人工審核後執行 Apply,向雲端 API 發送請求建立或更新資源,同時更新 State。

實戰補充

Q: Terraform 和 Bicep 怎麼選?

A: Terraform:跨雲(AWS + Azure + GCP)、社群生態最大、HCL 語法。Bicep:Azure 專用、和 ARM 深度整合、VS Code 支援好。純 Azure 環境推薦 Bicep,多雲環境用 Terraform。

Q: State 檔案丟了怎麼辦?

A: State 丟了 IaC 工具就「不知道」現有資源的存在。解法:(1) 用 terraform import 逐一匯入現有資源。(2) 永遠把 State 存在 Remote Backend 並定期備份。(3) 開啟 State Locking 防止並行操作衝突。

Q: 如何防止有人手動改雲端資源?

A: (1) 開啟 Drift Detection 定期檢查。(2) 限制生產環境的手動操作權限(只有 IaC Pipeline 有 Apply 權限)。(3) 用 Azure Policy / AWS Config 偵測違規資源。

理解測驗

🤔 為什麼 IaC 的 State 檔案不應該存在 Git 中?

🤔 terraform plan 的作用是什麼?

🤔 IaC 的冪等性(Idempotent)是什麼意思?

重點整理

💡一句話記住

IaC = 用程式碼管理基礎設施,像管程式碼一樣版控、Review、自動部署。 口訣:「Plan 先看、Apply 再做、State 別丟」

| 概念 | 說明 | |------|------| | State | 記錄當前基礎設施狀態,存在 Remote Backend | | Plan | 預覽變更,不實際執行 | | Apply | 執行變更,建立/更新/刪除資源 | | Module | 可重用的基礎設施元件 | | Drift | 手動改動導致實際狀態和程式碼不同步 |

你可能也想看

部署策略回到目錄 →

按 ← → 鍵切換課程