@azure/provisioning-core
The runtime for authoring Azure infrastructure in TypeScript: resource trees, symbolic expressions, shared configuration, and JSON and Bicep serialization. Creating or editing these objects changes a deployment definition, not live Azure resources.
Start with Getting started for a walkthrough using core and service classes such as StorageAccount and KeyVault.
Major features
Resource authoring
A deployment definition is a tree of ProvisioningComponent objects. Stack, Resource, and concrete resource classes such as StorageAccount are direct or indirect subclasses of it. Each building block links to its source implementation:
- ProvisioningComponent - the base class for tree nodes, providing parent-child tracking, inherited deployment context, traversal, and transformations. You can create your own subclass to group related resources, apply shared configuration, and expose resource handles as a reusable component. The component itself does not declare an Azure resource.
- Stack - the root component of a definition, holding resources and deployment inputs and outputs.
- Resource - the base for service classes and generic ARM declarations, including existing references, conditions, and dependencies. Writable properties can be edited after construction and before serialization; read-only properties remain available as references.
- ResourceGroup - a built-in Azure resource that also provides a parent context for its resources.
- Deployment context - carries inherited location, tags, and naming policy through the component tree. The nearest ancestor supplies location and policy; ancestor tags are merged with nearer values taking precedence.
- Naming - generates omitted resource names through a configurable policy, using resource naming rules that describe Azure length, character, and uniqueness requirements. These rules guide name generation; explicit names are used unchanged.
- Parameters - inputs supplied at deployment, with optional defaults and constraints.
- Variables - named values or expressions shared within the definition.
- Outputs - values returned by the deployment, such as a resource ID.
- Resource queries - find authored objects by type or literal name so they can be inspected and edited without querying Azure.
Read more
- Getting started - construct and configure resources through the public APIs.
- Configure resource properties - edit writable properties or replace nested objects before serialization.
- Infrastructure authoring model - resource relationships and reusable components.
- Names and shared defaults - naming policies, inherited settings, and resource-level overrides.
- Parameters, variables, and outputs - declare deployment values through stack collections.
Functions and expressions
Connect resource settings to parameters, calculations, and other resources even when their values are not yet known. Core preserves these relationships as deployment-time expressions rather than evaluating them in JavaScript.
- Function helpers -
fnbuilds symbolic operations such as concatenation, comparisons, and resource-ID calculations. - Expression types -
Expression<T>andExpressionOrValue<T>describe symbolic and literal values; generated input/view types use core's typing contracts to support nested authoring. - Resource property expressions - use resource properties as deployment-time expressions to connect resources, such as passing one resource's ID to another resource's input.
Read more
- Working with expressions - authoring calculations and resource references.
- Provisioning type system - input/view types and expression assignability.
- Proxy system - how core supports expressions on resource properties through ordinary TypeScript property access.
Deploy-time discriminators
Use asDiscriminator when a deployment expression must fill a literal discriminator.
In this example, kindParam is an Expression<"cache">, and
widget.properties.primaryRule accepts either a cache rule with cacheKind and days
or a redirect rule. The helper selects the cache variant while preserving its property checks.
import { asDiscriminator } from "@azure/provisioning-core";
widget.properties.primaryRule = {
kind: asDiscriminator(kindParam),
cacheKind: "long",
days: 7,
};
Prefer a literal discriminator when possible. This helper is a type assertion, not runtime validation.
Serialization and restoration
serialize converts the tree, values, and references into a JSON-compatible document. deserialize reconstructs supported resource objects so they can be queried, edited, and serialized again. Three pieces support this round trip:
- Serialization AST - defines the cross-language JSON format for exchanging provisioning definitions between TypeScript and .NET, so both sides interpret resource declarations, values, and references consistently.
- Runtime shapes - retain client-to-ARM property mappings, nested types, and encoding metadata after TypeScript erasure, guiding value conversion in both directions.
- Resource registration - resolves registered classes and shapes by resource type, API version, and variant. Load the relevant service packages before restoration so their registrations are available.
Imported scopes resolve to known parent relationships where possible. Otherwise, their expressions are preserved for round-tripping and explicit Bicep rendering without inferring a deployment destination. This does not add explicit scope authoring for new resources.
Read more
- Changing the serialization contract - contract source, generation, and affected consumers.
- Runtime shapes and registration - property mappings and concrete resource classes.
- Serialization and restoration - the round-trip workflow and its limitations.
Bicep generation
The internal renderBicepFiles API generates Bicep files from authored Stacks.
import { renderBicepFiles } from "@azure/provisioning-core/internal";
for (const file of renderBicepFiles(stack)) {
console.log(file.path);
console.log(file.contents);
}
The renderer accepts one Stack or an array of Stacks and returns paths and source
text without writing files or deploying resources. Restore saved JSON with
deserialize() before rendering it.
See Bicep generation for file layout and cross-file references, and Bicep scopes for deployment scope rules.
Related packages
For how service classes, their types, and runtime metadata are produced, see Service package anatomy and the TypeSpec emitter overview.