Resource Aliases
Relevant source files
The following files were used as context for generating this wiki page:- developer-docs/providers/metaschema.md
- sdk/nodejs/tests/resource.spec.ts
- sdk/nodejs/tests/runtime/langhost/cases/072.large_alias_lineage_chains/index.js
- sdk/nodejs/tests/runtime/langhost/run.spec.ts
- tests/testdata/codegen/simple-resource-with-aliases/schema.json
- tests/testdata/codegen/external-go-import-aliases/schema.json
- pkg/cmd/pulumi/packagecmd/package_info.go
Resource Aliases are a powerful feature in Pulumi that allow for the renaming or refactoring of resources without forcing a replacement (destroy and create) during a pulumi up. When a resource's logical name, type, or parentage changes, Pulumi's engine would normally see this as a new resource and delete the old one. Aliases provide a way to tell the engine that a resource is the same one as before, just with a new identity, thus preserving its state.
This mechanism is crucial for evolving infrastructure code over time. It supports scenarios like renaming a resource for clarity, changing a resource's type (e.g., from v1 to v2), or moving a resource to be a child of another resource. Aliases are specified as a list of old URNs that the new resource should be associated with.
Schema Definition
In the Pulumi Package Metaschema, aliases are defined as an optional array within a resource's definition. Each element in the aliases array is an object that specifies parts of a previous URN.
Sources: developer-docs/providers/metaschema.md:278-281
Alias Definition Object
The Alias Definition object has the following properties:
| Property | Type | Description |
|---|---|---|
name | string | The name portion of the alias, if any. |
project | string | The project portion of the alias, if any. |
type | string | The type portion of the alias, if any. |
Sources: developer-docs/providers/metaschema.md:143-159
The following diagram illustrates the structure of the Alias Definition within the metaschema.
Example Schema
Here is an example from a test schema showing how aliases are used. BasicResourceV2 has an alias to the old type example:index:BasicResource. This means if a user renames BasicResource to BasicResourceV2 in their code, Pulumi will understand it's an update, not a replacement.
{
"example:index:BasicResourceV2": {
"properties": {
"bar": {
"type": "string"
}
},
"required": ["bar"],
"inputProperties": {
"bar": {
"type": "string"
}
},
"requiredInputs": ["bar"],
"type": "object",
"aliases": [
{
"type": "example:index:BasicResource"
}
]
}
}
Sources: tests/testdata/codegen/simple-resource-with-aliases/schema.json:20-36
Runtime Behavior (Node.js)
In the Node.js SDK, aliases can be provided in the CustomResourceOptions. The SDK includes logic to compute the full set of potential alias URNs, especially in the context of parent-child resource relationships.
The allAliases Function
The allAliases function (internal to the @pulumi/pulumi package) is responsible for calculating the final list of alias URNs for a resource. It takes the resource's own aliases and combines them with the aliases of its parent resource to generate a comprehensive list.
This diagram shows the combination logic tested in sdk/nodejs/tests/resource.spec.ts.
This flowchart shows how parent and child aliases are combined to create a full set of possible old URNs for a resource.
Sources: sdk/nodejs/tests/resource.spec.ts:101-103
Alias Calculation Examples
The test suite for allAliases provides concrete examples of how parent and child aliases are merged.
| Test Case | Parent Aliases | Child Aliases | Expected Result URNs (abbreviated) - - - - |
|---|---|---|---|
| one child alias (name), one parent alias (type) | [{ type: "test:resource:type3" }] | [{ name: "myres-child2" }] | ...type$child::myres-child2, ...type3$child::myres-child, ...type3$child::myres-child2 |
| two child aliases, three parent aliases | [{ name: "myres2" }, { type: "type3" }, { name: "myres3" }] | [{ name: "myres-child2" }, { type: "child2" }] | ...type$child::myres-child2, ...type$child2::myres-child, ...type$child::myres2-child, ...type$child::myres2-child2, ...type$child2::myres2-child, ...type3$child::myres-child, ...type3$child::myres-child2, ...type3$child2::myres-child, ...type$child::myres3-child, ...type$child::myres3-child2, ...type$child2::myres3-child |
Sources: sdk/nodejs/tests/resource.spec.ts:127-169
Large-Scale Alias Usage
Pulumi is tested to handle a large number of aliases, including long lineage chains. Tests confirm that resources can have thousands of aliases, and these aliases are correctly processed even in parent-child hierarchies.
In one test case, a resource is created with 1,000 aliases, and a child resource is also created with 1,000 aliases. The engine correctly computes and handles the combined aliases.
// Example from a test case
const resource1Aliases = Array.from(new Array(1000).keys()).map((key) => `my-alias-name-${key}`);
const resource1 = new MyResource("testResource1", resource1Aliases);
const resource2Aliases = Array.from(new Array(1000).keys()).map((key) => `my-other-alias-name-${key}`);
const resource2 = new MyResource("testResource2", resource2Aliases, resource1);
Sources: sdk/nodejs/tests/runtime/langhost/cases/072.large_alias_lineage_chains/index.js:28-34
The test large_alias_lineage_chains demonstrates that the engine correctly includes the parent's type in the computed aliases for the child, ensuring that refactoring a parent resource's type is correctly propagated to its children's state.
Sources: sdk/nodejs/tests/runtime/langhost/cases/072.large_alias_lineage_chains/index.js:45-46, sdk/nodejs/tests/runtime/langhost/run.spec.ts:1017-1021
Go Language Specifics
The Go SDK also supports aliases, but they are often defined in the provider schema itself rather than directly in user code. However, language-specific features like packageImportAliases can be used to manage how generated code handles types from different packages, which is related to aliasing at the code generation level.
For instance, packageImportAliases in a schema's language.go section allows developers to define short, non-conflicting import paths for external packages.
"language": {
"go": {
"packageImportAliases": {
"github.com/pulumi/pulumi-aws/sdk/v4/go/aws/ec2": "awsec2",
"github.com/pulumi/pulumi-google-native/sdk/go/google/iam/v1": "gcpiamv1"
}
}
}
This is a code-generation-time aliasing mechanism, distinct from the runtime resource aliasing for state management, but it helps manage complexity in Go programs that use multiple providers.
Sources: tests/testdata/codegen/external-go-import-aliases/schema.json:79-85