Configure Azure Storage Cache Targets

The azure-native:storagecache:StorageTarget resource, part of the Pulumi Azure Native provider, defines a storage target within an Azure HPC Cache: the backend storage system and how it maps into the cache’s namespace. This guide focuses on three capabilities: NFS and Blob NFS target configuration, namespace junction mapping, and usage models and cache timing.

Storage targets belong to an existing Azure HPC Cache and reference backend storage systems such as NFS servers or Azure Storage accounts. The examples are intentionally small. Combine them with your own cache instances and storage infrastructure.

Connect NFS storage with namespace junctions

HPC workloads often aggregate multiple NFS exports into a unified namespace, allowing clients to access different storage paths through a single mount point.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const storageTarget = new azure_native.storagecache.StorageTarget("storageTarget", {
    cacheName: "sc1",
    junctions: [
        {
            namespacePath: "/path/on/cache",
            nfsAccessPolicy: "default",
            nfsExport: "exp1",
            targetPath: "/path/on/exp1",
        },
        {
            namespacePath: "/path2/on/cache",
            nfsAccessPolicy: "rootSquash",
            nfsExport: "exp2",
            targetPath: "/path2/on/exp2",
        },
    ],
    nfs3: {
        target: "10.0.44.44",
        usageModel: "READ_ONLY",
        verificationTimer: 30,
    },
    resourceGroupName: "scgroup",
    storageTargetName: "st1",
    targetType: azure_native.storagecache.StorageTargetType.Nfs3,
});
import pulumi
import pulumi_azure_native as azure_native

storage_target = azure_native.storagecache.StorageTarget("storageTarget",
    cache_name="sc1",
    junctions=[
        {
            "namespace_path": "/path/on/cache",
            "nfs_access_policy": "default",
            "nfs_export": "exp1",
            "target_path": "/path/on/exp1",
        },
        {
            "namespace_path": "/path2/on/cache",
            "nfs_access_policy": "rootSquash",
            "nfs_export": "exp2",
            "target_path": "/path2/on/exp2",
        },
    ],
    nfs3={
        "target": "10.0.44.44",
        "usage_model": "READ_ONLY",
        "verification_timer": 30,
    },
    resource_group_name="scgroup",
    storage_target_name="st1",
    target_type=azure_native.storagecache.StorageTargetType.NFS3)
package main

