Open-Source Wikis

/

Pulumi

/

Primitives

/

Resources and URNs

pulumi/pulumi

Resources and URNs

Active contributors: Justin Van Patten, Ian Wahbe, Thomas Gummerer

Purpose

Pulumi's universe consists of resources. Every cloud object — and every logical grouping — is a resource. Each resource has a URN (a stable identity), a type token (what kind of thing it is), an input map (what was asked for), an output map (what came back), and a parent / dependency graph linking it to others.

This page explains the canonical shape of a resource, the URN algebra, and the way the engine, the SDKs, and the snapshot all agree on this model.

The URN

sdk/go/common/resource/urn/urn.go defines:

urn:pulumi:<stack>::<project>::<parent-type>$<type>::<name>

Concrete example:

urn:pulumi:dev::my-app::aws:s3/bucket:Bucket::logs
urn:pulumi:dev::my-app::custom:component:App$aws:s3/bucket:Bucket::logs

Components of the URN:

  • <stack> — stack name (dev, prod, etc.).
  • <project> — project name from Pulumi.yaml.
  • <parent-type> — concatenated chain of parent resource types (separated by $). Empty for root-level resources.
  • <type> — the type token (e.g. aws:s3/bucket:Bucket).
  • <name> — the user-supplied name.

URNs are deterministic given those inputs. Renaming a resource — or moving its parent — produces a new URN. To preserve identity across renames, declare an Alias (proto/pulumi/alias.proto).

Type tokens

sdk/go/common/tokens/ defines:

type Type      = string  // e.g. "aws:s3/bucket:Bucket"
type Package   = string  // "aws"
type ModuleMember = string  // "aws:s3/bucket"

Format: <package>:<module>:<TypeName>. Module is hierarchical (aws:s3/bucket).

Type tokens are interned by providers and cataloged in their schemas. The engine uses the package portion to pick the right provider.

Resource categories

Category Marker What it is
Custom Custom: true Backed by a real provider RPC (Create/Update/Delete). 99% of resources.
Component Custom: false A logical grouping with no provider counterpart. Implemented by extending ComponentResource.
Provider type starts with pulumi:providers: An instance of a provider plugin with specific config. Synthesized as a default if not declared.
Stack type is pulumi:pulumi:Stack The root resource — every other resource is parented under it.
External External: true Read-only — declared via Resource.Read(...).
Remote component a component implemented in another language Looks like a Custom resource on the wire (uses Construct/Call).

Resource state

sdk/go/common/resource/resource_state.go defines:

type State struct {
    URN                       resource.URN
    Custom                    bool
    Delete                    bool
    ID                        resource.ID
    Type                      tokens.Type
    Inputs                    PropertyMap
    Outputs                   PropertyMap
    Parent                    resource.URN
    Protect                   bool
    External                  bool
    Dependencies              []resource.URN
    InitErrors                []string
    Provider                  string             // URN of provider as string
    PropertyDependencies      map[PropertyKey][]URN
    PendingReplacement        bool
    AdditionalSecretOutputs   []PropertyKey
    Aliases                   []resource.URN
    CustomTimeouts            CustomTimeouts
    ImportID                  resource.ID
    RetainOnDelete            bool
    DeletedWith               resource.URN
    Created                   *time.Time
    Modified                  *time.Time
    SourcePosition            string
}

Every field has a wire counterpart in proto/pulumi/resource.proto. The snapshot is a list of States plus metadata.

PropertyMap and PropertyValue

Inputs and outputs aren't typed structs — they're PropertyMap, a map[string]PropertyValue. PropertyValue is a sum type covering:

  • Primitives: bool, number, string.
  • Containers: array, object, set.
  • Special: Asset, Archive, Secret, Computed (engine-only "unknown"), Output (placeholder), ResourceReference.

This shape lives in sdk/go/common/resource/properties.go. Every SDK marshals between language-native values and PropertyMap for the wire.

Parent / dependency graph

A resource's parent is set by the SDK when constructing the resource (component children parent under the component). Dependencies are explicit (dependsOn) or implicit (an Output value flowed in as an input).

The step generator uses dependencies to determine execution order. The step executor schedules N steps in parallel; cross-resource dependencies serialize execution.

Aliases

When you rename a resource, declare an Alias:

new aws.s3.Bucket("logs", { ... }, { aliases: [{ name: "old-logs" }] });

The engine recognizes the old URN and emits a SameStep instead of a DeleteStep followed by a CreateStep (which would destroy and recreate the bucket).

URN scope

URNs are scoped by stack — same project, different stack means different URN. pulumi state move is the way to migrate URNs across stacks.

Custom timeouts and protect

Two oft-misunderstood fields:

  • Protect: truepulumi destroy refuses to delete this resource. To remove it: pulumi state unprotect <urn> then re-run destroy.
  • RetainOnDelete: true — the engine emits no Delete to the provider. The resource leaves the stack but remains in the cloud. Useful for cross-stack ownership transitions.
  • CustomTimeouts — per-op timeouts for Create / Update / Delete. The provider chooses how to honor them.

Source position

SourcePosition is the file and line where the resource was registered in the user's program. Recent versions of the engine plumb this through so error messages can point at the offending source line. Implemented by the language SDKs (each captures its own stack frame).

Entry points for modification

  • Adding a new resource state field — add to State, to proto/pulumi/resource.proto, regenerate, plumb through every SDK.
  • A new resource option — same path, but the option is in RegisterResourceRequest rather than the persisted State (or both).
  • A new property typePropertyValue in sdk/go/common/resource/properties.go. Cross-language work to teach every SDK.

See also

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Resources and URNs – Pulumi wiki | Factory