CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-pulumi--pulumi

Pulumi's Node.js SDK for infrastructure-as-code platform that allows you to create, deploy, and manage infrastructure using familiar programming languages and tools.

85

1.02x
Overview
Eval results
Files

resource-management.mddocs/

Resource Management

Pulumi's resource management system provides the foundation for creating, managing, and organizing cloud infrastructure resources with automatic dependency tracking and lifecycle management.

Core Resource Classes

abstract class Resource {
  readonly urn: Output<string>;
  readonly __pulumiResource: boolean;
  
  protected constructor(type: string, name: string, opts?: ResourceOptions);
}

class CustomResource extends Resource {
  readonly id: Output<ID>;
  readonly __pulumiCustomResource: boolean;
  
  protected constructor(type: string, name: string, props?: any, opts?: CustomResourceOptions);
}

class ProviderResource extends CustomResource {
  readonly pkg: string;
  readonly __pulumiProviderResource: boolean;
  
  protected constructor(pkg: string, name: string, props?: any, opts?: CustomResourceOptions);
}

class ComponentResource<TData = any> extends Resource {
  readonly __pulumiComponentResource: boolean;
  
  protected constructor(type: string, name: string, opts?: ComponentResourceOptions);
  
  registerOutputs(outputs?: Inputs | Promise<Inputs> | Output<Inputs>): void;
}

Resource Options

interface ResourceOptions {
  // Dependency management
  dependsOn?: Input<Input<Resource>[]> | Input<Resource>;
  parent?: Resource;
  
  // Lifecycle options
  protect?: boolean;
  ignoreChanges?: string[];
  deleteBeforeReplace?: boolean;
  replaceOnChanges?: string[];
  retainOnDelete?: boolean;
  deletedWith?: Resource;
  
  // Provider options
  provider?: ProviderResource;
  providers?: Record<string, ProviderResource>;
  version?: string;
  pluginDownloadURL?: string;
  
  // Aliasing and transformation
  aliases?: Input<Alias[]>;
  customTimeouts?: CustomTimeouts;
  transformations?: ResourceTransformation[];
  transforms?: ResourceTransform[];
  hooks?: ResourceHook[];
}

interface CustomResourceOptions extends ResourceOptions {
  id?: Input<ID>;
  import?: Input<string>;
  importId?: Input<ID>;
}

interface ComponentResourceOptions extends ResourceOptions {
  // ComponentResource-specific options
}

Resource Lifecycle Types

interface Alias {
  name?: Input<string>;
  type?: Input<string>;
  parent?: Input<Resource>;
  stack?: Input<string>;
  project?: Input<string>;
}

interface CustomTimeouts {
  create?: Input<string>;
  update?: Input<string>;
  delete?: Input<string>;
}

type ID = string;
type URN = string;

Transformation System

type ResourceTransform = (args: ResourceTransformArgs) => Promise<ResourceTransformResult | undefined> | ResourceTransformResult | undefined;

interface ResourceTransformArgs {
  type: string;
  name: string;
  props: Inputs;
  opts: ResourceOptions;
}

interface ResourceTransformResult {
  props?: Inputs;
  opts?: ResourceOptions;
}

// Legacy transformation system (deprecated)
type ResourceTransformation = (args: ResourceTransformationArgs) => Promise<ResourceTransformationResult | undefined> | ResourceTransformationResult | undefined;

Hook System

class ResourceHook {
  constructor(options: ResourceHookOptions);
}

interface ResourceHookOptions {
  before?: ResourceHookFunction;
  after?: ResourceHookFunction;
}

type ResourceHookFunction = (args: ResourceHookArgs) => Promise<void> | void;

interface ResourceHookArgs {
  type: string;
  name: string;
  props: Inputs;
  opts: ResourceOptions;
  resource: Resource;
}

Utility Functions

function createUrn(name: Input<string>, type: Input<string>, parent?: Resource, project?: string, stack?: string): Output<string>;
function allAliases(name: string, aliases: Input<Alias[]> | undefined, parent: Resource | undefined): Output<string>[];
function mergeOptions(opts1?: ResourceOptions, opts2?: ResourceOptions): ResourceOptions;
function parseResourceReference(ref: string): { urn: string; id?: string; packageVersion?: string };
function pkgFromType(type: string): string;
function resourceType(res: Resource): string;
function resourceName(res: Resource): string;

Usage Examples

Basic Resource Creation

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

// Simple resource creation
const bucket = new aws.s3.Bucket("my-bucket", {
  acl: "private",
  versioning: {
    enabled: true,
  },
});

// Resource with explicit dependencies
const role = new aws.iam.Role("lambda-role", {
  assumeRolePolicy: JSON.stringify({
    Version: "2012-10-17",
    Statement: [{
      Effect: "Allow",
      Principal: { Service: "lambda.amazonaws.com" },
      Action: "sts:AssumeRole",
    }],
  }),
});

const lambda = new aws.lambda.Function("my-lambda", {
  code: new pulumi.asset.AssetArchive({
    ".": new pulumi.asset.FileArchive("./lambda"),
  }),
  role: role.arn, // Automatic dependency
  handler: "index.handler",
  runtime: "nodejs18.x",
}, {
  dependsOn: [role], // Explicit dependency
});

Resource Options

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

// Resource with comprehensive options
const database = new aws.rds.Instance("prod-db", {
  engine: "postgres",
  instanceClass: "db.t3.micro",
  allocatedStorage: 20,
  dbName: "myapp",
  username: "admin",
  password: new pulumi.Config().requireSecret("dbPassword"),
}, {
  // Lifecycle protection
  protect: true,
  
  // Ignore changes to specific properties
  ignoreChanges: ["password"],
  
  // Custom timeout
  customTimeouts: {
    create: "30m",
    update: "20m",
    delete: "10m",
  },
  
  // Replace on specific property changes
  replaceOnChanges: ["engine", "instanceClass"],
  
  // Retain on delete
  retainOnDelete: true,
});

Component Resources

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

interface WebsiteArgs {
  domain: string;
  indexContent: string;
}

class Website extends pulumi.ComponentResource {
  public readonly bucketName: pulumi.Output<string>;
  public readonly websiteUrl: pulumi.Output<string>;
  
  constructor(name: string, args: WebsiteArgs, opts?: pulumi.ComponentResourceOptions) {
    super("custom:Website", name, {}, opts);
    
    // Create child resources
    const bucket = new aws.s3.Bucket(`${name}-bucket`, {
      website: {
        indexDocument: "index.html",
      },
    }, { parent: this });
    
    const indexObject = new aws.s3.BucketObject(`${name}-index`, {
      bucket: bucket.id,
      key: "index.html",
      content: args.indexContent,
      contentType: "text/html",
    }, { parent: this });
    
    // Set outputs
    this.bucketName = bucket.id;
    this.websiteUrl = bucket.websiteEndpoint;
    
    // Register outputs for the component
    this.registerOutputs({
      bucketName: this.bucketName,
      websiteUrl: this.websiteUrl,
    });
  }
}

// Use the component
const website = new Website("my-website", {
  domain: "example.com",
  indexContent: "<h1>Hello World</h1>",
});

Resource Transformations

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

// Global transformation to add common tags
const addCommonTags: pulumi.ResourceTransform = (args) => {
  if (args.type.startsWith("aws:")) {
    return {
      props: {
        ...args.props,
        tags: {
          ...args.props.tags,
          Environment: "production",
          ManagedBy: "pulumi",
          Project: pulumi.getProject(),
        },
      },
      opts: args.opts,
    };
  }
  return undefined;
};

// Apply transformation to specific resources
const bucket = new aws.s3.Bucket("my-bucket", {
  acl: "private",
}, {
  transforms: [addCommonTags],
});

// Or apply globally via stack options
const stack = new pulumi.ComponentResource("MyStack", "my-stack", {}, {
  transforms: [addCommonTags],
});

Resource Hooks

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

// Create hooks for monitoring resource creation
const loggingHook = new pulumi.ResourceHook({
  before: (args) => {
    console.log(`Creating resource: ${args.type}:${args.name}`);
  },
  after: (args) => {
    console.log(`Created resource: ${args.type}:${args.name}`);
  },
});

const bucket = new aws.s3.Bucket("my-bucket", {
  acl: "private",
}, {
  hooks: [loggingHook],
});

Resource Aliases

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

// Handle resource renames with aliases
const bucket = new aws.s3.Bucket("my-new-bucket", {
  acl: "private",
}, {
  aliases: [
    { name: "my-old-bucket" },
    { name: "my-very-old-bucket", type: "aws:s3/bucket:Bucket" },
  ],
});

Resource Import

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

// Import existing resource
const existingBucket = new aws.s3.Bucket("imported-bucket", {
  // Properties must match existing resource
  acl: "private",
  versioning: {
    enabled: false,
  },
}, {
  import: "existing-bucket-name",
});

Advanced Dependency Management

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

const vpc = new aws.ec2.Vpc("main-vpc", {
  cidrBlock: "10.0.0.0/16",
});

const subnet = new aws.ec2.Subnet("main-subnet", {
  vpcId: vpc.id,
  cidrBlock: "10.0.1.0/24",
});

const securityGroup = new aws.ec2.SecurityGroup("web-sg", {
  vpcId: vpc.id,
  ingress: [{
    fromPort: 80,
    toPort: 80,
    protocol: "tcp",
    cidrBlocks: ["0.0.0.0/0"],
  }],
});

// Resource with multiple dependencies
const instance = new aws.ec2.Instance("web-server", {
  ami: "ami-12345678",
  instanceType: "t3.micro",
  subnetId: subnet.id,
  vpcSecurityGroupIds: [securityGroup.id],
}, {
  // Explicit additional dependencies
  dependsOn: [vpc], // Even though implicit via subnet
  
  // Delete this resource with the VPC
  deletedWith: vpc,
});

Best Practices

  • Use component resources to create reusable infrastructure patterns
  • Leverage automatic dependency tracking through resource references
  • Use explicit dependsOn only when implicit dependencies aren't sufficient
  • Protect critical resources with the protect option
  • Use aliases when renaming or restructuring resources
  • Apply transformations for consistent resource configuration
  • Use custom timeouts for long-running operations
  • Consider replaceOnChanges for properties that require replacement
  • Use retainOnDelete for resources that should persist after stack deletion

Install with Tessl CLI

npx tessl i tessl/npm-pulumi--pulumi

docs

asset-management.md

automation.md

configuration.md

dynamic-resources.md

index.md

logging-diagnostics.md

output-system.md

provider-development.md

resource-management.md

runtime-operations.md

stack-references.md

utilities.md

tile.json