# 基礎設施即程式碼基礎

::: tip 前言
**你有沒有經歷過這種噩夢：線上伺服器掛了，但沒人記得當初是怎麼設定的？** 手動登入伺服器、憑記憶敲指令、祈禱不要敲錯——這就是傳統維運的日常。基礎設施即程式碼（Infrastructure as Code，IaC）徹底改變了這一切：用程式碼來定義和管理基礎設施，讓伺服器設定像軟體一樣可版本控制、可重現、可審計。
:::

**這篇文章會帶你學什麼？**

學完這章後，你將獲得：

- **核心概念**：理解 IaC 是什麼，為什麼它是現代維運的基石
- **工作流認知**：掌握 Terraform 的 Write → Plan → Apply → Destroy 四階段流程
- **工具選型**：了解 Terraform、Pulumi、CloudFormation 等主流工具的優劣
- **風險意識**：理解設定漂移的危害和偵測方法
- **最佳實踐**：掌握 IaC 專案的工程化管理方法

| 章節 | 內容 | 核心概念 |
|-----|------|---------|
| **第 1 章** | IaC 概念 | 手動維運 vs 程式碼化管理 |
| **第 2 章** | Terraform 工作流 | Write → Plan → Apply |
| **第 3 章** | 工具對比 | Terraform、Pulumi、CDK |
| **第 4 章** | 設定漂移 | 偵測、預防、修復 |
| **第 5 章** | 最佳實踐 | 模組化、狀態管理、CI/CD |

---

## 0. 全景圖：基礎設施也需要「原始碼」的動機

想像你是一個廚師。如果每道菜都憑感覺做，今天放一匙鹽、明天放兩匙，味道永遠不穩定。但如果你把配方寫下來——精確到每種調料的公克數——任何人都能重現同樣的味道。

基礎設施管理面臨的是同樣的問題。一台伺服器的設定可能涉及作業系統、網路規則、安全群組、儲存磁碟區、環境變數等幾十個參數。手動設定不僅容易出錯，而且**不可重現、不可審計、不可回滾**。

::: tip IaC 的核心價值
- **可重現**：同一份程式碼，無論執行多少次，結果都一樣（冪等性）
- **可版本控制**：基礎設施變更透過 Git 管理，誰改了什麼、為什麼改，一目了然
- **可審計**：所有變更都有記錄，滿足合規要求
- **可自動化**：透過 CI/CD 流水線自動部署，消除人為操作風險
- **可協作**：團隊成員透過 Pull Request 審查基礎設施變更，就像審查程式碼一樣
:::

---

## 1. IaC 概念：從「手動點擊」到「程式碼宣告」

傳統維運的工作方式是：登入雲平台控制台，手動點擊建立伺服器、設定網路、設定安全群組。這種方式在管理幾台伺服器時還能應付，但當規模擴大到幾十、幾百台時，就變成了噩夢。

IaC 的核心思想是：**用宣告式程式碼描述你想要的基礎設施狀態，讓工具自動幫你實現**。你不需要告訴工具「先建立 VPC，再建立子網路，再建立安全群組」（命令式），只需要說「我要一個這樣的網路環境」（宣告式），工具會自動計算出需要執行的步驟。

<IaCConceptDemo />

| 維度 | 手動維運 | 基礎設施即程式碼 |
|------|---------|--------------|
| 操作方式 | 登入控制台點擊 | 編寫程式碼檔案 |
| 可重現性 | 依賴文件和記憶 | 程式碼即文件，100% 可重現 |
| 變更追蹤 | 無記錄或記錄不全 | Git 版本控制，完整歷史 |
| 協作方式 | 口頭溝通、文件傳遞 | Pull Request 審查 |
| 回滾能力 | 手動逆向操作 | git revert + 重新 apply |
| 一致性 | 環境間差異大 | 開發/測試/正式完全一致 |

