The azure-native:blueprint:TemplateArtifact resource, part of the Pulumi Azure Native provider, defines ARM template artifacts within Azure Blueprints that deploy Resource Manager templates as part of a blueprint assignment. This guide focuses on two capabilities: embedding ARM templates with parameterized deployments and scoping artifacts to management groups or subscriptions.
Template artifacts belong to blueprint definitions and deploy ARM templates when the blueprint is assigned. The examples are intentionally small. Combine them with your own blueprint definitions, resource groups, and parameter configurations.
Deploy a storage account template with parameterized SKU
Organizations standardizing infrastructure often embed ARM templates in blueprints to ensure consistent resource deployment across subscriptions or management groups.
import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";
const templateArtifact = new azure_native.blueprint.TemplateArtifact("templateArtifact", {
artifactName: "storageTemplate",
blueprintName: "simpleBlueprint",
kind: "template",
parameters: {
storageAccountType: {
value: "[parameters('storageAccountType')]",
},
},
resourceGroup: "storageRG",
resourceScope: "providers/Microsoft.Management/managementGroups/ContosoOnlineGroup",
template: {
contentVersion: "1.0.0.0",
outputs: {
storageAccountName: {
type: "string",
value: "[variables('storageAccountName')]",
},
},
parameters: {
storageAccountType: {
allowedValues: [
"Standard_LRS",
"Standard_GRS",
"Standard_ZRS",
"Premium_LRS",
],
defaultValue: "Standard_LRS",
metadata: {
description: "Storage Account type",
},
type: "string",
},
},
resources: [{
apiVersion: "2016-01-01",
kind: "Storage",
location: "[resourceGroup().location]",
name: "[variables('storageAccountName')]",
properties: {},
sku: {
name: "[parameters('storageAccountType')]",
},
type: "Microsoft.Storage/storageAccounts",
}],
variables: {
storageAccountName: "[concat(uniquestring(resourceGroup().id), 'standardsa')]",
},
},
});
import pulumi
import pulumi_azure_native as azure_native
template_artifact = azure_native.blueprint.TemplateArtifact("templateArtifact",
artifact_name="storageTemplate",
blueprint_name="simpleBlueprint",
kind="template",
parameters={
"storageAccountType": {
"value": "[parameters('storageAccountType')]",
},
},
resource_group="storageRG",
resource_scope="providers/Microsoft.Management/managementGroups/ContosoOnlineGroup",
template={
"contentVersion": "1.0.0.0",
"outputs": {
"storageAccountName": {
"type": "string",
"value": "[variables('storageAccountName')]",
},
},
"parameters": {
"storageAccountType": {
"allowedValues": [
"Standard_LRS",
"Standard_GRS",
"Standard_ZRS",
"Premium_LRS",
],
"defaultValue": "Standard_LRS",
"metadata": {
"description": "Storage Account type",
},
"type": "string",
},
},
"resources": [{
"apiVersion": "2016-01-01",
"kind": "Storage",
"location": "[resourceGroup().location]",
"name": "[variables('storageAccountName')]",
"properties": {},
"sku": {
"name": "[parameters('storageAccountType')]",
},
"type": "Microsoft.Storage/storageAccounts",
}],
"variables": {
"storageAccountName": "[concat(uniquestring(resourceGroup().id), 'standardsa')]",
},
})
package main
import (
blueprint "github.com/pulumi/pulumi-azure-native-sdk/blueprint/v3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := blueprint.NewTemplateArtifact(ctx, "templateArtifact", &blueprint.TemplateArtifactArgs{
ArtifactName: pulumi.String("storageTemplate"),
BlueprintName: pulumi.String("simpleBlueprint"),
Kind: pulumi.String("template"),
Parameters: blueprint.ParameterValueMap{
"storageAccountType": &blueprint.ParameterValueArgs{
Value: pulumi.Any("[parameters('storageAccountType')]"),
},
},
ResourceGroup: pulumi.String("storageRG"),
ResourceScope: pulumi.String("providers/Microsoft.Management/managementGroups/ContosoOnlineGroup"),
Template: pulumi.Any(map[string]interface{}{
"contentVersion": "1.0.0.0",
"outputs": map[string]interface{}{
"storageAccountName": map[string]interface{}{
"type": "string",
"value": "[variables('storageAccountName')]",
},
},
"parameters": map[string]interface{}{
"storageAccountType": map[string]interface{}{
"allowedValues": []string{
"Standard_LRS",
"Standard_GRS",
"Standard_ZRS",
"Premium_LRS",
},
"defaultValue": "Standard_LRS",
"metadata": map[string]interface{}{
"description": "Storage Account type",
},
"type": "string",
},
},
"resources": []map[string]interface{}{
map[string]interface{}{
"apiVersion": "2016-01-01",
"kind": "Storage",
"location": "[resourceGroup().location]",
"name": "[variables('storageAccountName')]",
"properties": map[string]interface{}{},
"sku": map[string]interface{}{
"name": "[parameters('storageAccountType')]",
},
"type": "Microsoft.Storage/storageAccounts",
},
},
"variables": map[string]interface{}{
"storageAccountName": "[concat(uniquestring(resourceGroup().id), 'standardsa')]",
},
}),
})
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 templateArtifact = new AzureNative.Blueprint.TemplateArtifact("templateArtifact", new()
{
ArtifactName = "storageTemplate",
BlueprintName = "simpleBlueprint",
Kind = "template",
Parameters =
{
{ "storageAccountType", new AzureNative.Blueprint.Inputs.ParameterValueArgs
{
Value = "[parameters('storageAccountType')]",
} },
},
ResourceGroup = "storageRG",
ResourceScope = "providers/Microsoft.Management/managementGroups/ContosoOnlineGroup",
Template = new Dictionary<string, object?>
{
["contentVersion"] = "1.0.0.0",
["outputs"] = new Dictionary<string, object?>
{
["storageAccountName"] = new Dictionary<string, object?>
{
["type"] = "string",
["value"] = "[variables('storageAccountName')]",
},
},
["parameters"] = new Dictionary<string, object?>
{
["storageAccountType"] = new Dictionary<string, object?>
{
["allowedValues"] = new[]
{
"Standard_LRS",
"Standard_GRS",
"Standard_ZRS",
"Premium_LRS",
},
["defaultValue"] = "Standard_LRS",
["metadata"] = new Dictionary<string, object?>
{
["description"] = "Storage Account type",
},
["type"] = "string",
},
},
["resources"] = new[]
{
new Dictionary<string, object?>
{
["apiVersion"] = "2016-01-01",
["kind"] = "Storage",
["location"] = "[resourceGroup().location]",
["name"] = "[variables('storageAccountName')]",
["properties"] = new Dictionary<string, object?>
{
},
["sku"] = new Dictionary<string, object?>
{
["name"] = "[parameters('storageAccountType')]",
},
["type"] = "Microsoft.Storage/storageAccounts",
},
},
["variables"] = new Dictionary<string, object?>
{
["storageAccountName"] = "[concat(uniquestring(resourceGroup().id), 'standardsa')]",
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.blueprint.TemplateArtifact;
import com.pulumi.azurenative.blueprint.TemplateArtifactArgs;
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 templateArtifact = new TemplateArtifact("templateArtifact", TemplateArtifactArgs.builder()
.artifactName("storageTemplate")
.blueprintName("simpleBlueprint")
.kind("template")
.parameters(Map.of("storageAccountType", ParameterValueArgs.builder()
.value("[parameters('storageAccountType')]")
.build()))
.resourceGroup("storageRG")
.resourceScope("providers/Microsoft.Management/managementGroups/ContosoOnlineGroup")
.template(Map.ofEntries(
Map.entry("contentVersion", "1.0.0.0"),
Map.entry("outputs", Map.of("storageAccountName", Map.ofEntries(
Map.entry("type", "string"),
Map.entry("value", "[variables('storageAccountName')]")
))),
Map.entry("parameters", Map.of("storageAccountType", Map.ofEntries(
Map.entry("allowedValues",
"Standard_LRS",
"Standard_GRS",
"Standard_ZRS",
"Premium_LRS"),
Map.entry("defaultValue", "Standard_LRS"),
Map.entry("metadata", Map.of("description", "Storage Account type")),
Map.entry("type", "string")
))),
Map.entry("resources", Map.ofEntries(
Map.entry("apiVersion", "2016-01-01"),
Map.entry("kind", "Storage"),
Map.entry("location", "[resourceGroup().location]"),
Map.entry("name", "[variables('storageAccountName')]"),
Map.entry("properties", Map.ofEntries(
)),
Map.entry("sku", Map.of("name", "[parameters('storageAccountType')]")),
Map.entry("type", "Microsoft.Storage/storageAccounts")
)),
Map.entry("variables", Map.of("storageAccountName", "[concat(uniquestring(resourceGroup().id), 'standardsa')]"))
))
.build());
}
}
resources:
templateArtifact:
type: azure-native:blueprint:TemplateArtifact
properties:
artifactName: storageTemplate
blueprintName: simpleBlueprint
kind: template
parameters:
storageAccountType:
value: '[parameters(''storageAccountType'')]'
resourceGroup: storageRG
resourceScope: providers/Microsoft.Management/managementGroups/ContosoOnlineGroup
template:
contentVersion: 1.0.0.0
outputs:
storageAccountName:
type: string
value: '[variables(''storageAccountName'')]'
parameters:
storageAccountType:
allowedValues:
- Standard_LRS
- Standard_GRS
- Standard_ZRS
- Premium_LRS
defaultValue: Standard_LRS
metadata:
description: Storage Account type
type: string
resources:
- apiVersion: 2016-01-01
kind: Storage
location: '[resourceGroup().location]'
name: '[variables(''storageAccountName'')]'
properties: {}
sku:
name: '[parameters(''storageAccountType'')]'
type: Microsoft.Storage/storageAccounts
variables:
storageAccountName: '[concat(uniquestring(resourceGroup().id), ''standardsa'')]'
The template property contains a complete ARM template JSON structure with parameters, variables, resources, and outputs. The parameters property maps blueprint parameters to template parameters using ARM template expressions like [parameters('storageAccountType')]. The resourceGroup property specifies which blueprint resource group placeholder receives the deployed resources. The resourceScope determines whether this artifact lives at the management group or subscription level.
Beyond these examples
These snippets focus on specific template artifact features: ARM template embedding, parameter mapping, and scope targeting (management groups vs subscriptions). They’re intentionally minimal rather than full blueprint definitions.
The examples reference pre-existing infrastructure such as blueprint definitions (blueprintName) and resource scopes (management groups or subscriptions). They focus on configuring the artifact rather than provisioning the entire blueprint hierarchy.
To keep things focused, common artifact patterns are omitted, including:
- Artifact dependencies (dependsOn property)
- Display names and descriptions for documentation
- Policy assignment and role assignment artifacts (shown in minimal form only)
- Complex ARM template structures beyond basic storage accounts
These omissions are intentional: the goal is to illustrate how template artifacts are wired into blueprints, not provide drop-in governance modules. See the TemplateArtifact resource reference for all available configuration options.
Let's deploy Azure Blueprint Template Artifacts
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Configuration & Setup
artifactName, blueprintName, and resourceScope properties are immutable and cannot be modified after creation. Changes to these require recreating the artifact.resourceScope with either management group format (/providers/Microsoft.Management/managementGroups/{managementGroup}) or subscription format (/subscriptions/{subscriptionId}).kind to "template" for template artifacts. This is a required field.Parameters & Templates
[parameters('parameterName')] in the parameters field. For example: value: "[parameters('storageAccountType')]".template property contains a standard ARM template with contentVersion, parameters, variables, resources, and outputs sections.Deployment & Dependencies
resourceGroup property to specify the name of the resource group placeholder where the template will be deployed.dependsOn array to list artifact names that must be deployed before this artifact. This ensures proper deployment sequencing.artifactName identifies this specific artifact within the blueprint, while blueprintName identifies the parent blueprint definition that contains this artifact.Using a different cloud?
Explore integration guides for other cloud providers: