AgentSkillsCN

pulumi

在使用 TypeScript、Python、Go 或 C# 编写 Pulumi 程序以构建云基础设施时使用。涵盖资源声明、堆栈、输出、组件资源以及预览/更新工作流。 适用场景:使用 TypeScript/Python/Go/C# 进行基础设施建设、命令式 IaC、Pulumi 堆栈、组件资源 不适用场景:声明式 HCL 基础的 IaC(应使用 Terraform)、仅限 Azure 的 Bicep DSL(应使用 Bicep)、Kubernetes 清单(应使用 Kubernetes)

SKILL.md
--- frontmatter
name: pulumi
description: |
  Use when writing Pulumi programs for cloud infrastructure using TypeScript, Python, Go, or C#. Covers resource declarations, stacks, Outputs, component resources, and preview/up workflow.
  USE FOR: infrastructure in TypeScript/Python/Go/C#, imperative IaC, Pulumi stacks, component resources
  DO NOT USE FOR: declarative HCL-based IaC (use terraform), Azure-only Bicep DSL (use bicep), Kubernetes manifests (use kubernetes)
license: MIT
metadata:
  displayName: "Pulumi"
  author: "Tyler-R-Kendrick"
compatibility: claude, copilot, cursor

Pulumi

Overview

Pulumi is an open-source IaC platform that lets you define cloud infrastructure using general-purpose programming languages (TypeScript, Python, Go, C#, Java). Unlike HCL-based tools, you get full IDE support, loops, conditionals, type checking, and package management.

TypeScript Example

typescript
import * as aws from "@pulumi/aws";
import * as pulumi from "@pulumi/pulumi";

const config = new pulumi.Config();
const environment = config.require("environment");

const bucket = new aws.s3.Bucket("assets", {
  bucket: `my-app-${environment}-assets`,
  tags: { Environment: environment },
});

const bucketVersioning = new aws.s3.BucketVersioningV2("assets-versioning", {
  bucket: bucket.id,
  versioningConfiguration: { status: "Enabled" },
});

export const bucketArn = bucket.arn;

Python Example

python
import pulumi
import pulumi_aws as aws

config = pulumi.Config()
environment = config.require("environment")

bucket = aws.s3.Bucket("assets",
    bucket=f"my-app-{environment}-assets",
    tags={"Environment": environment},
)

pulumi.export("bucket_arn", bucket.arn)

Workflow

bash
# Create a new project
pulumi new aws-typescript

# Preview changes
pulumi preview

# Deploy changes
pulumi up

# Destroy resources
pulumi destroy

# Switch stacks (environments)
pulumi stack select prod

Outputs and Apply

Pulumi resources return Output<T> values (resolved asynchronously):

typescript
// Outputs are lazy — use .apply() to transform
const url = bucket.websiteEndpoint.apply(ep => `https://${ep}`);

// Use pulumi.interpolate for string interpolation
const name = pulumi.interpolate`app-${bucket.id}`;

// Use pulumi.all to combine multiple outputs
const combined = pulumi.all([bucket.arn, bucket.id]).apply(
  ([arn, id]) => `${arn} (${id})`
);

Component Resources

Create reusable infrastructure abstractions:

typescript
class StaticSite extends pulumi.ComponentResource {
  public readonly url: pulumi.Output<string>;

  constructor(name: string, args: { domain: string }, opts?: pulumi.ComponentResourceOptions) {
    super("custom:StaticSite", name, {}, opts);

    const bucket = new aws.s3.Bucket(`${name}-bucket`, {
      website: { indexDocument: "index.html" },
    }, { parent: this });

    this.url = bucket.websiteEndpoint;
    this.registerOutputs({ url: this.url });
  }
}

Stack Configuration

bash
# Set config values
pulumi config set environment prod
pulumi config set --secret dbPassword s3cret

# Access in code
const config = new pulumi.Config();
const env = config.require("environment");
const dbPass = config.requireSecret("dbPassword");

State Backends

BackendDescription
Pulumi CloudDefault managed backend with collaboration features
S3pulumi login s3://my-bucket
Azure Blobpulumi login azblob://container
Localpulumi login --local

Best Practices

  • Always run pulumi preview before pulumi up to review changes.
  • Use ComponentResource classes for reusable infrastructure patterns.
  • Never call .apply() on Outputs when pulumi.interpolate suffices.
  • Use pulumi.Config for environment-specific values and secrets.
  • Use stack references for cross-stack dependencies instead of hardcoded values.
  • Pin provider package versions in package.json / requirements.txt.
  • Use aliases when renaming resources to avoid delete-and-recreate.