import (
	storagecache "github.com/pulumi/pulumi-azure-native-sdk/storagecache/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := storagecache.NewStorageTarget(ctx, "storageTarget", &storagecache.StorageTargetArgs{
			CacheName: pulumi.String("sc1"),
			Junctions: storagecache.NamespaceJunctionArray{
				&storagecache.NamespaceJunctionArgs{
					NamespacePath:   pulumi.String("/path/on/cache"),
					NfsAccessPolicy: pulumi.String("default"),
					NfsExport:       pulumi.String("exp1"),
					TargetPath:      pulumi.String("/path/on/exp1"),
				},
				&storagecache.NamespaceJunctionArgs{
					NamespacePath:   pulumi.String("/path2/on/cache"),
					NfsAccessPolicy: pulumi.String("rootSquash"),
					NfsExport:       pulumi.String("exp2"),
					TargetPath:      pulumi.String("/path2/on/exp2"),
				},
			},
			Nfs3: &storagecache.Nfs3TargetArgs{
				Target:            pulumi.String("10.0.44.44"),
				UsageModel:        pulumi.String("READ_ONLY"),
				VerificationTimer: pulumi.Int(30),
			},
			ResourceGroupName: pulumi.String("scgroup"),
			StorageTargetName: pulumi.String("st1"),
			TargetType:        pulumi.String(storagecache.StorageTargetTypeNfs3),
		})
		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 storageTarget = new AzureNative.StorageCache.StorageTarget("storageTarget", new()
    {
        CacheName = "sc1",
        Junctions = new[]
        {
            new AzureNative.StorageCache.Inputs.NamespaceJunctionArgs
            {
                NamespacePath = "/path/on/cache",
                NfsAccessPolicy = "default",
                NfsExport = "exp1",
                TargetPath = "/path/on/exp1",
            },
            new AzureNative.StorageCache.Inputs.NamespaceJunctionArgs
            {
                NamespacePath = "/path2/on/cache",
                NfsAccessPolicy = "rootSquash",
                NfsExport = "exp2",
                TargetPath = "/path2/on/exp2",
            },
        },
        Nfs3 = new AzureNative.StorageCache.Inputs.Nfs3TargetArgs
        {
            Target = "10.0.44.44",
            UsageModel = "READ_ONLY",
            VerificationTimer = 30,
        },
        ResourceGroupName = "scgroup",
        StorageTargetName = "st1",
        TargetType = AzureNative.StorageCache.StorageTargetType.Nfs3,
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.storagecache.StorageTarget;
import com.pulumi.azurenative.storagecache.StorageTargetArgs;
import com.pulumi.azurenative.storagecache.inputs.NamespaceJunctionArgs;
import com.pulumi.azurenative.storagecache.inputs.Nfs3TargetArgs;
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 storageTarget = new StorageTarget("storageTarget", StorageTargetArgs.builder()
            .cacheName("sc1")
            .junctions(            
                NamespaceJunctionArgs.builder()
                    .namespacePath("/path/on/cache")
                    .nfsAccessPolicy("default")
                    .nfsExport("exp1")
                    .targetPath("/path/on/exp1")
                    .build(),
                NamespaceJunctionArgs.builder()
                    .namespacePath("/path2/on/cache")
                    .nfsAccessPolicy("rootSquash")
                    .nfsExport("exp2")
                    .targetPath("/path2/on/exp2")
                    .build())
            .nfs3(Nfs3TargetArgs.builder()
                .target("10.0.44.44")
                .usageModel("READ_ONLY")
                .verificationTimer(30)
                .build())
            .resourceGroupName("scgroup")
            .storageTargetName("st1")
            .targetType("nfs3")
            .build());

    }
}
resources:
  storageTarget:
    type: azure-native:storagecache:StorageTarget
    properties:
      cacheName: sc1
      junctions:
        - namespacePath: /path/on/cache
          nfsAccessPolicy: default
          nfsExport: exp1
          targetPath: /path/on/exp1
        - namespacePath: /path2/on/cache
          nfsAccessPolicy: rootSquash
          nfsExport: exp2
          targetPath: /path2/on/exp2
      nfs3:
        target: 10.0.44.44
        usageModel: READ_ONLY
        verificationTimer: 30
      resourceGroupName: scgroup
      storageTargetName: st1
      targetType: nfs3

The nfs3 block specifies the NFS server IP and usage model (READ_ONLY optimizes for read-heavy workloads). The junctions array maps NFS exports to cache namespace paths: namespacePath defines the client-visible path, while nfsExport and targetPath identify the backend export and directory. The nfsAccessPolicy controls root squashing and access rules for each junction.

Attach Azure Blob storage with NFS protocol

Azure HPC Cache can front Azure Blob containers that support NFS 3.0, providing low-latency access to cloud object storage.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const storageTarget = new azure_native.storagecache.StorageTarget("storageTarget", {
    blobNfs: {
        target: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/scgroup/providers/Microsoft.Storage/storageAccounts/blofnfs/blobServices/default/containers/blobnfs",
        usageModel: "READ_WRITE",
        verificationTimer: 28800,
        writeBackTimer: 3600,
    },
    cacheName: "sc1",
    junctions: [{
        namespacePath: "/blobnfs",
    }],
    resourceGroupName: "scgroup",
    storageTargetName: "st1",
    targetType: azure_native.storagecache.StorageTargetType.BlobNfs,
});
import pulumi
import pulumi_azure_native as azure_native

storage_target = azure_native.storagecache.StorageTarget("storageTarget",
    blob_nfs={
        "target": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/scgroup/providers/Microsoft.Storage/storageAccounts/blofnfs/blobServices/default/containers/blobnfs",
        "usage_model": "READ_WRITE",
        "verification_timer": 28800,
        "write_back_timer": 3600,
    },
    cache_name="sc1",
    junctions=[{
        "namespace_path": "/blobnfs",
    }],
    resource_group_name="scgroup",
    storage_target_name="st1",
    target_type=azure_native.storagecache.StorageTargetType.BLOB_NFS)
package main

import (
	storagecache "github.com/pulumi/pulumi-azure-native-sdk/storagecache/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := storagecache.NewStorageTarget(ctx, "storageTarget", &storagecache.StorageTargetArgs{
			BlobNfs: &storagecache.BlobNfsTargetArgs{
				Target:            pulumi.String("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/scgroup/providers/Microsoft.Storage/storageAccounts/blofnfs/blobServices/default/containers/blobnfs"),
				UsageModel:        pulumi.String("READ_WRITE"),
				VerificationTimer: pulumi.Int(28800),
				WriteBackTimer:    pulumi.Int(3600),
			},
			CacheName: pulumi.String("sc1"),
			Junctions: storagecache.NamespaceJunctionArray{
				&storagecache.NamespaceJunctionArgs{
					NamespacePath: pulumi.String("/blobnfs"),
				},
			},
			ResourceGroupName: pulumi.String("scgroup"),
			StorageTargetName: pulumi.String("st1"),
			TargetType:        pulumi.String(storagecache.StorageTargetTypeBlobNfs),
		})
		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 storageTarget = new AzureNative.StorageCache.StorageTarget("storageTarget", new()
    {
        BlobNfs = new AzureNative.StorageCache.Inputs.BlobNfsTargetArgs
        {
            Target = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/scgroup/providers/Microsoft.Storage/storageAccounts/blofnfs/blobServices/default/containers/blobnfs",
            UsageModel = "READ_WRITE",
            VerificationTimer = 28800,
            WriteBackTimer = 3600,
        },
        CacheName = "sc1",
        Junctions = new[]
        {
            new AzureNative.StorageCache.Inputs.NamespaceJunctionArgs
            {
                NamespacePath = "/blobnfs",
            },
        },
        ResourceGroupName = "scgroup",
        StorageTargetName = "st1",
        TargetType = AzureNative.StorageCache.StorageTargetType.BlobNfs,
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.storagecache.StorageTarget;
import com.pulumi.azurenative.storagecache.StorageTargetArgs;
import com.pulumi.azurenative.storagecache.inputs.BlobNfsTargetArgs;
import com.pulumi.azurenative.storagecache.inputs.NamespaceJunctionArgs;
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 storageTarget = new StorageTarget("storageTarget", StorageTargetArgs.builder()
            .blobNfs(BlobNfsTargetArgs.builder()
                .target("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/scgroup/providers/Microsoft.Storage/storageAccounts/blofnfs/blobServices/default/containers/blobnfs")
                .usageModel("READ_WRITE")
                .verificationTimer(28800)
                .writeBackTimer(3600)
                .build())
            .cacheName("sc1")
            .junctions(NamespaceJunctionArgs.builder()
                .namespacePath("/blobnfs")
                .build())
            .resourceGroupName("scgroup")
            .storageTargetName("st1")
            .targetType("blobNfs")
            .build());

    }
}
resources:
  storageTarget:
    type: azure-native:storagecache:StorageTarget
    properties:
      blobNfs:
        target: /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/scgroup/providers/Microsoft.Storage/storageAccounts/blofnfs/blobServices/default/containers/blobnfs
        usageModel: READ_WRITE
        verificationTimer: 28800
        writeBackTimer: 3600
      cacheName: sc1
      junctions:
        - namespacePath: /blobnfs
      resourceGroupName: scgroup
      storageTargetName: st1
      targetType: blobNfs

The blobNfs block references an Azure Storage container via its full ARM resource ID. The usageModel set to READ_WRITE enables caching for both reads and writes. The verificationTimer (28800 seconds, or 8 hours) controls how often the cache checks for backend changes, while writeBackTimer (3600 seconds, or 1 hour) determines how frequently cached writes flush to blob storage.

Configure storage target without namespace junctions

Some deployments defer namespace configuration, creating the storage target first and adding junctions later.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const storageTarget = new azure_native.storagecache.StorageTarget("storageTarget", {
    cacheName: "sc1",
    nfs3: {
        target: "10.0.44.44",
        usageModel: "READ_ONLY",
        verificationTimer: 30,
    },
    resourceGroupName: "scgroup",
    storageTargetName: "st1",
    targetType: azure_native.storagecache.StorageTargetType.Nfs3,
});
import pulumi
import pulumi_azure_native as azure_native

storage_target = azure_native.storagecache.StorageTarget("storageTarget",
    cache_name="sc1",
    nfs3={
        "target": "10.0.44.44",
        "usage_model": "READ_ONLY",
        "verification_timer": 30,
    },
    resource_group_name="scgroup",
    storage_target_name="st1",
    target_type=azure_native.storagecache.StorageTargetType.NFS3)
package main

