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 格式

線上工具推薦


總結:Pulumi + TypeScript 讓開發者用熟悉的程式語言定義基礎設施,享受型別安全、IDE 支援和 npm 生態。2026年,Pulumi 已支援 200+ Provider,覆蓋 AWS、GCP、Azure 等主流雲平台。對於熟悉 TypeScript 的開發者,Pulumi 是比 Terraform 更自然、更高效的 IaC 選擇。

本站提供瀏覽器本地工具,免註冊即可試用 →

#Pulumi#IaC#TypeScript#基础设施即代码#AWS#GCP#Azure#云资源管理