【実務・中級編】PulumiでCloudflare WorkersとD1データベースを統合管理するサーバーレス構成の完全ガイド – インフラ構成管理(IaC)活用バイブル

【Pulumi×Cloudflare】エッジの覇者へ贈る:Workers & D1 サーバーレスインフラ完全コード化の極意

テックリードの君なら、もう気づいているはずだ。
コンソールをポチポチ叩いてリソースを作る「クリックOps」や、複雑怪奇で遅いTerraformのHCL(HashiCorp Configuration Language)にフラストレーションを溜める時代は終わった。

エッジコンピューティングのスピードを最大限に活かし、TypeScriptの型安全性をインフラ定義にまで持ち込む。それが Pulumi だ。

今回は、Cloudflare Workers と超高速エッジSQLデータベースである D1、そしてDNSルーティングを Pulumiで完全にコード化(IaC)し、冪等性を完全に担保したサーバーレス環境を構築する手法 を、現場の即戦力となる知見とともに余すところなく伝授しよう。

—

1. エッジ時代におけるIaCとCloudflareプロバイダの深淵

なぜ、Cloudflareワーカーズの管理にPulumiなのか?

Cloudflare Workersは、世界275都市以上のエッジロケーションでコードを実行する。しかし、インフラストラクチャが分散すればするほど、その管理はカオスになりがちだ。

  • `wrangler.toml` によるデプロイ管理の限界(複数環境の複雑化、シークレット管理の破綻)
  • TerraformのCloudflareプロバイダにおける、Workersのバンドル・デプロイプロセスのまどろっこしさ

Pulumiを使えば、インフラの定義に TypeScript(またはPython, Go)の全パワー を利用できる。関数、ループ、条件分岐、そして何より既存のnpmパッケージを活用したビルドパイプラインの統合が、圧倒的な開発スピードをもたらす。

Cloudflareプロバイダの仕組み

PulumiのCloudflareプロバイダは、CloudflareのAPI(GraphQLおよびREST)を直接叩き、リソースの状態を抽象化する。
ここで重要なのは、「Workersスクリプトのバンドル・アップロード」と「D1データベースのスキーマ適用」というアプリケーションレイヤーに近い処理を、インフラのライフサイクル(Create/Update/Delete)にどう組み込むかという点だ。

—

2. 実践:Workers × D1 × DNS の完全プロビジョニング

百聞は一見に如かず。プロジェクトのディレクトリ構造からコードの隅々まで、プロダクションクオリティの構成を解説する。

ディレクトリ構造のベストプラクティス

チーム開発で破綻しないための、洗練されたレイアウトだ。

.
├── Pulumi.yaml
├── Pulumi.dev.yaml # 開発環境用スタック設定(シークレット含む)
├── Pulumi.prod.yaml # 本番環境用スタック設定
├── package.json
├── tsconfig.json
├── index.ts # インフラのメインエントリーポイント
└── src # Workersのソースコード
├── index.ts
└── schema.sql # D1データベースの初期スキーマ

1. `package.json` と依存関係

最新の型定義と、ビルドに不可欠なパッケージを確実に固定する。

{
“name”: “cloudflare-edge-pulumi”,
“devDependencies”: {
“@pulumi/cloudflare”: “^5.0.0”,
“@pulumi/pulumi”: “^3.100.0”,
“typescript”: “^5.3.0”,
“esbuild”: “^0.19.0”
},
“dependencies”: {
“@cloudflare/workers-types”: “^4.20231218.0”
}
}

2. インフラ定義の核心:`index.ts`

ここが今回のハイライトだ。D1データベースの作成、スキーマのバインド、Workersスクリプトのビルド&デプロイ、そしてカスタムドメインのルーティングまでを1つのトランザクション(のような冪等性)で完結させる。

import as pulumi from “@pulumi/pulumi”;
import as cloudflare from “@pulumi/cloudflare”;
import as esbuild from “esbuild”;
import as fs from “fs”;
import as path from “path”;

// 1. スタック設定の読み込み
const config = new pulumi.Config();
const domain = config.require(“domain”);
const zoneId = config.require(“zoneId”);
const environment = pulumi.getStack();

// 2. D1データベースのプロビジョニング
// エッジに分散するSQLiteデータベースを宣言的に作成
const database = new cloudflare.D1Database(`app-db-${environment}`, {
accountId: config.require(“cloudflareAccountId”),
name: `production-d1-${environment}`,
});

// 3. Workersスクリプトのインメモリビルド(esbuild)
// 開発体験を極限まで高めるため、Pulumiの実行時にコードをバンドルする
const buildWorker = () => {
const entryPoint = path.join(__dirname, “src”, “index.ts”);
const result = esbuild.buildSync({
entryPoints: [entryPoint],
bundle: true,
write: false,
format: “esm”,
target: “esnext”,
minify: true,
});
return result.outputFiles[0].text;
};

