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 & Setup
What properties can't I change after creating a template artifact?
The artifactName, blueprintName, and resourceScope properties are immutable and cannot be modified after creation. Changes to these require recreating the artifact.
How do I specify the scope for a template artifact?
Use resourceScope with either management group format (/providers/Microsoft.Management/managementGroups/{managementGroup}) or subscription format (/subscriptions/{subscriptionId}).
What value should I use for the kind property?
Set kind to "template" for template artifacts. This is a required field.
Parameters & Templates
How do I pass parameters from my blueprint to the ARM template?
Reference blueprint-level parameters using the syntax [parameters('parameterName')] in the parameters field. For example: value: "[parameters('storageAccountType')]".
What goes in the template property?
The template property contains a standard ARM template with contentVersion, parameters, variables, resources, and outputs sections.
Deployment & Dependencies
Can I deploy my template to a specific resource group?
Yes, use the resourceGroup property to specify the name of the resource group placeholder where the template will be deployed.
How do I control the order that artifacts are deployed?
Use the dependsOn array to list artifact names that must be deployed before this artifact. This ensures proper deployment sequencing.
What's the difference between artifactName and blueprintName?
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: