Pulumi + TypeScript IaC 實戰:2026年開發者基礎設施即程式碼完全指南
DevOps
2026年,為什麼 Pulumi + TypeScript 對開發者更友好
Terraform 用 HCL 定義基礎設施,這是一種領域特定語言(DSL)。開發者需要學習新語法、處理字串插值、忍受缺乏 IDE 支援的痛苦。Pulumi 讓你用真正的程式語言定義基礎設施——TypeScript 意味著你有型別檢查、IDE 自動補全、npm 生態、條件邏輯和迴圈。
| 維度 | Terraform (HCL) | Pulumi (TypeScript) | CDK (TypeScript) |
|---|---|---|---|
| 語言 | HCL (DSL) | TypeScript | TypeScript |
| 型別安全 | 無 | 完整 | 完整 |
| IDE 支援 | 有限 | 完整 | 完整 |
| 條件邏輯 | count/for_each | if/else/for | if/else/for |
| 模組復用 | Terraform Module | npm 套件 | Construct |
| 狀態管理 | State File | Pulumi Cloud/自託管 | CDK Cloud |
| 祕密管理 | .tfvars | Config secrets | Context |
| 測試 | terraform test | Mocha/Jest | Jest |
| 學習曲線 | 低 | 低 | 中 |
Pulumi 架構
┌─────────────────────────────────────────────────────┐
│ Pulumi CLI (pulumi) │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ Engine │ │ Language │ │ Resource │ │
│ │ (編排核心) │──│ Host │──│ Provider │ │
│ └────────────┘ │ (Node.js) │ │ (gRPC) │ │
│ └────────────┘ └────────────┘ │
└─────────────────────────────────────────────────────┘
完整專案搭建
curl -fsSL https://get.pulumi.com | sh
pulumi login
mkdir my-infra && cd my-infra
pulumi new aws-typescript
部署 AWS 資源
import * as aws from "@pulumi/aws";
import * as awsx from "@pulumi/awsx";
import * as pulumi from "@pulumi/pulumi";
const env = pulumi.getStack();
const vpc = new awsx.ec2.Vpc("main-vpc", {
cidrBlock: "10.0.0.0/16",
subnets: [
{ type: "public", cidrMask: 24 },
{ type: "private", cidrMask: 24 },
],
tags: { Environment: env },
});
const db = new aws.rds.Instance("app-db", {
engine: "postgres",
engineVersion: "16.4",
instanceClass: "db.t3.medium",
allocatedStorage: 100,
storageType: "gp3",
dbName: "appdb",
username: "appadmin",
password: pulumi.Config.requireSecret("db-password"),
skipFinalSnapshot: true,
tags: { Environment: env },
});
const cluster = new aws.ecs.Cluster("app-cluster", {
tags: { Environment: env },
});
export const dbEndpoint = db.endpoint;
部署 GCP 資源
import * as gcp from "@pulumi/gcp";
const cluster = new gcp.container.Cluster("app-cluster", {
project: gcp.config.project,
location: "us-central1",
initialNodeCount: 3,
nodeConfig: { machineType: "e2-medium" },
});
export const clusterName = cluster.name;
部署 Azure 資源
import * as azure from "@pulumi/azure";
const resourceGroup = new azure.core.ResourceGroup("app-rg", {
location: "East Asia",
tags: { Environment: pulumi.getStack() },
});
const aks = new azure.containerservice.KubernetesCluster("app-aks", {
resourceGroupName: resourceGroup.name,
location: resourceGroup.location,
defaultNodePool: { name: "default", nodeCount: 3, vmSize: "Standard_D2s_v3" },
identity: { type: "SystemAssigned" },
});
export const aksFqdn = aks.fqdn;
Stack 管理和設定
pulumi stack init dev
pulumi stack init prod
pulumi config set aws:region us-east-1
pulumi config set db-password "secret-value" --secret
pulumi stack select prod
pulumi up
const config = new pulumi.Config();
const instanceCount = config.requireNumber("instance-count");
const dbPassword = config.requireSecret("db-password");
const isProd = pulumi.getStack() === "prod";
測試基礎設施
import * as pulumi from "@pulumi/pulumi";
import { describe, it, expect } from "mocha";
pulumi.runtime.setMocks({
newResource: (args) => ({ id: `${args.name}-id`, state: args.inputs }),
call: (args) => args.inputs,
});
describe("Infrastructure", () => {
it("should use larger DB in production", () => {
const isProd = true;
const dbInstanceClass = isProd ? "db.r6g.xlarge" : "db.t3.medium";
expect(dbInstanceClass).to.equal("db.r6g.xlarge");
});
});
Pulumi vs Terraform vs CDK
| 維度 | Pulumi | Terraform | CDK |
|---|---|---|---|
| 語言 | TS/Python/Go/C# | HCL | TS/Python/Java/C# |
| Provider | 200+ | 3000+ | AWS為主 |
| 測試 | 原生 | terraform test | Jest |
| 多雲 | 原生 | 原生 | AWS為主 |
5 個常見陷阱
1. 輸出值在執行時不可用
Pulumi 的 Output<T> 是非同步的,不能在執行時直接存取值。
2. 資源依賴未正確宣告
Pulumi 自動推斷依賴,但有時需要顯式宣告。
3. Stack 設定中明文儲存祕密
使用 --secret 標記保護敏感設定。
4. 忽略 destroy 保護
生產環境應啟用資源保護,防止意外刪除。
5. 並行部署導致競態條件
多個 Stack 同時部署同一資源可能導致衝突。
10 個錯誤排查
| # | 錯誤現象 | 可能原因 | 排查方法 |
|---|---|---|---|
| 1 | requireSecret 回傳加密值 | 在非 apply 中使用 | 使用 apply 或 interpolate |
| 2 | 資源建立逾時 | 雲 API 限流 | 檢查並行度 |
| 3 | Provider 版本不相容 | package.json 版本過舊 | pulumi plugin install |
| 4 | Stack 狀態損壞 | 部署中斷 | pulumi state unprotect |
| 5 | 型別錯誤 | TypeScript 型別不匹配 | tsc --noEmit |
| 6 | 迴圈依賴 | 資源間互相引用 | 重構依賴圖 |
| 7 | 設定缺失 | Stack 設定未設定 | pulumi config |
| 8 | 權限不足 | 雲憑證權限不夠 | 檢查 IAM 角色 |
| 9 | Drift 偵測 | 手動修改了雲資源 | pulumi refresh |
| 10 | 匯入現有資源失敗 | 資源 ID 不正確 | 檢查 ID 格式 |
線上工具推薦
- JSON 格式化:/zh-TW/json/format
- Base64 編碼:/zh-TW/encode/base64
- 雜湊計算:/zh-TW/encode/hash
總結:Pulumi + TypeScript 讓開發者用熟悉的程式語言定義基礎設施,享受型別安全、IDE 支援和 npm 生態。2026年,Pulumi 已支援 200+ Provider,覆蓋 AWS、GCP、Azure 等主流雲平台。對於熟悉 TypeScript 的開發者,Pulumi 是比 Terraform 更自然、更高效的 IaC 選擇。
本站提供瀏覽器本地工具,免註冊即可試用 →
#Pulumi#IaC#TypeScript#基础设施即代码#AWS#GCP#Azure#云资源管理