pulumi-typescript について
TypeScriptでPulumiのインフラプロジェクトを作成・デプロイするためのスキルです。Pulumi ESCによる設定とシークレット管理、再利用可能なコンポーネント、スタック参照、プレビューと検証を経てデプロイする手順を扱います。
主な機能
- 01TypeScriptプロジェクトの設定とパターン
- 02Pulumi ESCによる設定とシークレット管理
- 03再利用可能な多言語コンポーネント
- 04スタック参照と出力の処理
- 05プレビュー、検証、デプロイの手順
活用シーン
- 01TypeScriptテンプレートでインフラプロジェクトを開始
- 02ESCでスタック設定と認証情報を管理
- 03Pulumiの複数言語で再利用可能なコンポーネントを共有
- 04デプロイ前にインフラ変更を確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ dirien/ claude-skills --skill pulumi-typescriptインストール後、Claude Code で/pulumi-typescriptを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
evals/evals.jsonreferences/pulumi-best-practices-aws.mdpulumi-best-practices-azure.mdpulumi-best-practices-gcp.mdpulumi-esc.mdpulumi-patterns.mdpulumi-typescript.md詳細
Pulumi TypeScript スキル
開発ワークフロー
1. プロジェクトのセットアップ
# Create new TypeScript project
pulumi new typescript
# Or with a cloud-specific template
pulumi new aws-typescript
pulumi new azure-typescript
pulumi new gcp-typescript
プロジェクト構成:
my-project/
├── Pulumi.yaml
├── Pulumi.dev.yaml # Stack config (use ESC instead)
├── package.json
├── tsconfig.json
└── index.ts
2. Pulumi ESC との統合
pulumi config set やスタック設定ファイルを使う代わりに、シークレットと設定を一元管理するために Pulumi ESC を使用します。
ESC 環境をスタックにリンクする:
# Create ESC environment
pulumi env init myorg/myproject-dev
# Edit environment
pulumi env edit myorg/myproject-dev
# Link to Pulumi stack
pulumi config env add myorg/myproject-dev
ESC 環境の定義(YAML):
values:
# Static configuration
pulumiConfig:
aws:region: us-west-2
myapp:instanceType: t3.medium
# Dynamic OIDC credentials for AWS
aws:
login:
fn::open::aws-login:
oidc:
roleArn: arn:aws:iam::123456789:role/pulumi-oidc
sessionName: pulumi-deploy
# Pull secrets from AWS Secrets Manager
secrets:
fn::open::aws-secrets:
region: us-west-2
login: ${aws.login}
get:
dbPassword:
secretId: prod/database/password
# Expose to environment variables
environmentVariables:
AWS_ACCESS_KEY_ID: ${aws.login.accessKeyId}
AWS_SECRET_ACCESS_KEY: ${aws.login.secretAccessKey}
AWS_SESSION_TOKEN: ${aws.login.sessionToken}
3. TypeScript のパターン
基本的なリソースの作成:
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
// Get configuration from ESC
const config = new pulumi.Config();
const instanceType = config.require("instanceType");
// Create resources with proper tagging
const bucket = new aws.s3.Bucket("my-bucket", {
versioning: { enabled: true },
serverSideEncryptionConfiguration: {
rule: {
applyServerSideEncryptionByDefault: {
sseAlgorithm: "AES256",
},
},
},
tags: {
Environment: pulumi.getStack(),
ManagedBy: "Pulumi",
},
});
// Export outputs
export const bucketName = bucket.id;
export const bucketArn = bucket.arn;
再利用可能なコンポーネントリソース:
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
interface WebServiceArgs {
port: pulumi.Input<number>;
imageUri: pulumi.Input<string>;
}
class WebService extends pulumi.ComponentResource {
public readonly url: pulumi.Output<string>;
constructor(name: string, args: WebServiceArgs, opts?: pulumi.ComponentResourceOptions) {
super("custom:app:WebService", name, {}, opts);
// Create child resources with { parent: this }
const lb = new aws.lb.LoadBalancer(`${name}-lb`, {
loadBalancerType: "application",
// ... configuration
}, { parent: this });
this.url = lb.dnsName;
this.registerOutputs({ url: this.url });
}
}
スタック間の依存関係に対するスタック参照:
import * as pulumi from "@pulumi/pulumi";
// Reference outputs from networking stack
const networkingStack = new pulumi.StackReference("myorg/networking/prod");
const vpcId = networkingStack.getOutput("vpcId");
const subnetIds = networkingStack.getOutput("privateSubnetIds");
Output の操作:
import * as pulumi from "@pulumi/pulumi";
// Use apply for transformations
const uppercaseName = bucket.id.apply(id => id.toUpperCase());
// Use pulumi.all for multiple outputs
const combined = pulumi.all([bucket.id, bucket.arn]).apply(
([id, arn]) => `Bucket ${id} has ARN ${arn}`
);
// Conditional resources
const isProd = pulumi.getStack() === "prod";
const monitoring = isProd ? new aws.cloudwatch.MetricAlarm("alarm", {
// ... configuration
}) : undefined;
4. pulumi env run で ESC を使用する
ESC 環境変数を注入して、任意のコマンドを実行します。
# Run pulumi commands with ESC credentials
pulumi env run myorg/aws-dev -- pulumi up
# Run tests with secrets
pulumi env run myorg/test-env -- npm test
# Open environment and export to shell
pulumi env open myorg/myproject-dev --format shell
5. 非同期パターン
// Export async function for top-level await
export = async () => {
const data = await fetchExternalData();
const resource = new aws.s3.Bucket("bucket", {
tags: { data: data.value },
});
return {
bucketName: resource.id,
};
};
6. マルチ言語コンポーネント
任意の Pulumi 言語(Python、Go、C#、Java、YAML)から利用できるコンポーネントを TypeScript で作成します。
マルチ言語コンポーネントのプロジェクト構成:
my-component/
├── PulumiPlugin.yaml # Required for multi-language
├── package.json
├── tsconfig.json
└── index.ts # Component definition
PulumiPlugin.yaml:
runtime: nodejs
適切な Args インターフェースを備えたコンポーネント:
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
// Args interface - use Input types for all properties
export interface SecureBucketArgs {
// Wrap all scalar members in Input types
bucketName: pulumi.Input<string>;
enableVersioning?: pulumi.Input<boolean>;
tags?: pulumi.Input<Record<string, pulumi.Input<string>>>;
}
export class SecureBucket extends pulumi.ComponentResource {
public readonly bucketId: pulumi.Output<string>;
public readonly bucketArn: pulumi.Output<string>;
// Constructor must have 'args' parameter with type annotation
constructor(name: string, args: SecureBucketArgs, opts?: pulumi.ComponentResourceOptions) {
super("myorg:storage:SecureBucket", name, {}, opts);
const bucket = new aws.s3.Bucket(`${name}-bucket`, {
bucket: args.bucketName,
versioning: { enabled: args.enableVersioning ?? true },
serverSideEncryptionConfiguration: {
rule: {
applyServerSideEncryptionByDefault: {
sseAlgorithm: "AES256",
},
},
},
tags: args.tags,
}, { parent: this });
this.bucketId = bucket.id;
this.bucketArn = bucket.arn;
this.registerOutputs({
bucketId: this.bucketId,
bucketArn: this.bucketArn,
});
}
}
マルチ言語で利用できるように公開する:
# Consume from git repository
pulumi package add github.com/myorg/my-component
# With version tag
pulumi package add github.com/myorg/[email protected]
# Local development
pulumi package add /path/to/local/my-component
マルチ言語 Args の要件:
- すべてのスカラー型プロパティに
pulumi.Input<T>を使用する - 共用体型(
string | number)はサポートされていないため、使用しない - 関数やコールバックはシリアライズできないため、使用しない
- コンストラクターには型宣言付きの
argsパラメーターが必要
検証を伴うデプロイワークフロー
安全にデプロイするため、以下の検証済みワークフローに従います。
1. 変更をプレビューする
pulumi preview
出力を確認し、作成、変更、削除されるリソースを把握します。
2. 変更を検証する
プレビューの出力で以下を確認します。
- 想定外のリソースの削除や変更がないこと
- リソースの数と種類が正しいこと
- 設定値(リージョン、インスタンスタイプ、タグなど)が適切であること
変更内容に問題がある場合は、先に根本原因を調査します。
# Check current stack state
pulumi stack output
# Review ESC environment values
pulumi env open myorg/myproject-dev
# Verify configuration
pulumi config
3. デプロイする
検証が完了したら、変更をデプロイします。
pulumi up
4. Output を確認する
デプロイが成功したら、Output を確認します。
pulumi stack output
Output を期待値(バケット名、エンドポイント URL、リソース ID など)と比較します。
エラーからの復旧
pulumi up がデプロイの途中で失敗した場合:
- エラーメッセージで、失敗した特定のリソースを確認する
- リソースの設定と ESC 環境の値を確認する
- 根本的な問題(IAM 権限や無効な設定など)を修正する
pulumi upを再度実行する — Pulumi は中断した箇所から再開します- スタックの状態に一貫性がない場合は、
pulumi refreshを使用して、実際のクラウドリソースと状態を同期する
ベストプラクティス
セキュリティ
- すべてのシークレットに Pulumi ESC を使用し、スタック設定ファイルにシークレットをコミットしない
- 静的な認証情報ではなく、OIDC 認証を有効にする
- 可能な場合は、有効期間の短い動的シークレットを使用する
- 最小権限の IAM ポリシーを適用する
- S3 バケットでは必ずサーバー側の暗号化(AES256 または KMS)を有効にする — これは必須のデフォルトです
- 明示的に必要な場合を除き、S3 バケットへのパブリックアクセスをブロックする
- データ保護のため、ストレージリソースでバージョニングを有効にする
コードの構成
- 再利用可能なインフラストラクチャパターンには ComponentResources を使用する
- 設定の検証に TypeScript の型システムを活用する
- スタック固有の設定は ESC 環境に保持する
- スタック間の依存関係にはスタック参照を使用する
デプロイ
pulumi upの前には必ずpulumi previewを実行する- リリースには ESC 環境のバージョニングとタグを使用する
- すべてのリソースに適切なタグ付け戦略を適用する
よく使うコマンド
# Environment Commands (pulumi env)
pulumi env init <org>/<project>/<env> # Create environment
pulumi env edit <org>/<env> # Edit environment
pulumi env open <org>/<env> # View resolved values
pulumi env run <org>/<env> -- <command> # Run with env vars
pulumi env version tag <org>/<env> <tag> # Tag version
# Pulumi Commands
pulumi new typescript # New project
pulumi config env add <org>/<env> # Link ESC environment
pulumi preview # Preview changes
pulumi up # Deploy
pulumi stack output # View outputs
pulumi destroy # Tear down
pulumi refresh # Sync state with cloud
参考資料
- references/pulumi-esc.md - ESC のパターンとコマンド
- references/pulumi-patterns.md - 一般的なインフラストラクチャのパターン
- references/pulumi-typescript.md - TypeScript 固有のガイダンス
- references/pulumi-best-practices-aws.md - AWS のベストプラクティス
- references/pulumi-best-practices-azure.md - Azure のベストプラクティス
- references/pulumi-best-practices-gcp.md - GCP のベストプラクティス