The azure-native:resources:Deployment resource, part of the Pulumi Azure Native provider, executes ARM template deployments within a resource group, managing the lifecycle of Azure resources defined in the template. This guide focuses on three capabilities: template deployment from external URIs and Template Specs, automatic rollback on deployment failure, and deployment modes and error handling.
Deployments require an existing resource group and reference ARM templates stored as URLs, Template Specs, or inline JSON. The examples are intentionally small. Combine them with your own templates, parameter files, and resource groups.
Deploy a template from a URI with SAS token
Most Azure deployments reference ARM templates stored in external locations like Azure Storage or GitHub. When templates live in private storage accounts, you need a SAS token to authenticate access.
import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";
const deployment = new azure_native.resources.Deployment("deployment", {
deploymentName: "my-deployment",
properties: {
mode: azure_native.resources.DeploymentMode.Incremental,
parameters: {},
templateLink: {
queryString: "sv=2019-02-02&st=2019-04-29T22%3A18%3A26Z&se=2019-04-30T02%3A23%3A26Z&sr=b&sp=rw&sip=168.1.5.60-168.1.5.70&spr=https&sig=xxxxxxxx0xxxxxxxxxxxxx%2bxxxxxxxxxxxxxxxxxxxx%3d",
uri: "https://example.com/exampleTemplate.json",
},
},
resourceGroupName: "my-resource-group",
});
import pulumi
import pulumi_azure_native as azure_native
deployment = azure_native.resources.Deployment("deployment",
deployment_name="my-deployment",
properties={
"mode": azure_native.resources.DeploymentMode.INCREMENTAL,
"parameters": {},
"template_link": {
"query_string": "sv=2019-02-02&st=2019-04-29T22%3A18%3A26Z&se=2019-04-30T02%3A23%3A26Z&sr=b&sp=rw&sip=168.1.5.60-168.1.5.70&spr=https&sig=xxxxxxxx0xxxxxxxxxxxxx%2bxxxxxxxxxxxxxxxxxxxx%3d",
"uri": "https://example.com/exampleTemplate.json",
},
},
resource_group_name="my-resource-group")
package main
import (
resources "github.com/pulumi/pulumi-azure-native-sdk/resources/v3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := resources.NewDeployment(ctx, "deployment", &resources.DeploymentArgs{
DeploymentName: pulumi.String("my-deployment"),
Properties: &resources.DeploymentPropertiesArgs{
Mode: resources.DeploymentModeIncremental,
Parameters: resources.DeploymentParameterMap{},
TemplateLink: &resources.TemplateLinkArgs{
QueryString: pulumi.String("sv=2019-02-02&st=2019-04-29T22%3A18%3A26Z&se=2019-04-30T02%3A23%3A26Z&sr=b&sp=rw&sip=168.1.5.60-168.1.5.70&spr=https&sig=xxxxxxxx0xxxxxxxxxxxxx%2bxxxxxxxxxxxxxxxxxxxx%3d"),
Uri: pulumi.String("https://example.com/exampleTemplate.json"),
},
},
ResourceGroupName: pulumi.String("my-resource-group"),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;
return await Deployment.RunAsync(() =>
{
var deployment = new AzureNative.Resources.Deployment("deployment", new()
{
DeploymentName = "my-deployment",
Properties = new AzureNative.Resources.Inputs.DeploymentPropertiesArgs
{
Mode = AzureNative.Resources.DeploymentMode.Incremental,
Parameters = null,
TemplateLink = new AzureNative.Resources.Inputs.TemplateLinkArgs
{
QueryString = "sv=2019-02-02&st=2019-04-29T22%3A18%3A26Z&se=2019-04-30T02%3A23%3A26Z&sr=b&sp=rw&sip=168.1.5.60-168.1.5.70&spr=https&sig=xxxxxxxx0xxxxxxxxxxxxx%2bxxxxxxxxxxxxxxxxxxxx%3d",
Uri = "https://example.com/exampleTemplate.json",
},
},
ResourceGroupName = "my-resource-group",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.resources.Deployment;
import com.pulumi.azurenative.resources.DeploymentArgs;
import com.pulumi.azurenative.resources.inputs.DeploymentPropertiesArgs;
import com.pulumi.azurenative.resources.inputs.TemplateLinkArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var deployment = new Deployment("deployment", DeploymentArgs.builder()
.deploymentName("my-deployment")
.properties(DeploymentPropertiesArgs.builder()
.mode("Incremental")
.parameters(Map.ofEntries(
))
.templateLink(TemplateLinkArgs.builder()
.queryString("sv=2019-02-02&st=2019-04-29T22%3A18%3A26Z&se=2019-04-30T02%3A23%3A26Z&sr=b&sp=rw&sip=168.1.5.60-168.1.5.70&spr=https&sig=xxxxxxxx0xxxxxxxxxxxxx%2bxxxxxxxxxxxxxxxxxxxx%3d")
.uri("https://example.com/exampleTemplate.json")
.build())
.build())
.resourceGroupName("my-resource-group")
.build());
}
}
resources:
deployment:
type: azure-native:resources:Deployment
properties:
deploymentName: my-deployment
properties:
mode: Incremental
parameters: {}
templateLink:
queryString: sv=2019-02-02&st=2019-04-29T22%3A18%3A26Z&se=2019-04-30T02%3A23%3A26Z&sr=b&sp=rw&sip=168.1.5.60-168.1.5.70&spr=https&sig=xxxxxxxx0xxxxxxxxxxxxx%2bxxxxxxxxxxxxxxxxxxxx%3d
uri: https://example.com/exampleTemplate.json
resourceGroupName: my-resource-group
The templateLink property points to your template’s location. The uri specifies the template URL, while queryString provides the SAS token for authentication. The mode property controls how Azure applies the template: Incremental adds or updates resources without touching existing ones, while Complete removes resources not defined in the template.
Deploy a versioned template spec by resource ID
Template Specs store and version ARM templates as Azure resources, making them easier to share across teams and enforce governance.
import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";
const deployment = new azure_native.resources.Deployment("deployment", {
deploymentName: "my-deployment",
properties: {
mode: azure_native.resources.DeploymentMode.Incremental,
parameters: {},
templateLink: {
id: "/subscriptions/00000000-0000-0000-0000-000000000001/resourceGroups/my-resource-group/providers/Microsoft.Resources/TemplateSpecs/TemplateSpec-Name/versions/v1",
},
},
resourceGroupName: "my-resource-group",
});
import pulumi
import pulumi_azure_native as azure_native
deployment = azure_native.resources.Deployment("deployment",
deployment_name="my-deployment",
properties={
"mode": azure_native.resources.DeploymentMode.INCREMENTAL,
"parameters": {},
"template_link": {
"id": "/subscriptions/00000000-0000-0000-0000-000000000001/resourceGroups/my-resource-group/providers/Microsoft.Resources/TemplateSpecs/TemplateSpec-Name/versions/v1",
},
},
resource_group_name="my-resource-group")
package main
import (
resources "github.com/pulumi/pulumi-azure-native-sdk/resources/v3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := resources.NewDeployment(ctx, "deployment", &resources.DeploymentArgs{
DeploymentName: pulumi.String("my-deployment"),
Properties: &resources.DeploymentPropertiesArgs{
Mode: resources.DeploymentModeIncremental,
Parameters: resources.DeploymentParameterMap{},
TemplateLink: &resources.TemplateLinkArgs{
Id: pulumi.String("/subscriptions/00000000-0000-0000-0000-000000000001/resourceGroups/my-resource-group/providers/Microsoft.Resources/TemplateSpecs/TemplateSpec-Name/versions/v1"),
},
},
ResourceGroupName: pulumi.String("my-resource-group"),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;
return await Deployment.RunAsync(() =>
{
var deployment = new AzureNative.Resources.Deployment("deployment", new()
{
DeploymentName = "my-deployment",
Properties = new AzureNative.Resources.Inputs.DeploymentPropertiesArgs
{
Mode = AzureNative.Resources.DeploymentMode.Incremental,
Parameters = null,
TemplateLink = new AzureNative.Resources.Inputs.TemplateLinkArgs
{
Id = "/subscriptions/00000000-0000-0000-0000-000000000001/resourceGroups/my-resource-group/providers/Microsoft.Resources/TemplateSpecs/TemplateSpec-Name/versions/v1",
},
},
ResourceGroupName = "my-resource-group",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.resources.Deployment;
import com.pulumi.azurenative.resources.DeploymentArgs;
import com.pulumi.azurenative.resources.inputs.DeploymentPropertiesArgs;
import com.pulumi.azurenative.resources.inputs.TemplateLinkArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var deployment = new Deployment("deployment", DeploymentArgs.builder()
.deploymentName("my-deployment")
.properties(DeploymentPropertiesArgs.builder()
.mode("Incremental")
.parameters(Map.ofEntries(
))
.templateLink(TemplateLinkArgs.builder()
.id("/subscriptions/00000000-0000-0000-0000-000000000001/resourceGroups/my-resource-group/providers/Microsoft.Resources/TemplateSpecs/TemplateSpec-Name/versions/v1")
.build())
.build())
.resourceGroupName("my-resource-group")
.build());
}
}
resources:
deployment:
type: azure-native:resources:Deployment
properties:
deploymentName: my-deployment
properties:
mode: Incremental
parameters: {}
templateLink:
id: /subscriptions/00000000-0000-0000-0000-000000000001/resourceGroups/my-resource-group/providers/Microsoft.Resources/TemplateSpecs/TemplateSpec-Name/versions/v1
resourceGroupName: my-resource-group
Instead of a URI, the templateLink.id property references a Template Spec by its full resource ID, including the version path. This approach centralizes template management and ensures teams deploy approved, versioned infrastructure definitions.
Roll back to a specific deployment on failure
Production deployments often need automatic rollback strategies to minimize downtime when new changes fail validation or cause runtime errors.
import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";
const deployment = new azure_native.resources.Deployment("deployment", {
deploymentName: "my-deployment",
properties: {
mode: azure_native.resources.DeploymentMode.Complete,
onErrorDeployment: {
deploymentName: "name-of-deployment-to-use",
type: azure_native.resources.OnErrorDeploymentType.SpecificDeployment,
},
parameters: {},
templateLink: {
uri: "https://example.com/exampleTemplate.json",
},
},
resourceGroupName: "my-resource-group",
});
import pulumi
import pulumi_azure_native as azure_native
deployment = azure_native.resources.Deployment("deployment",
deployment_name="my-deployment",
properties={
"mode": azure_native.resources.DeploymentMode.COMPLETE,
"on_error_deployment": {
"deployment_name": "name-of-deployment-to-use",
"type": azure_native.resources.OnErrorDeploymentType.SPECIFIC_DEPLOYMENT,
},
"parameters": {},
"template_link": {
"uri": "https://example.com/exampleTemplate.json",
},
},
resource_group_name="my-resource-group")
package main
import (
resources "github.com/pulumi/pulumi-azure-native-sdk/resources/v3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := resources.NewDeployment(ctx, "deployment", &resources.DeploymentArgs{
DeploymentName: pulumi.String("my-deployment"),
Properties: &resources.DeploymentPropertiesArgs{
Mode: resources.DeploymentModeComplete,
OnErrorDeployment: &resources.OnErrorDeploymentArgs{
DeploymentName: pulumi.String("name-of-deployment-to-use"),
Type: resources.OnErrorDeploymentTypeSpecificDeployment,
},
Parameters: resources.DeploymentParameterMap{},
TemplateLink: &resources.TemplateLinkArgs{
Uri: pulumi.String("https://example.com/exampleTemplate.json"),
},
},
ResourceGroupName: pulumi.String("my-resource-group"),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;
return await Deployment.RunAsync(() =>
{
var deployment = new AzureNative.Resources.Deployment("deployment", new()
{
DeploymentName = "my-deployment",
Properties = new AzureNative.Resources.Inputs.DeploymentPropertiesArgs
{
Mode = AzureNative.Resources.DeploymentMode.Complete,
OnErrorDeployment = new AzureNative.Resources.Inputs.OnErrorDeploymentArgs
{
DeploymentName = "name-of-deployment-to-use",
Type = AzureNative.Resources.OnErrorDeploymentType.SpecificDeployment,
},
Parameters = null,
TemplateLink = new AzureNative.Resources.Inputs.TemplateLinkArgs
{
Uri = "https://example.com/exampleTemplate.json",
},
},
ResourceGroupName = "my-resource-group",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.resources.Deployment;
import com.pulumi.azurenative.resources.DeploymentArgs;
import com.pulumi.azurenative.resources.inputs.DeploymentPropertiesArgs;
import com.pulumi.azurenative.resources.inputs.OnErrorDeploymentArgs;
import com.pulumi.azurenative.resources.inputs.TemplateLinkArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var deployment = new Deployment("deployment", DeploymentArgs.builder()
.deploymentName("my-deployment")
.properties(DeploymentPropertiesArgs.builder()
.mode("Complete")
.onErrorDeployment(OnErrorDeploymentArgs.builder()
.deploymentName("name-of-deployment-to-use")
.type("SpecificDeployment")
.build())
.parameters(Map.ofEntries(
))
.templateLink(TemplateLinkArgs.builder()
.uri("https://example.com/exampleTemplate.json")
.build())
.build())
.resourceGroupName("my-resource-group")
.build());
}
}
resources:
deployment:
type: azure-native:resources:Deployment
properties:
deploymentName: my-deployment
properties:
mode: Complete
onErrorDeployment:
deploymentName: name-of-deployment-to-use
type: SpecificDeployment
parameters: {}
templateLink:
uri: https://example.com/exampleTemplate.json
resourceGroupName: my-resource-group
The onErrorDeployment property defines rollback behavior. When type is SpecificDeployment, Azure redeploys the deployment named in deploymentName if the current deployment fails. This provides a safety net for risky changes.
Roll back to the last successful deployment on failure
When you don’t know which specific deployment to roll back to, Azure can automatically identify and redeploy the most recent successful deployment.
import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";
const deployment = new azure_native.resources.Deployment("deployment", {
deploymentName: "my-deployment",
properties: {
mode: azure_native.resources.DeploymentMode.Complete,
onErrorDeployment: {
type: azure_native.resources.OnErrorDeploymentType.LastSuccessful,
},
parameters: {},
templateLink: {
uri: "https://example.com/exampleTemplate.json",
},
},
resourceGroupName: "my-resource-group",
});
import pulumi
import pulumi_azure_native as azure_native
deployment = azure_native.resources.Deployment("deployment",
deployment_name="my-deployment",
properties={
"mode": azure_native.resources.DeploymentMode.COMPLETE,
"on_error_deployment": {
"type": azure_native.resources.OnErrorDeploymentType.LAST_SUCCESSFUL,
},
"parameters": {},
"template_link": {
"uri": "https://example.com/exampleTemplate.json",
},
},
resource_group_name="my-resource-group")
package main
import (
resources "github.com/pulumi/pulumi-azure-native-sdk/resources/v3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := resources.NewDeployment(ctx, "deployment", &resources.DeploymentArgs{
DeploymentName: pulumi.String("my-deployment"),
Properties: &resources.DeploymentPropertiesArgs{
Mode: resources.DeploymentModeComplete,
OnErrorDeployment: &resources.OnErrorDeploymentArgs{
Type: resources.OnErrorDeploymentTypeLastSuccessful,
},
Parameters: resources.DeploymentParameterMap{},
TemplateLink: &resources.TemplateLinkArgs{
Uri: pulumi.String("https://example.com/exampleTemplate.json"),
},
},
ResourceGroupName: pulumi.String("my-resource-group"),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;
return await Deployment.RunAsync(() =>
{
var deployment = new AzureNative.Resources.Deployment("deployment", new()
{
DeploymentName = "my-deployment",
Properties = new AzureNative.Resources.Inputs.DeploymentPropertiesArgs
{
Mode = AzureNative.Resources.DeploymentMode.Complete,
OnErrorDeployment = new AzureNative.Resources.Inputs.OnErrorDeploymentArgs
{
Type = AzureNative.Resources.OnErrorDeploymentType.LastSuccessful,
},
Parameters = null,
TemplateLink = new AzureNative.Resources.Inputs.TemplateLinkArgs
{
Uri = "https://example.com/exampleTemplate.json",
},
},
ResourceGroupName = "my-resource-group",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.resources.Deployment;
import com.pulumi.azurenative.resources.DeploymentArgs;
import com.pulumi.azurenative.resources.inputs.DeploymentPropertiesArgs;
import com.pulumi.azurenative.resources.inputs.OnErrorDeploymentArgs;
import com.pulumi.azurenative.resources.inputs.TemplateLinkArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var deployment = new Deployment("deployment", DeploymentArgs.builder()
.deploymentName("my-deployment")
.properties(DeploymentPropertiesArgs.builder()
.mode("Complete")
.onErrorDeployment(OnErrorDeploymentArgs.builder()
.type("LastSuccessful")
.build())
.parameters(Map.ofEntries(
))
.templateLink(TemplateLinkArgs.builder()
.uri("https://example.com/exampleTemplate.json")
.build())
.build())
.resourceGroupName("my-resource-group")
.build());
}
}
resources:
deployment:
type: azure-native:resources:Deployment
properties:
deploymentName: my-deployment
properties:
mode: Complete
onErrorDeployment:
type: LastSuccessful
parameters: {}
templateLink:
uri: https://example.com/exampleTemplate.json
resourceGroupName: my-resource-group
Setting onErrorDeployment.type to LastSuccessful tells Azure to find and redeploy the most recent successful deployment automatically. This is simpler than tracking deployment names manually but requires at least one successful deployment in the resource group’s history.
Beyond these examples
These snippets focus on specific deployment-level features: template deployment from URIs and Template Specs, error handling and automatic rollback, and deployment modes. They’re intentionally minimal rather than full infrastructure deployments.
The examples may reference pre-existing infrastructure such as resource groups, ARM templates or Template Specs, and previous successful deployments for rollback scenarios. They focus on configuring the deployment rather than provisioning the templates or resource groups themselves.
To keep things focused, common deployment patterns are omitted, including:
- Template parameters and parameter files
- Inline template definitions (template property)
- Deployment location and tagging
- What-if validation and deployment scopes
These omissions are intentional: the goal is to illustrate how each deployment feature is wired, not provide drop-in infrastructure modules. See the Deployment resource reference for all available configuration options.
Let's deploy Azure Resource Manager Templates
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Configuration & Setup
deploymentName and resourceGroupName are immutable and cannot be changed after creation.Template Sources
templateLink with uri pointing to your template JSON. For private storage, add a queryString with your SAS token.templateLink.id to the full resource ID of your TemplateSpec version (e.g., /subscriptions/.../providers/Microsoft.Resources/TemplateSpecs/TemplateSpec-Name/versions/v1).Deployment Modes
Incremental mode adds or updates resources without affecting existing resources not in the template. Complete mode deletes any resources in the resource group that aren’t defined in the template.Error Handling & Rollback
onErrorDeployment with type set to either SpecificDeployment (rollback to a named deployment) or LastSuccessful (rollback to the last successful deployment).SpecificDeployment rolls back to a deployment you specify by name using deploymentName. LastSuccessful automatically rolls back to the most recent successful deployment without requiring a name.onErrorDeployment used with Complete mode. While not explicitly prohibited, rollback is typically paired with Complete mode deployments.