Deploy Azure Blueprint Template Artifacts

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 FREE

Frequently Asked Questions

Configuration & Scope
What's the difference between management group and subscription scope?
You can deploy artifacts at management group scope (format: /providers/Microsoft.Management/managementGroups/{managementGroup}) or subscription scope (format: /subscriptions/{subscriptionId}). Set this using the resourceScope property.
What does the resourceGroup property do?
The resourceGroup property specifies the name of the resource group placeholder where the ARM template will be deployed. This is optional and only applicable when deploying resources that require a resource group.
Why do I need to set kind to 'template'?
The kind property identifies this as an ARM template artifact (as opposed to policy or role assignment artifacts). It must be set to "template" for Resource Manager template deployments.
How do I control the order artifacts are deployed?
Use the dependsOn property with an array of artifact names that must be deployed before this artifact. This ensures proper deployment sequencing.
Immutability & Lifecycle
What properties can't I change after creating the artifact?
The artifactName, blueprintName, and resourceScope properties are immutable. Changing any of these requires recreating the artifact.
Is this API stable or still in preview?
This resource uses API version 2018-11-01-preview, which is a preview version. Be aware that preview APIs may have breaking changes in future releases.
Parameters & Templates
How do I reference blueprint parameters in my template?
Use the syntax [parameters('parameterName')] in the parameters property to reference blueprint-level parameters. For example, value: "[parameters('storageAccountType')]" references a blueprint parameter named storageAccountType.

Using a different cloud?

Explore integration guides for other cloud providers: