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
Pulumi provides various utility functions and helpers for common operations, type checking, and metadata access in Pulumi programs.
function isInstance<T>(obj: any, name: string): obj is T;
function hasTrueBooleanMember(obj: any, memberName: string): boolean;
function hasFunctionMember(obj: any, memberName: string): boolean;function values(obj: any): any[];
function union<T>(set1: Set<T>, set2: Set<T>): Set<T>;
function toObject<T, V>(source: Iterable<T>, keySelector: (item: T) => string, elementSelector?: (item: T) => V): {[key: string]: V};
function groupBy<T, V>(source: Iterable<T>, keySelector: (item: T) => string, elementSelector?: (item: T) => V): {[key: string]: V[]};function getOrganization(): string;
function getProject(): string;
function getStack(): string;
function getRootDirectory(): string;const disableResourceReferences: boolean;
const errorOutputString: boolean;import * as pulumi from "@pulumi/pulumi";
// Safe type checking for Pulumi types across versions
function isOutput(obj: any): obj is pulumi.Output<any> {
return pulumi.utils.isInstance(obj, "__pulumiOutput");
}
function isResource(obj: any): obj is pulumi.Resource {
return pulumi.utils.isInstance(obj, "__pulumiResource");
}
function isAsset(obj: any): obj is pulumi.Asset {
return pulumi.utils.isInstance(obj, "__pulumiAsset");
}
// Check for specific members
function hasOutputMethods(obj: any): boolean {
return pulumi.utils.hasFunctionMember(obj, "apply") &&
pulumi.utils.hasFunctionMember(obj, "isKnown");
}
// Check boolean flags
function isProtectedResource(obj: any): boolean {
return pulumi.utils.hasTrueBooleanMember(obj, "__pulumiProtected");
}
// Usage
const bucket = new aws.s3.Bucket("my-bucket");
if (isResource(bucket)) {
console.log("Object is a Pulumi resource");
}
if (isOutput(bucket.id)) {
console.log("Bucket ID is an Output");
}import * as pulumi from "@pulumi/pulumi";
// Convert array to object with key selector
const resources = [
{ name: "web-server-1", type: "ec2", region: "us-east-1" },
{ name: "web-server-2", type: "ec2", region: "us-west-2" },
{ name: "db-server-1", type: "rds", region: "us-east-1" },
];
const resourcesByName = pulumi.iterable.toObject(
resources,
item => item.name,
item => item
);
console.log(resourcesByName["web-server-1"]); // { name: "web-server-1", ... }
// Group resources by type
const resourcesByType = pulumi.iterable.groupBy(
resources,
item => item.type,
item => item.name
);
console.log(resourcesByType.ec2); // ["web-server-1", "web-server-2"]
console.log(resourcesByType.rds); // ["db-server-1"]
// Get object values
const config = {
environment: "production",
region: "us-east-1",
debug: false,
};
const configValues = pulumi.utils.values(config);
console.log(configValues); // ["production", "us-east-1", false]
// Set operations
const set1 = new Set(["a", "b", "c"]);
const set2 = new Set(["c", "d", "e"]);
const combined = pulumi.utils.union(set1, set2);
console.log(Array.from(combined)); // ["a", "b", "c", "d", "e"]import * as pulumi from "@pulumi/pulumi";
// Get deployment context information
const organization = pulumi.getOrganization();
const project = pulumi.getProject();
const stack = pulumi.getStack();
const rootDir = pulumi.getRootDirectory();
console.log(`Deploying ${organization}/${project}/${stack}`);
console.log(`Project root: ${rootDir}`);
// Use metadata in resource naming
const resourcePrefix = `${project}-${stack}`;
const bucket = new aws.s3.Bucket(`${resourcePrefix}-assets`, {
bucket: `${organization}-${project}-${stack}-assets`,
tags: {
Project: project,
Stack: stack,
Organization: organization,
},
});
// Create environment-aware configurations
function getEnvironmentConfig() {
const stackName = pulumi.getStack();
const configs = {
development: {
instanceType: "t3.micro",
minSize: 1,
maxSize: 2,
},
staging: {
instanceType: "t3.small",
minSize: 2,
maxSize: 4,
},
production: {
instanceType: "t3.medium",
minSize: 3,
maxSize: 10,
},
};
return configs[stackName as keyof typeof configs] || configs.development;
}
const envConfig = getEnvironmentConfig();
console.log(`Using configuration for ${pulumi.getStack()}:`, envConfig);import * as pulumi from "@pulumi/pulumi";
// Helper for checking resource types
function getResourceType(resource: pulumi.Resource): string {
if (pulumi.utils.isInstance(resource, "__pulumiCustomResource")) {
return "CustomResource";
} else if (pulumi.utils.isInstance(resource, "__pulumiComponentResource")) {
return "ComponentResource";
} else if (pulumi.utils.isInstance(resource, "__pulumiProviderResource")) {
return "ProviderResource";
}
return "Resource";
}
// Helper for extracting output values safely
function extractOutputValue<T>(output: pulumi.Output<T>, defaultValue: T): Promise<T> {
return output.apply(value => value !== undefined ? value : defaultValue);
}
// Helper for creating resource names with metadata
function createResourceName(baseName: string, suffix?: string): string {
const project = pulumi.getProject();
const stack = pulumi.getStack();
let name = `${project}-${stack}-${baseName}`;
if (suffix) {
name += `-${suffix}`;
}
// Ensure name meets resource naming requirements
return name.toLowerCase().replace(/[^a-z0-9-]/g, '-');
}
// Helper for validating resource configurations
function validateResourceConfig(config: any, required: string[]): void {
const missing = required.filter(key => !pulumi.utils.hasTrueBooleanMember(config, key) && !config[key]);
if (missing.length > 0) {
throw new pulumi.RunError(`Missing required configuration: ${missing.join(", ")}`);
}
}
// Usage examples
const bucket = new aws.s3.Bucket("assets");
console.log(`Resource type: ${getResourceType(bucket)}`);
const bucketId = await extractOutputValue(bucket.id, "default-bucket-id");
console.log(`Bucket ID: ${bucketId}`);
const resourceName = createResourceName("web-server", "primary");
console.log(`Generated name: ${resourceName}`);
validateResourceConfig({ name: "test", enabled: true }, ["name", "enabled"]);import * as pulumi from "@pulumi/pulumi";
// Utility for inspecting resource properties
function inspectResource(resource: pulumi.Resource): void {
console.log(`Resource URN: ${resource.urn}`);
if (pulumi.utils.isInstance(resource, "__pulumiCustomResource")) {
const customResource = resource as pulumi.CustomResource;
customResource.id.apply(id => console.log(`Resource ID: ${id}`));
}
// Check for common properties
const resourceAny = resource as any;
Object.keys(resourceAny).forEach(key => {
if (pulumi.utils.isInstance(resourceAny[key], "__pulumiOutput")) {
console.log(`Property ${key} is an Output`);
}
});
}
// Utility for checking Pulumi state
function checkPulumiState(): void {
const hasSecrets = Object.keys(process.env).some(key =>
key.startsWith('PULUMI_CONFIG_') && key.endsWith('_SECRET')
);
console.log(`Project: ${pulumi.getProject()}`);
console.log(`Stack: ${pulumi.getStack()}`);
console.log(`Organization: ${pulumi.getOrganization()}`);
console.log(`Has secrets: ${hasSecrets}`);
}
// Development helper for listing all outputs
function listAllOutputs(resources: pulumi.Resource[]): void {
resources.forEach((resource, index) => {
console.log(`Resource ${index}: ${getResourceType(resource)}`);
const resourceAny = resource as any;
Object.keys(resourceAny).forEach(key => {
if (pulumi.utils.isInstance(resourceAny[key], "__pulumiOutput")) {
resourceAny[key].apply((value: any) => {
console.log(` ${key}: ${JSON.stringify(value)}`);
});
}
});
});
}
// Usage
const bucket = new aws.s3.Bucket("debug-bucket");
const database = new aws.rds.Instance("debug-db", {
engine: "postgres",
instanceClass: "db.t3.micro",
});
inspectResource(bucket);
checkPulumiState();
listAllOutputs([bucket, database]);import * as pulumi from "@pulumi/pulumi";
// Helper for batching operations
function batchOperations<T, R>(
items: T[],
batchSize: number,
operation: (batch: T[]) => Promise<R[]>
): Promise<R[]> {
const batches: T[][] = [];
for (let i = 0; i < items.length; i += batchSize) {
batches.push(items.slice(i, i + batchSize));
}
return Promise.all(batches.map(operation)).then(results =>
results.flat()
);
}
// Helper for memoizing expensive operations
function memoize<T extends (...args: any[]) => any>(fn: T): T {
const cache = new Map();
return ((...args: any[]) => {
const key = JSON.stringify(args);
if (cache.has(key)) {
return cache.get(key);
}
const result = fn(...args);
cache.set(key, result);
return result;
}) as T;
}
// Memoized expensive configuration calculation
const getExpensiveConfig = memoize((stack: string) => {
console.log(`Computing expensive config for ${stack}`);
// Expensive operation here
return {
setting1: `value-for-${stack}`,
setting2: Math.random(),
};
});
// Usage
const config1 = getExpensiveConfig(pulumi.getStack()); // Computed
const config2 = getExpensiveConfig(pulumi.getStack()); // CachedInstall with Tessl CLI
npx tessl i tessl/npm-pulumi--pulumidocs
evals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9
scenario-10