::: tip 宣告式 vs 命令式
- **宣告式（Declarative）**：描述「我要什麼」，工具自動計算「怎麼做」。Terraform、CloudFormation 採用這種方式。優點是冪等性好，缺點是靈活性受限。
- **命令式（Imperative）**：描述「怎麼做」，一步步執行。Ansible、Shell 腳本採用這種方式。優點是靈活，缺點是難以保證冪等性。
- **混合式**：Pulumi、AWS CDK 用通用程式語言編寫，兼具宣告式的狀態管理和命令式的靈活性。
:::

---

## 2. Terraform 工作流：Write → Plan → Apply

Terraform 是目前最流行的 IaC 工具，由 HashiCorp 開發。它的工作流程清晰直觀，分為四個階段，就像軟體開發的「編碼→審查→部署→清理」。

<TerraformWorkflowDemo />

::: tip 四階段工作流
1. **Write（編寫）**：用 HCL（HashiCorp Configuration Language）編寫基礎設施定義檔案（.tf）。宣告你需要的資源：伺服器、資料庫、網路等。
2. **Plan（計畫）**：執行 `terraform plan`，Terraform 會對比目前狀態和目標狀態，產生一份「執行計畫」——告訴你它打算建立、修改、刪除哪些資源。這是安全網，讓你在真正執行前確認變更。
3. **Apply（執行）**：確認計畫無誤後，執行 `terraform apply`，Terraform 按計畫建立或修改資源。執行完成後，目前狀態會儲存到狀態檔案（terraform.tfstate）。
4. **Destroy（銷毀）**：不再需要時，執行 `terraform destroy` 清理所有資源，避免產生不必要的費用。
:::

| 指令 | 作用 | 是否修改基礎設施 | 使用場景 |
|------|------|----------------|---------|
| `terraform init` | 初始化專案，下載 Provider | 否 | 首次使用或添加新 Provider |
| `terraform plan` | 預覽變更，產生執行計畫 | 否 | 每次變更前必須執行 |
| `terraform apply` | 執行變更，建立/修改資源 | 是 | 確認 plan 後執行 |
| `terraform destroy` | 銷毀所有資源 | 是 | 清理測試環境、下線服務 |
| `terraform state` | 查看/管理狀態檔案 | 視操作而定 | 狀態遷移、資源匯入 |

---

## 3. 工具對比：選擇適合你的 IaC 工具

IaC 領域有多種工具，各有側重。選擇工具時需要考慮團隊技術棧、雲平台、專案規模等因素。沒有「最好」的工具，只有最適合你場景的工具。

<IaCToolComparisonDemo />

| 工具 | 語言 | 雲平台支援 | 學習曲線 | 適用場景 |
|------|------|-----------|---------|---------|
| Terraform | HCL | 多雲（AWS/Azure/GCP） | 中等 | 多雲環境、團隊協作 |
| Pulumi | Python/TS/Go | 多雲 | 低（熟悉程式語言） | 開發者友善、複雜邏輯 |
| AWS CloudFormation | JSON/YAML | 僅 AWS | 中等 | 純 AWS 環境 |
| AWS CDK | Python/TS/Java | 僅 AWS | 低 | AWS + 程式語言偏好 |
| Ansible | YAML | 多雲 + 裸機 | 低 | 設定管理、混合環境 |

::: tip 如何選擇？
- **新創團隊 / 單雲**：CloudFormation（AWS）或對應雲平台原生工具，生態整合最好
- **多雲 / 中大型團隊**：Terraform，社群最大、Provider 最豐富、招聘最容易
- **開發者主導的團隊**：Pulumi 或 CDK，用熟悉的程式語言寫基礎設施，IDE 支援好
- **需要設定管理**：Ansible，擅長伺服器內部設定（安裝軟體、修改設定檔）
:::

---

## 4. 設定漂移：無聲的定時炸彈

設定漂移（Configuration Drift）是 IaC 實踐中最隱蔽的敵人。它指的是**實際基礎設施狀態與程式碼定義的狀態之間逐漸產生偏差**。