// 4. Cloudflare Workers Scriptの定義
const workerScript = new cloudflare.WorkerScript(`edge-worker-${environment}`, {
accountId: config.require(“cloudflareAccountId”),
name: `api-${environment}`,
content: buildWorker(),
// D1データベースをバインディングとしてWorkersに渡す
d1Databases: [{
binding: “DB”,
databaseId: database.id,
}],
compatibilityDate: “2024-01-01”,
});

// 5. カスタムドメイン(Routes)の設定
// 例: api.example.com/ をWorkersに向ける
const workerRoute = new cloudflare.WorkerRoute(`worker-route-${environment}`, {
zoneId: zoneId,
pattern: `api.${domain}/`,
scriptName: workerScript.name,
});

// 6. 出力値の定義(CI/CDやデバッグ用)
export const workerName = workerScript.name;
export const d1DatabaseId = database.id;
export const endpointUrl = pulumi.interpolate`https://api.${domain}`;

—

3. チーム開発の生産性を爆上げするプロの技術

ここからが、凡百のチュートリアルとは一線を画す「テックリードの知見」だ。チーム全体の開発スピードを物理の限界まで加速させる設定と作法を共有しよう。

隠れたキーボードショートカット & IDEプラグイン(VS Code)

VS CodeでPulumiを扱う際、以下のプラグインを入れていないなら今すぐインストールせよ。

1. Pulumi Extension (Official)

  • スタックのプレビュー、更新、リソースグラフの視覚化をIDE内で完結させる。

2. Error Lens

  • TypeScriptの型エラーやPulumiのConfig未設定エラーをコード行の末尾にインライン表示させ、視線移動をゼロにする。

【神ショートカット】

  • `Ctrl + Shift + P` -> `Pulumi: Preview` : 変更を加えた瞬間にインフラの差分(Diff)を非同期で確認。
  • `Ctrl + Shift + P` -> `Pulumi: Up` : デプロイの実行。

チーム開発における設定共有化ルール

複数のエンジニアでCloudflareインフラを触るとき、シークレット(APIトークン等)の管理で事故が起きる。以下のルールを鉄則とせよ。

1. プレーンテキストのシークレット禁止

  • `Pulumi..yaml` に機密情報を直接書かない。必ず `pulumi config set –secret` を使用し、Pulumi Secret Encryption(KMS / AWS Secrets Manager / HashiCorp Vault等、またはPulumi Serviceの暗号化)を利用する。

2. Passphraseの共有

  • バックエンドにPulumi Service(SaaS)を使わず、S3/GCSなどをState Backendにする場合は、`PULUMI_CONFIG_PASSPHRASE` 環境変数を1Password等のパスワードマネージャーでチーム共有し、CI/CDおよびローカルの暗号化鍵を統一する。

—

4. ローカル開発から本番デプロイまでのシームレスなワークフロー

エッジ開発の最大のボトルネックは「ローカルと本番の挙動の乖離」だ。
これを打破するため、`Wrangler` のローカルエミュレーションと Pulumi のIaCを組み合わせたハイブリッド・ワークフローを構築する。

1. ローカル開発(Wrangler CLIの活用)

Workersのロジック開発やD1のクエリテストには、Cloudflare公式の `wrangler` をローカルサーバーとして走らせる。

ローカルでのD1マイグレーション実行とWorkers起動
npx wrangler d1 execute production-d1-dev –local –file=./src/schema.sql
npx wrangler dev

2. インフラのプロビジョニング & デプロイ(Pulumi)

ローカルで動作確認が取れたコードとインフラの変更を、Pulumiで一撃でクラウドへ反映する。

依存関係のインストールとログイン
npm install
pulumi stack select dev

プレビューで変更点を入念に確認(ここで恐怖心を取り除く)
pulumi preview

デプロイ実行
pulumi up –yes

このワークフローにより、「インフラの構築」「データベースのプロビジョニング」「Workersのコードデプロイ」「DNSルーティングの設定」のすべてが、ひとつの `pulumi up` コマンドに収束する。

—

結び:インフラをコードで統べる快感

ここまでついてきた君なら、もう従来の重厚長大なインフラ管理に戻ることはできないはずだ。
TypeScriptの型補完が効く快適なエディタの中で、Cloudflare Workersの高速なエッジ演算とD1のデータベースが、Pulumiのコードによって美しく結びつき、一瞬で世界中にデプロイされていく。

この完全自動化されたサーバーレス・パイプラインこそが、モダンな開発チームに圧倒的なアジリティをもたらす。さあ、今すぐターミナルを開き、`pulumi up` を叩いて世界を書き換えよう。

タイトルとURLをコピーしました