CoursesPulumiIntermediate

Component resources & reuse

Package infra into classes.

Intermediate12 min · lesson 7 of 12

A ComponentResource packages several resources into one reusable, higher-level building block — the Pulumi equivalent of a module, but expressed as a class. You subclass pulumi.ComponentResource, create the child resources in the constructor, parent them to the component, and expose a clean set of outputs. Consumers instantiate your class and get a whole vetted pattern (a bucket with logging, encryption, and public-access blocks) in one line.

securebucket.ts
export class SecureBucket extends pulumi.ComponentResource {
readonly bucket: aws.s3.BucketV2;
constructor(name: string, opts?: pulumi.ComponentResourceOptions) {
super("acme:storage:SecureBucket", name, {}, opts);
this.bucket = new aws.s3.BucketV2(name, {}, { parent: this });
new aws.s3.BucketServerSideEncryptionConfigurationV2(`${name}-enc`, {
bucket: this.bucket.id,
rules: [{ applyServerSideEncryptionByDefault: { sseAlgorithm: "aws:kms" } }],
}, { parent: this });
new aws.s3.BucketPublicAccessBlock(`${name}-block`, {
bucket: this.bucket.id, blockPublicAcls: true, blockPublicPolicy: true,
ignorePublicAcls: true, restrictPublicBuckets: true,
}, { parent: this });
this.registerOutputs({ bucketId: this.bucket.id });
}
}

Use it like any class

Now a secure bucket is a one-liner, and because it is real code you distribute it like any package — an npm/PyPI module your teams import. Components are how an organization encodes its golden paths: the secure, tagged, logged defaults become the easy option, so doing the right thing is less typing than doing the wrong thing.

index.ts
import { SecureBucket } from "./securebucket";
const logs = new SecureBucket("logs"); // encrypted + private by construction
const data = new SecureBucket("data");
Parent children to the component
Always pass { parent: this } when creating child resources in a component (and registerOutputs at the end). Without it, the resources are not associated with the component in state or the resource graph, which breaks the tree view, some replace/delete ordering, and aliasing. The parenting is what makes the component a real unit rather than loose resources.