【入門編】Pulumi Stack References(スタック間参照)を使った効率的なマイクロサービス基盤構築 – インフラ構成管理(IaC)活用バイブル

こんにちは!クラウドインフラ・SREの世界へようこそ。
日々、膨大なリソースの管理やデプロイの待ち時間に頭を悩ませていませんか?

「Terraformで書いたインフラコードが、巨大になりすぎて計画(plan)や適用(apply)に何分もかかる……」
「VPCのような基盤ネットワークを変更しただけなのに、なぜか全く関係ないアプリケーション層まで巻き込んで壊れかけた……」

そんな苦い経験を持つあなたに朗報です。これをマスターすれば、毎日のインフラ作業が劇的に、そして圧倒的に楽になりますよ。

今回は、現代のクラウド開発において最強の武器となる「Pulumi(プルミ)」、そしてその真骨頂である「Stack References(スタック間参照)」を用いた、美しくスケーラブルなマイクロサービス基盤の構築術を徹底解説します。

初めてPulumiに触れる方でも置いてけぼりにしません。基本のセットアップから「これぞIaCの理想形だ」と唸る動作確認まで、優しく、そしてディープに案内していきましょう。

—

1. なぜ「巨大モノリスインフラ」を捨てて分割すべきなのか?

インフラストラクチャ・作為・コード(IaC)の初期によくあるアンチパターンが、「ひとつのリポジトリ、ひとつの状態ファイル(State)にすべてを詰め込む」という巨大モノリス構成です。

これには以下のような致命的な問題があります。

  • 爆風半径(Blast Radius)の肥大化: ちょっとしたLambda関数の設定変更ミスが、プロダクション環境の基幹VPCやデータベースを吹き飛ばすリスク。
  • デプロイのノロジカ: 管理するリソースが数千を超えると、差分計算だけでコーヒーを飲み干せるほどの時間がかかる。
  • チーム間のコンフリクト: ネットワークエンジニアとアプリケーションエンジニアが同じStateファイルを奪い合い、マージ地獄に陥る。

解決策:インフラの「マイクロサービス化」

コードベースを「ネットワーク層」「共通基盤層(DB/K8s等)」「各アプリケーション層」に綺麗に切り分けましょう。
しかし、ここで新たな課題が生じます。「分割したインフラ同士はどうやってデータをやり取りするのか?」です。

VPCのIDやサブネットの配列を、人間がコピペしてJSONに書き込む? そんな前時代的なやり方はSREの美学に反します。ここで登場するのが、Pulumi Stack Referencesです。

—

2. Pulumiとは?(ツールの役割と基本)

