Guide for authoring Pulumi ComponentResource classes. Use when creating reusable infrastructure components, designing component interfaces, setting up multi-language support, or distributing component packages.
Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.
Quelldateien prüfen
Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.
Mit Codex oder Claude installieren Kopieren Sie diesen Prompt, fügen Sie ihn in Codex, Claude oder einen anderen Assistant ein und lassen Sie die Skill-Seite prüfen und installieren.
Ein direkter Befehl überspringt den Prüf-Prompt. Prüfen Sie die Quelle, bevor Sie ihn ausführen.
Guide for authoring Pulumi ComponentResource classes. Use when creating reusable infrastructure components, designing component interfaces, setting up multi-language support, or distributing component packages.
Authoring Pulumi Components
A ComponentResource groups related infrastructure resources into a reusable, logical unit. Components make infrastructure easier to understand, reuse, and maintain. Components appear as a single node with children nested underneath in pulumi preview/pulumi up output and in the Pulumi Cloud console.
This skill covers the full component authoring lifecycle. For general Pulumi coding patterns (Output handling, secrets, aliases, preview workflows), use the pulumi-best-practices skill instead.
When to Use This Skill
Invoke this skill when:
Creating a new ComponentResource class
Designing the args interface for a component
Making a component consumable from multiple Pulumi languages
Publishing or distributing a component package
Refactoring inline resources into a reusable component
Debugging component behavior (missing outputs, stuck creating, children at wrong level)
Component Anatomy
Every component has four required elements:
Extend ComponentResource and call super() with a type URN
Accept standard parameters: name, args, and ComponentResourceOptions
Set parent: this on all child resources
Call registerOutputs() at the end of the constructor
TypeScript
import * as pulumi from"@pulumi/pulumi";
import * as aws from"@pulumi/aws";
interfaceStaticSiteArgs {
indexDocument?: pulumi.Input<string>;
errorDocument?: pulumi.Input<string>;
}
classStaticSiteextendspulumi.ComponentResource {
publicreadonlybucketName: pulumi.Output<string>;
publicreadonlywebsiteUrl: pulumi.Output<string>;
constructor(name: string, args: StaticSiteArgs, opts?: pulumi.ComponentResourceOptions) {
// 1. Call super with type URN: <package>:<module>:<type>super("myorg:index:StaticSite", name, {}, opts);
// 2. Create child resources with parent: thisconst bucket = new aws.s3.Bucket(`${name}-bucket`, {}, { parent: this });
const website = new aws.s3.BucketWebsiteConfigurationV2(`${name}-website`, {
bucket: bucket.id,
indexDocument: { suffix: args.indexDocument ?? "index.html" },
errorDocument: { key: args.errorDocument ?? "error.html" },
}, { parent: this });
// 3. Expose outputs as class propertiesthis.bucketName = bucket.id;
this.websiteUrl = website.websiteEndpoint;
// 4. Register outputs -- always the last linethis.registerOutputs({
bucketName: this.bucketName,
websiteUrl: this.websiteUrl,
});
}
}
// Usageconst site = newStaticSite("marketing", {
indexDocument: "index.html",
});
exportconst url = site.websiteUrl;
Accept explicit providers for multi-region or multi-account deployments. ComponentResourceOptions carries provider configuration to children automatically:
// Consumer passes a provider for a different regionconst usWest = new aws.Provider("us-west", { region: "us-west-2" });
const site = newStaticSite("west-site", { indexDocument: "index.html" }, {
providers: [usWest],
});
Children with { parent: this } automatically inherit the provider. No extra code is needed inside the component.
Multi-Language Components
If your component will be consumed from multiple Pulumi languages (TypeScript, Python, Go, C#, Java, YAML), package it as a multi-language component.
Do You Need Multi-Language?
Ask: "Will anyone consume this component from a different language than it was authored in?"
Single-language component (no packaging needed):
Your team uses one language and the component stays within that codebase
The component is internal to a single project or monorepo
No PulumiPlugin.yaml needed -- just import the class directly
Multi-language component (packaging required):
Other teams consume your component in different languages
Platform teams building abstractions for developers who choose their own language
YAML consumers need access -- even if you author in TypeScript, YAML programs require multi-language packaging to use your component
Building a shared component library for your organization
Publishing to the Pulumi private registry or public registry is a common reason, but not required for multi-language support
Common mistake: A TypeScript platform team builds components only their TypeScript users can consume. If application developers use Python or YAML, those components are invisible to them without multi-language packaging.
Setup
Create a PulumiPlugin.yaml in the component directory to declare the runtime:
runtime:nodejs
Or for Python:
runtime:python
Serialization Constraints
For multi-language compatibility, args must be serializable. These constraints apply regardless of the authoring language:
Allowed
Not Allowed
string, number, boolean
Union types (string | number)
Input<T> wrappers
Functions and callbacks
Arrays and maps of primitives
Complex nested generics
Enums
Platform-specific types
Consuming Multi-Language Components
Consumers install the component with pulumi package add, which automatically downloads the provider plugin, generates a local SDK in the consumer's language, and updates Pulumi.yaml:
# From a Git repository
pulumi package add <git-repo-url>
# From a specific version tag
pulumi package add <git-repo-url>@v1.0.0
For fresh checkouts or CI environments, run pulumi install to ensure all package dependencies are available. The consumer does not need to manually generate SDKs.
Authors who publish SDKs to package managers (npm, PyPI, etc.) can optionally use pulumi package gen-sdk to generate language-specific SDKs for publishing. Most component authors do not need this -- pulumi package add handles SDK generation on the consumer side.
Entry Points
Published multi-language components require an entry point that hosts the component provider process. The entry point pattern differs by language.
TypeScript (runtime: nodejs):
Export component classes from index.ts. No separate entry point file is needed. Pulumi introspects exported classes automatically.
// index.ts -- exports are the entry pointexport { StaticSite, StaticSiteArgs } from"./staticSite";
export { SecureBucket, SecureBucketArgs } from"./secureBucket";
Python (runtime: python):
Create a __main__.py that calls component_provider_host with all component classes:
from pulumi.provider.experimental import component_provider_host
from static_site import StaticSite
from secure_bucket import SecureBucket
if __name__ == "__main__":
component_provider_host(
name="my-components",
components=[StaticSite, SecureBucket],
)
Go (runtime: go):
Create a main.go that builds and runs the provider:
Choose a distribution method based on your audience:
Audience
Method
How
Same project
Direct import
Standard language import
Same organization
Private registry
pulumi package publish to Pulumi Cloud
Same organization
Git repository
pulumi package add <repo> with version tags
Language ecosystem
Package manager
Publish to npm, PyPI, NuGet, or Maven
Public community
Pulumi Registry
Submit via pulumi/registry GitHub repo
Pulumi Private Registry
The private registry is the centralized catalog for your organization's components. It provides automatic API documentation, version management, and discoverability for all teams.
Prerequisites: Configure GitHub OIDC integration with Pulumi Cloud before using this workflow.
The registry supports private GitHub and GitLab repositories. For non-OIDC setups, authenticate with GITHUB_TOKEN or GITLAB_TOKEN environment variables.
The private registry automatically generates SDK documentation for each published component. Enrich the generated docs by adding type annotations to your component's inputs and outputs (JSDoc in TypeScript, docstrings in Python, Annotate() methods in Go).