這種偏差通常是怎麼產生的？有人為了「快速修復」一個線上問題，直接登入控制台手動改了安全群組規則；有人為了除錯，臨時加大了某台伺服器的設定但忘了改回來。這些「小改動」日積月累，最終導致程式碼和實際環境嚴重脫節。

<ConfigDriftDemo />

::: tip 設定漂移的危害
1. **不可重現**：程式碼描述的環境和實際環境不一致，新建環境時會出問題
2. **回滾失敗**：以為回滾到上一版本就能恢復，但實際環境已經被手動修改過
3. **安全隱患**：手動開放的連接埠、放寬的權限可能被遺忘，成為攻擊入口
4. **審計失效**：合規審計基於程式碼，但程式碼不反映真實狀態
:::

| 預防措施 | 說明 |
|---------|------|
| 禁止手動變更 | 透過 IAM 策略限制控制台操作權限 |
| 定期漂移偵測 | 定時執行 `terraform plan` 檢查差異 |
| 自動修復 | 偵測到漂移後自動執行 apply 恢復一致性 |
| 變更審計 | 開啟 CloudTrail 等審計日誌，追蹤所有變更來源 |

---

## 5. 最佳實踐：讓 IaC 專案可持續演進

IaC 程式碼和應用程式碼一樣，需要良好的工程實踐來保證可維護性。隨著基礎設施規模增長，沒有章法的 IaC 程式碼會變成另一種形式的「技術債」。

<IaCBestPracticeDemo />

::: tip 六條核心最佳實踐
1. **模組化**：將可重複使用的基礎設施抽象為模組（如 VPC 模組、資料庫模組），避免複製貼上。就像寫函式一樣，一處定義、多處呼叫。
2. **環境隔離**：開發、測試、正式使用獨立的狀態檔案和變數檔案，透過 workspace 或目錄結構隔離。
3. **遠端狀態管理**：狀態檔案（tfstate）儲存在遠端後端（S3 + DynamoDB），支援團隊協作和狀態鎖定，避免並行衝突。
4. **敏感資訊管理**：密碼、金鑰等敏感資訊不要寫在程式碼裡，使用 Vault、AWS Secrets Manager 等工具管理。
5. **CI/CD 整合**：將 terraform plan 整合到 PR 流程，apply 透過流水線自動執行，杜絕本機手動操作。
6. **程式碼審查**：基礎設施變更和應用程式碼一樣需要 Code Review，尤其是涉及安全群組、IAM 策略的變更。
:::

---

## 總結

基礎設施即程式碼是現代雲原生維運的基石。它把「不可描述的手動操作」變成了「可版本控制的程式碼」，讓基礎設施管理從「藝術」變成了「工程」。

回顧本章的關鍵要點：

1. **IaC 的本質**：用程式碼宣告基礎設施的期望狀態，讓工具自動實現
2. **Terraform 工作流**：Write → Plan → Apply 三步走，Plan 是安全網
3. **工具選型**：多雲選 Terraform，單雲選原生工具，開發者團隊選 Pulumi
4. **設定漂移**：最隱蔽的風險，需要透過流程和工具雙重防護
5. **工程化管理**：模組化、環境隔離、遠端狀態、CI/CD 整合缺一不可

## 延伸閱讀

- [Terraform 官方教學](https://developer.hashicorp.com/terraform/tutorials) - 從零開始學 Terraform
- [Pulumi 文件](https://www.pulumi.com/docs/) - 用程式語言寫基礎設施
- [AWS CDK Workshop](https://cdkworkshop.com/) - AWS CDK 實戰教學
- [Infrastructure as Code (O'Reilly)](https://www.oreilly.com/library/view/infrastructure-as-code/9781098114664/) - IaC 領域的經典書籍
- [Spacelift Blog](https://spacelift.io/blog) - IaC 最佳實踐和行業趨勢