import (
	storagecache "github.com/pulumi/pulumi-azure-native-sdk/storagecache/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := storagecache.NewStorageTarget(ctx, "storageTarget", &storagecache.StorageTargetArgs{
			CacheName: pulumi.String("sc1"),
			Nfs3: &storagecache.Nfs3TargetArgs{
				Target:            pulumi.String("10.0.44.44"),
				UsageModel:        pulumi.String("READ_ONLY"),
				VerificationTimer: pulumi.Int(30),
			},
			ResourceGroupName: pulumi.String("scgroup"),
			StorageTargetName: pulumi.String("st1"),
			TargetType:        pulumi.String(storagecache.StorageTargetTypeNfs3),
		})
		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 storageTarget = new AzureNative.StorageCache.StorageTarget("storageTarget", new()
    {
        CacheName = "sc1",
        Nfs3 = new AzureNative.StorageCache.Inputs.Nfs3TargetArgs
        {
            Target = "10.0.44.44",
            UsageModel = "READ_ONLY",
            VerificationTimer = 30,
        },
        ResourceGroupName = "scgroup",
        StorageTargetName = "st1",
        TargetType = AzureNative.StorageCache.StorageTargetType.Nfs3,
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.storagecache.StorageTarget;
import com.pulumi.azurenative.storagecache.StorageTargetArgs;
import com.pulumi.azurenative.storagecache.inputs.Nfs3TargetArgs;
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 storageTarget = new StorageTarget("storageTarget", StorageTargetArgs.builder()
            .cacheName("sc1")
            .nfs3(Nfs3TargetArgs.builder()
                .target("10.0.44.44")
                .usageModel("READ_ONLY")
                .verificationTimer(30)
                .build())
            .resourceGroupName("scgroup")
            .storageTargetName("st1")
            .targetType("nfs3")
            .build());

    }
}
resources:
  storageTarget:
    type: azure-native:storagecache:StorageTarget
    properties:
      cacheName: sc1
      nfs3:
        target: 10.0.44.44
        usageModel: READ_ONLY
        verificationTimer: 30
      resourceGroupName: scgroup
      storageTargetName: st1
      targetType: nfs3

This minimal configuration creates an NFS target without junctions. You can add namespace mappings afterward by updating the storage target resource. This approach separates storage target provisioning from namespace design.

Beyond these examples

These snippets focus on specific storage target features: NFS and Blob NFS target types, namespace junction mapping, and usage models and cache timers. They’re intentionally minimal rather than full HPC cache deployments.

The examples reference pre-existing infrastructure such as Azure HPC Cache instances, NFS servers or Azure Storage accounts with NFS 3.0 enabled, and resource groups and subscriptions. They focus on configuring the storage target rather than provisioning the cache or backend storage.

To keep things focused, common storage target patterns are omitted, including:

  • Storage target state management (state property)
  • CLFS and unknown target types
  • Advanced verification and write-back tuning
  • Allocation percentage controls

These omissions are intentional: the goal is to illustrate how each storage target feature is wired, not provide drop-in HPC modules. See the StorageTarget resource reference for all available configuration options.

Let's configure Azure Storage Cache Targets

Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.

Try Pulumi Cloud for FREE

Frequently Asked Questions

Getting Started & Target Types
What storage target types are available?
You can create storage targets of type nfs3 (NFS servers), blobNfs (Azure Blob Storage with NFS), clfs, or unknown.
How do I connect to an NFS server?
Set targetType to nfs3 and configure the nfs3.target property with your NFS server’s IP address (e.g., 10.0.44.44).
How do I connect to Azure Blob Storage with NFS?
Set targetType to blobNfs and configure blobNfs.target with the full Azure resource path to your storage container (e.g., /subscriptions/.../containers/blobnfs).
Configuration & Junctions
Are junctions required when creating a storage target?
No, junctions are optional. You can create a storage target without specifying any junctions.
What's the difference between READ_ONLY and READ_WRITE usage models?
usageModel controls caching behavior. Examples show READ_ONLY for NFS3 targets and READ_WRITE for BlobNfs targets.
What NFS access policies can I configure for junctions?
You can set nfsAccessPolicy to default or rootSquash on individual junctions to control access permissions.
Immutability & Lifecycle
What properties can't be changed after creating a storage target?
The targetType, cacheName, storageTargetName, and resourceGroupName properties are all immutable and cannot be modified after creation.
Advanced Configuration
What is verificationTimer and how should I set it?
verificationTimer is a timer value in seconds that controls verification behavior. Examples show 30 seconds for NFS3 targets and 28800 seconds (8 hours) for BlobNfs targets.
What is writeBackTimer and when should I use it?
writeBackTimer is specific to BlobNfs targets and controls write-back caching behavior. The example shows a value of 3600 seconds (1 hour).

Using a different cloud?

Explore storage guides for other cloud providers: