こんにちは!インフラストラクチャーの世界へようこそ。
クラウドの規模が大きくなるにつれ、「すべてのリソースにセキュリティタグを付け忘れない」「本番環境のストレージは必ず暗号化する」といったガバナンスの維持に頭を悩ませていませんか?
今回は、Pulumiの秘儀「Transforms(トランスフォーム)」を使って、開発者がうっかりミスをしても「自動的に安全な設定が強制されるインフラ基盤」を作る方法を解説します。
これをマスターすれば、面倒なコードレビューや「タグ付けして!」というリマインドの嵐から解放され、毎日のインフラ管理が劇的に楽になりますよ。さあ、一緒に深淵を覗いてみましょう。
—
1. PulumiのTransforms機能とは?(CrossGuardとの違い)
まず、「Policy as Code」といえばPulumiには CrossGuard(Policy Pack) という強力な仕組みがあります。これは「ルール違反のコードを検知してデプロイをブロックする」警察官のような役割をします。
一方、今回解説する Transforms は、いわば「錬金術師」です。
開発者が書いたリソースの定義(TypeScriptなどのコード)がPulumi Engineに評価される直前にフックし、コードを書き換えることなく、自動的にプロパティ(タグや暗号化設定など)を注入・上書きしてしまいます。
[開発者のコード]
↓
(Transforms) ← ★ここで自動的にセキュリティ設定を注入!
↓
[Pulumi Engine] → [クラウドプロバイダ (AWS/GCP/Azure)]
- CrossGuard: 「ダメなコードは通さない!」(検知・ブロック)
- Transforms: 「コードはそのまま、裏で完璧に直しておくよ!」(自動修復・強制注入)
開発者の体験を損なわずにセキュリティを強制するなら、Transformsが圧倒的に優れています。
—
2. 基礎セットアップ:環境の準備
まずは、手元で動かせるように最小限のPulumi(TypeScript)環境を準備しましょう。すでにPulumi CLIとNode.jsが入っている前提で進めます。
適当なディレクトリを作り、プロジェクトを初期化します。
mkdir pulumi-transforms-demo
cd pulumi-transforms-demo
pulumi new aws-typescript –dir . –yes
これでTypeScriptベースのAWS用Pulumiプロジェクトが生成されます。
—
3. すべてのリソースにタグと暗号化を注入するTypeScript実装
ここからが本番です。`index.ts` を開き、Transformsを使って「すべてのS3バケットとEC2インスタンス(およびタグをサポートする全リソース)」に強制的にタグと暗号化を付与するコードを実装します。
以下のコードに書き換えてください。
import as pulumi from “@pulumi/pulumi”;
import as aws from “@pulumi/aws”;
// ==========================================
// 1. Transformsの定義(ここが今回の心臓部)
// ==========================================
// プロジェクト全体のスタックに適用するグローバルなTransform
pulumi.runtime.registerStackTransformation(args => {
// args.type にはリソースの種類(例: “aws:s3/bucket:Bucket”)が入ります
// args.props には開発者が指定したプロパティが入っています
// 例1: タグをサポートする全てのリソースに、共通タグを強制付与する
if (args.props.tags) {
args.props.tags = {
…args.props.tags,
“ManagedBy”: “Pulumi”,
“Environment”: pulumi.getStack(), // “dev” や “prod” が自動で入る
“ComplianceChecked”: “true”,
};
} else {
// 開発者がタグを書き忘れても、強制的に追加する
args.props.tags = {
“ManagedBy”: “Pulumi”,
“Environment”: pulumi.getStack(),
“ComplianceChecked”: “true”,
};
}
// 例2: S3バケットの場合、強制的にサーバーサイド暗号化(SSE-S3)をデフォルト有効にする
if (args.type === “aws:s3/bucket:Bucket”) {
// 開発者が暗号化設定を書いていなくても強制注入
if (!args.props.serverSideEncryptionConfiguration) {
args.props.serverSideEncryptionConfiguration = {
rule: {
applyServerSideEncryptionByDefault: {
sseAlgorithm: “AES256”,
},
},
};
console.log(`[Security Policy] S3 Bucket ‘${args.name}’ にデフォルト暗号化を強制適用しました。`);
}
}
// 変換されたプロパティと、必要であればリソース名を返却
return {
props: args.props,
opts: args.opts,
};
});
// ==========================================
// 2. 開発者が書くインフラコード(非常にシンプル)
// ==========================================
// 開発者は暗号化やタグの記述を一切気にせず、ただバケットを作るだけでOK!
const myBucket = new aws.s3.Bucket(“my-secure-bucket”, {
// あえて暗号化も共通タグも書いていません
});
// エクスポートして確認できるようにする
export const bucketName = myBucket.id;
—
4. 動作確認:何が起きているか?
それでは、このコードをプレビューしてみましょう。
pulumi preview
コンソール出力を見ると、次のようなログが出力されます(※Transforms内の`console.log`)。
`[Security Policy] S3 Bucket ‘my-secure-bucket’ にデフォルト暗号化を強制適用しました。`
そして、実際のAWSリソースの計画(Plan)を細かく見てみると、開発者が書いていないにもかかわらず以下の設定が自動で追加されていることがわかります。
1. `tags` に `ManagedBy: Pulumi` や `Environment: dev` が付与されている。
2. `serverSideEncryptionConfiguration` が自動で埋め込まれている。
これがTransformsの魔力です。
—
5. 開発者が意識せずにセキュアなインフラを構築できる仕組み
この手法の本質は、「セキュリティの担保を人間の注意力に依存させないこと」にあります。
- 開発者へのメリット: 面倒なタグ付けの規定を覚える必要も、暗号化ボイラープレートをコピペする必要もありません。ただ作りたいリソースを書くだけで、勝手にセキュアになります。
- SRE / プラットフォームチームへのメリット: 「全社セキュリティポリシーに準拠しているか」をコードベースで100%強制できます。監査の際にも「Transforms層で全リソースの暗号化とタグ付けを義務付けています」と胸を張って言えます。
さらに応用として、環境名(`pulumi.getStack()`)に応じて本番環境(`prod`)のときだけ強力な暗号化キー(KMS)を強制したり、パブリックアクセスをブロックする設定を差し込むことも自由自在です。
—
まとめ
PulumiのTransforms機能、いかがでしたでしょうか?
「インフラのコード化」から一歩進んだ、「インフラ統制の自動化」を実現するためのマストスキルです。
これを導入すれば、あなたのチームの開発スピードを一切落とすことなく、クラウド環境のセキュリティとコンプライアンスを鉄壁のものにできます。ぜひ、次のプロジェクトの基盤コードに組み込んでみてください。あなたの毎日のSREライフが、より快適でエキサイティングなものになることを願っています!