pulumi-typescript by dirien/claude-skills
npx skills add https://github.com/dirien/claude-skills --skill pulumi-typescript# 创建新的 TypeScript 项目
pulumi new typescript
# 或者使用特定云平台的模板
pulumi new aws-typescript
pulumi new azure-typescript
pulumi new gcp-typescript
项目结构:
my-project/
├── Pulumi.yaml
├── Pulumi.dev.yaml # 堆栈配置(使用 ESC 替代)
├── package.json
├── tsconfig.json
└── index.ts
使用 Pulumi ESC 进行集中式密钥和配置管理,而不是使用 pulumi config set 或堆栈配置文件。
将 ESC 环境链接到堆栈:
# 创建 ESC 环境
pulumi env init myorg/myproject-dev
# 编辑环境
pulumi env edit myorg/myproject-dev
# 链接到 Pulumi 堆栈
pulumi config env add myorg/myproject-dev
ESC 环境定义(YAML):
values:
# 静态配置
pulumiConfig:
aws:region: us-west-2
myapp:instanceType: t3.medium
# 用于 AWS 的动态 OIDC 凭据
aws:
login:
fn::open::aws-login:
oidc:
roleArn: arn:aws:iam::123456789:role/pulumi-oidc
sessionName: pulumi-deploy
# 从 AWS Secrets Manager 拉取密钥
secrets:
fn::open::aws-secrets:
region: us-west-2
login: ${aws.login}
get:
dbPassword:
secretId: prod/database/password
# 暴露给环境变量
environmentVariables:
AWS_ACCESS_KEY_ID: ${aws.login.accessKeyId}
AWS_SECRET_ACCESS_KEY: ${aws.login.secretAccessKey}
AWS_SESSION_TOKEN: ${aws.login.sessionToken}
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
基本资源创建:
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
// 从 ESC 获取配置
const config = new pulumi.Config();
const instanceType = config.require("instanceType");
// 使用适当的标签创建资源
const bucket = new aws.s3.Bucket("my-bucket", {
versioning: { enabled: true },
serverSideEncryptionConfiguration: {
rule: {
applyServerSideEncryptionByDefault: {
sseAlgorithm: "AES256",
},
},
},
tags: {
Environment: pulumi.getStack(),
ManagedBy: "Pulumi",
},
});
// 导出输出
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);
// 使用 { parent: this } 创建子资源
const lb = new aws.lb.LoadBalancer(`${name}-lb`, {
loadBalancerType: "application",
// ... 配置
}, { parent: this });
this.url = lb.dnsName;
this.registerOutputs({ url: this.url });
}
}
用于跨堆栈依赖的堆栈引用:
import * as pulumi from "@pulumi/pulumi";
// 引用网络堆栈的输出
const networkingStack = new pulumi.StackReference("myorg/networking/prod");
const vpcId = networkingStack.getOutput("vpcId");
const subnetIds = networkingStack.getOutput("privateSubnetIds");
处理 Outputs:
import * as pulumi from "@pulumi/pulumi";
// 使用 apply 进行转换
const uppercaseName = bucket.id.apply(id => id.toUpperCase());
// 使用 pulumi.all 处理多个输出
const combined = pulumi.all([bucket.id, bucket.arn]).apply(
([id, arn]) => `Bucket ${id} has ARN ${arn}`
);
// 条件性资源
const isProd = pulumi.getStack() === "prod";
const monitoring = isProd ? new aws.cloudwatch.MetricAlarm("alarm", {
// ... 配置
}) : undefined;
运行任何命令时注入 ESC 环境变量:
# 使用 ESC 凭据运行 pulumi 命令
pulumi env run myorg/aws-dev -- pulumi up
# 使用密钥运行测试
pulumi env run myorg/test-env -- npm test
# 打开环境并导出到 shell
pulumi env open myorg/myproject-dev --format shell
// 导出异步函数以使用顶级 await
export = async () => {
const data = await fetchExternalData();
const resource = new aws.s3.Bucket("bucket", {
tags: { data: data.value },
});
return {
bucketName: resource.id,
};
};
在 TypeScript 中创建可以从任何 Pulumi 语言(Python、Go、C#、Java、YAML)使用的组件。
多语言组件的项目结构:
my-component/
├── PulumiPlugin.yaml # 多语言必需
├── package.json
├── tsconfig.json
└── index.ts # 组件定义
PulumiPlugin.yaml:
runtime: nodejs
具有正确 Args 接口的组件:
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
// Args 接口 - 对所有属性使用 Input 类型
export interface SecureBucketArgs {
// 将所有标量成员包装在 Input 类型中
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>;
// 构造函数必须具有带类型注解的 'args' 参数
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,
});
}
}
发布以供多语言使用:
# 从 git 仓库使用
pulumi package add github.com/myorg/my-component
# 带版本标签
pulumi package add github.com/myorg/my-component@v1.0.0
# 本地开发
pulumi package add /path/to/local/my-component
多语言 Args 要求:
pulumi.Input<T>string | number)- 不支持args 参数遵循此经过验证的工作流以确保安全部署:
pulumi preview
查看输出以了解将创建、修改或删除哪些资源。
检查预览输出中的以下内容:
如果更改看起来不正确,请在继续之前调查根本原因:
# 检查当前堆栈状态
pulumi stack output
# 查看 ESC 环境值
pulumi env open myorg/myproject-dev
# 验证配置
pulumi config
验证后,部署更改:
pulumi up
成功部署后,确认输出:
pulumi stack output
将输出与预期值(例如,存储桶名称、端点 URL、资源 ID)进行比较。
如果 pulumi up 在部署过程中失败:
pulumi up — Pulumi 将从上次中断的地方恢复pulumi refresh 将状态与实际云资源同步pulumi up 之前始终运行 pulumi preview# 环境命令(pulumi env)
pulumi env init <org>/<project>/<env> # 创建环境
pulumi env edit <org>/<env> # 编辑环境
pulumi env open <org>/<env> # 查看解析后的值
pulumi env run <org>/<env> -- <command> # 使用环境变量运行
pulumi env version tag <org>/<env> <tag> # 标记版本
# Pulumi 命令
pulumi new typescript # 新项目
pulumi config env add <org>/<env> # 链接 ESC 环境
pulumi preview # 预览更改
pulumi up # 部署
pulumi stack output # 查看输出
pulumi destroy # 拆除
pulumi refresh # 与云同步状态
每周安装次数
76
仓库
GitHub 星标数
2
首次出现
2026年1月21日
安全审计
安装于
opencode65
gemini-cli65
codex64
github-copilot61
claude-code58
cursor52
# 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
Project structure:
my-project/
├── Pulumi.yaml
├── Pulumi.dev.yaml # Stack config (use ESC instead)
├── package.json
├── tsconfig.json
└── index.ts
Instead of using pulumi config set or stack config files, use Pulumi ESC for centralized secrets and configuration.
Link ESC environment to stack:
# 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 environment definition (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}
Basic resource creation:
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;
Component resources for reusability:
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 });
}
}
Stack references for cross-stack dependencies:
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");
Working with Outputs:
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;
Run any command with ESC environment variables injected:
# 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
// 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,
};
};
Create components in TypeScript that can be consumed from any Pulumi language (Python, Go, C#, Java, YAML).
Project structure for multi-language component:
my-component/
├── PulumiPlugin.yaml # Required for multi-language
├── package.json
├── tsconfig.json
└── index.ts # Component definition
PulumiPlugin.yaml:
runtime: nodejs
Component with proper Args interface:
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,
});
}
}
Publishing for multi-language consumption:
# Consume from git repository
pulumi package add github.com/myorg/my-component
# With version tag
pulumi package add github.com/myorg/my-component@v1.0.0
# Local development
pulumi package add /path/to/local/my-component
Multi-language Args requirements:
pulumi.Input<T> for all scalar propertiesstring | number) - not supportedargs parameter with type declarationFollow this validated workflow for safe deployments:
pulumi preview
Review the output to understand what resources will be created, modified, or deleted.
Check the preview output for:
If changes look incorrect, investigate the root cause before proceeding:
# Check current stack state
pulumi stack output
# Review ESC environment values
pulumi env open myorg/myproject-dev
# Verify configuration
pulumi config
Once validated, deploy the changes:
pulumi up
After successful deployment, confirm the outputs:
pulumi stack output
Compare outputs against expected values (e.g., bucket names, endpoint URLs, resource IDs).
If pulumi up fails mid-deployment:
pulumi up again — Pulumi will resume from where it left offpulumi refresh to sync state with actual cloud resourcespulumi preview before pulumi up# 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
Weekly Installs
76
Repository
GitHub Stars
2
First Seen
Jan 21, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
opencode65
gemini-cli65
codex64
github-copilot61
claude-code58
cursor52