Pulumiで極めるエフェメラル環境:Pull Request駆動による「消せるインフラ」の深淵
インフラを「管理する」時代は終わった。これからは「エフェメラル(一時的)に生成し、役目を終えたら塵一つ残さず消し去る」のが、真のDevOpsにおける正義だ。
Terraformの「計画と適用」の分離による非同期的な状態管理に苛立ちを感じたことはないか? Pulumiは、TypeScriptやGoといった汎用言語を操ることで、インフラを「ソフトウェア」として昇華させる。今回は、Pull Request(PR)ごとに本番と同等の環境を動的に立ち上げ、マージと同時に強制的に破棄する、ゼロトラスト志向のエフェメラル・アーキテクチャの極致を解説する。
—
1. なぜ「Pulumi」でなければならないのか
TerraformのHCLは宣言的だが、複雑な条件分岐や、動的な依存解決には限界がある。Pulumiの真髄は、「スタック(Stack)の動的プログラミング」にある。
エフェメラル環境を構築する際、最大の敵は「状態の汚染」と「リソースのゾンビ化」だ。Pulumiは、独自のState管理(Pulumi ServiceまたはセルフホストのS3/GCSバックエンド)により、CIの実行コンテキストを直接インフラのライフサイクルにバインドできる。
2. アーキテクチャ設計:Ephemeral Lifecycle Manager
GitHub ActionsとPulumiを組み合わせ、以下のフローを実装する。
1. PR作成時: `pulumi up –yes` で独立したスタック(例: `env/pr-123`)をデプロイ。
2. 追従更新: PRへのPush毎に `pulumi up` で差分適用。
3. PRマージ/クローズ時: `pulumi destroy –yes` で全リソースを即時破棄。
核心:Stackの自動生成と動的命名
スタック名はPR番号に依存させるのが定石だ。これにより、名前空間の衝突を物理的に防ぐ。
// pulumi-infra/index.ts
import as pulumi from “@pulumi/pulumi”;
// 環境識別子を取得(GitHub Actionsの環境変数を利用)
const prNumber = process.env.GITHUB_PR_NUMBER;
const stackName = pulumi.getStack(); // 例: “staging-pr-123”
if (!prNumber) {
throw new Error(“PR番号が特定できません。CIコンテキストを確認してください。”);
}
// リソース名のプレフィックスを動的生成
// これにより、同一アカウント内でも複数PRが共存可能になる
const resourcePrefix = `ephemeral-${prNumber}`;
// 例:AWS Security Groupの作成
const sg = new aws.ec2.SecurityGroup(`${resourcePrefix}-sg`, {
description: “Ephemeral environment SG”,
ingress: [{ protocol: “tcp”, fromPort: 80, toPort: 80, cidrBlocks: [“0.0.0.0/0”] }]
});
—
3. 高度な最適化ハック:パフォーマンスとコストの制圧
A. プロバイダのメモリ効率化
Pulumiは実行時に言語ランタイム(Node.jsなど)を立ち上げる。大規模なスタックではメモリ消費が懸念されるが、`pulumi.runtime.setMocks` を活用したユニットテストをCIパイプラインの初期段階に組み込み、無駄なAPI呼び出しを事前に弾け。
B. ステートの分離による「完全なクリーンアップ」
リソースの孤立を防ぐため、「Destroy-on-Exit」パターンをパイプラインに強制する。`on: pull_request: types: [closed]` トリガーを設定し、マージ時には必ず `pulumi destroy` を実行する。
.github/workflows/cleanup.yml
jobs:
cleanup:
runs-on: ubuntu-latest
steps:
- uses: pulumi/actions@v4
- name: Destroy Ephemeral Stack
run: |
pulumi stack select staging-pr-${{ github.event.pull_request.number }}
pulumi destroy –yes –remove # Stateファイルごと削除して痕跡を消す
—
4. ゼロトラストを実現する「最小権限」の動的注入
エフェメラル環境の最大の脆弱性は、環境構築用の認証情報が永続化されることだ。これを回避するため、OIDC(OpenID Connect)を利用した短命トークンを採用する。
- GitHub ActionsがAWS/GCPのIAMロールをAssumeRoleする際、`sub`(Subject)クレームにPR番号を含めることで、そのスタックにしかアクセスできないIAMポリシーを動的に生成・適応させる。
—
5. 伝説的なエンジニアからの提言:破壊を恐れるな
多くの現場がエフェメラル環境の導入で失敗するのは、「手動で修正したリソース」が残ってしまうからだ。
1. Immutability(不変性)の遵守: Pulumiのコードで定義されていないリソースは、手動であっても一切許容しない。CI/CDで `pulumi refresh` を実行し、ドリフト(乖離)を検知した瞬間にビルドを失敗させる厳格なガバナンスが必要だ。
2. コストの可視化: Pulumiの `transformation` 機能を使用し、すべてのリソースに `CreatedBy: PR-123` というタグを自動付与せよ。コストセンターが不明なリソースは即座に削除する、という自動化された「インフラの掃除屋」を実装せよ。
結論:コードがインフラを支配する
Pulumiによるエフェメラル環境の構築は、単なる自動化ではない。「環境は使い捨てるもの」という思想の体現だ。PRという最小単位で破壊と構築を繰り返すことで、エンジニアは「環境構築の失敗」という恐怖から解放される。
次世代のインフラは、誰かがポチポチと設定するものではなく、コードが自ら生まれ、使命を終えたら自ら消えゆく、静かなる自律システムであるべきだ。さあ、今すぐコードを書き、クラウドの荒野に動的な聖域を築け。