Pulumi + TypeScript IaC実践:2026年開発者のためのInfrastructure as Codeガイド
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 |
| テスト | 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 },
});
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. 実行時にOutput値が利用不可
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 | ドリフト検出 | 手動でクラウドリソースを変更 | pulumi refresh |
| 10 | 既存リソースのインポート失敗 | リソースIDが不正 | ID形式を確認 |
おすすめツール
- JSONフォーマッター:/ja/json/format
- Base64エンコーダー:/ja/encode/base64
- ハッシュ計算:/ja/encode/hash
まとめ:Pulumi + TypeScriptは開発者が使い慣れたプログラミング言語でインフラを定義でき、型安全性、IDEサポート、npmエコシステムの恩恵を受けられます。2026年、Pulumiは200以上のProviderをサポートし、AWS、GCP、Azureなどの主要クラウドプラットフォームをカバーしています。TypeScriptに慣れた開発者にとって、PulumiはTerraformよりも自然で効率的なIaCの選択肢です。
ブラウザローカルツールを無料で試す →
#Pulumi#IaC#TypeScript#基础设施即代码#AWS#GCP#Azure#云资源管理