Pulumiは、JSONやYAML、あるいは専用のDSLではなく、使い慣れたプログラミング言語(TypeScript, Python, Go, C#など)を使ってクラウドインフラを定義・構築できる次世代のIaCツールです。

Terraformとの最大の違いは、「本物のプログラミング言語のパワー(ループ、条件分岐、関数、テスト)をそのまま使えること」。
今回は、型安全でインテリセンス(入力補完)の恩恵を最大限に受けられる TypeScript を用いて解説します。

—

3. 5分で完了!Pulumiのインストールと基礎セットアップ

まずは手元の環境を整えましょう。ここではmacOSをベースに説明しますが、LinuxやWindows(WSL2)でも同様です。

Step 1: ツールのインストール

Homebrewを使って、Pulumi CLIとNode.jsをインストールします。

Pulumi CLIのインストール
brew install pulumi

バージョン確認
pulumi version

Step 2: クラウド認証の設定(今回はAWSを例に)

あらかじめ `aws configure` などで有効なクレデンシャルを設定しておいてください。Pulumiは背後でAWS Providerを通じて動くため、AWS CLIの権限をそのまま継承します。

Step 3: プロジェクトの初期化

作業用ディレクトリを作り、Pulumiプロジェクトをセットアップします。

mkdir pulumi-microservices-demo && cd pulumi-microservices-demo
pulumi new aws-typescript

途中でいくつか質問されます(プロジェクト名、スタック名、AWSのリージョンなど)。基本はデフォルト(Enter連打)でOKです。
完了すると、`index.ts` や `package.json` が生成されます。

—

4. Stack Referencesで実現する「ネットワーク層」と「アプリ層」の分離

ここからが本題です。今回は以下の2つの「スタック(環境・単位ごとの独立したインフラ空間)」を作ります。

1. `network` スタック: VPCやサブネットなど、変更頻度が低い基盤ネットワークを管理。
2. `app` スタック: そのVPC上にデプロイされるアプリケーション(例: ECSやEC2など)を管理。

フェーズ1:ネットワーク層の構築 (`network` スタック)

まずはVPCを作るコードを記述します。`index.ts` を以下のように書き換えてください。

`index.ts` (Network Stack)

import as pulumi from “@pulumi/pulumi”;
import as aws from “@pulumi/aws”;

// 1. シンプルなVPCの作成
const vpc = new aws.ec2.Vpc(“demo-vpc”, {
cidrBlock: “10.0.0.0/16”,
enableDnsHostnames: true,
enableDnsSupport: true,
tags: { Name: “pulumi-demo-vpc” },
});

// 2. パブリックサブネットの作成
const publicSubnet = new aws.ec2.Subnet(“demo-subnet”, {
vpcId: vpc.id,
cidrBlock: “10.0.1.0/24”,
mapPublicIpOnLaunch: true,
tags: { Name: “pulumi-demo-subnet” },
});

// — ここが極意:他のスタックから参照させたい値を「Export」する —
export const vpcId = vpc.id;
export const subnetId = publicSubnet.id;
export const vpcCidr = vpc.cidrBlock;

これをデプロイします。

pulumi stack init dev-network
pulumi up –yes

デプロイが成功すると、ターミナルに `vpcId` や `subnetId` が出力されます。これが他のスタックへの「招待状」になります。

—

フェーズ2:アプリケーション層からの参照 (`app` スタック)

次に、別のディレクトリ(または同じプロジェクト内の別スタック)でアプリケーション側のコードを書きます。今回は論理的に分かりやすくするため、同じプロジェクト内で新しいスタック `dev-app` を作成し、先ほどの `dev-network` のリソースを参照してみましょう。

新しいスタックに切り替えます。

pulumi stack init dev-app

そして、コードから別のスタックを参照するには、`pulumi.StackReference` を使います。
以下のコードを(必要に応じて別ファイル、あるいはスタックを分けた際の記述として)見てください。

`index.ts` (App Stack – Stack Referencesの活用)

import as pulumi from “@pulumi/pulumi”;
import as aws from “@pulumi/aws”;

// 1. 既にデプロイ済みの “dev-network” スタックを指すリファレンスを作成
// 組織名/プロジェクト名/スタック名 の形式で指定します(個人利用なら `organization/project/stack`)
const stackOrg = pulumi.getOrganization();
const projectName = pulumi.getProject();
const networkStackRef = new pulumi.StackReference(`${stackOrg}/${projectName}/dev-network`);

// 2. スタックの出力(Exports)から安全に値を取得する(型安全!)
const vpcId = networkStackRef.requireOutput(“vpcId”);
const subnetId = networkStackRef.requireOutput(“subnetId”);

// 3. 取得したVPC IDを使って、アプリケーション用のセキュリティグループを作成
const appSecurityGroup = new aws.ec2.SecurityGroup(“app-sg”, {
vpcId: vpcId, // ← 別スタックで作られたVPC IDを動的にバインド!
description: “Security group for microservice app”,
ingress: [
{ protocol: “tcp”, fromPort: 80, toPort: 80, cidrBlocks: [“0.0.0.0/0”] },
],
egress: [
{ protocol: “-1”, fromPort: 0, toPort: 0, cidrBlocks: [“0.0.0.0/0”] },
],
tags: { Name: “microservice-app-sg” },
});

// 4. アプリ側からも必要な情報を外へエクスポート
export const securityGroupId = appSecurityGroup.id;
export const boundVpcId = vpcId;

これをデプロイします。

pulumi up –yes

凄さに気づきましたか?
`dev-app` スタックは、`dev-network` がどのように作られたかの詳細(AWSのコンソール画面やコードの中身)を一切知る必要がありません。ただ、「ネットワーク側が公開してくれた `vpcId`」というインターフェース(契約)だけを頼りに、安全にリソースを結合しています。

—

5. 変更影響範囲を最小限に抑える組織的アプローチ

この Stack References を導入したアーキテクチャ運用を始めると、組織のワークフローに劇的な変化が訪れます。

1. 関心事の完全な分離(SoC):
ネットワークチームは `dev-network` だけを保守し、セキュリティやIP設計に集中できます。アプリチームは `dev-app` 内で自由にコンテナをデプロイできます。
2. デプロイ順序の自然な制御:
依存関係のグラフはスタック間で自動解決されます。`dev-network` が存在しない(あるいは値が変更されていない)状態で `dev-app` を壊すような変更を加えると、Pulumiが明確にエラーや差分を検知して教えてくれます。
3. 爆風半径の極小化:
アプリのコードを修正して `pulumi up` しても、ネットワーク層のStateには1ミリも触れません。「うっかりVPCを消してしまった」というインフラエンジニアの悪夢から解放されます。

—

まとめ:今日のまとめと次のステップ

今回は、Pulumiの Stack References を用いて、巨大モノリスインフラから脱却し、疎結合で安全なマイクロサービス基盤を構築する手法を解説しました。

  • Pulumi なら、TypeScriptの表現力を活かしてモダンなIaCができる。
  • Stack References を使えば、インフラストラクチャ間を安全なインターフェースで接続できる。
  • ネットワーク層とアプリケーション層を分離することで、変更影響範囲を最小化し、チームの生産性を爆発的に高められる。

これをマスターすれば、毎日のインフラ作業のストレスが嘘のように消え去り、「コードを書く楽しさ」が戻ってくるはずです。

さあ、次はあなたのプロジェクトのVPCとECS/EKSの構成を、この方式で美しく分割してみませんか?
あなたのSREライフが、より快適でエキサイティングなものになりますように。それではまた!

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