Create Azure Blob Storage Containers

The azure-native:storage:BlobContainer resource, part of the Pulumi Azure Native provider, defines a blob container within an Azure Storage account: its name, encryption settings, and immutability policies. This guide focuses on three capabilities: basic container creation, encryption scope enforcement, and object-level immutability for compliance.

Blob containers belong to storage accounts and resource groups that must exist before container creation. The examples are intentionally small. Combine them with your own storage accounts, encryption scopes, and access policies.

Create a basic blob container

Most deployments start by creating a blob container within an existing storage account to organize blobs.

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

const blobContainer = new azure_native.storage.BlobContainer("blobContainer", {
    accountName: "sto328",
    containerName: "container6185",
    resourceGroupName: "res3376",
});
import pulumi
import pulumi_azure_native as azure_native

blob_container = azure_native.storage.BlobContainer("blobContainer",
    account_name="sto328",
    container_name="container6185",
    resource_group_name="res3376")
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := storage.NewBlobContainer(ctx, "blobContainer", &storage.BlobContainerArgs{
			AccountName:       pulumi.String("sto328"),
			ContainerName:     pulumi.String("container6185"),
			ResourceGroupName: pulumi.String("res3376"),
		})
		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 blobContainer = new AzureNative.Storage.BlobContainer("blobContainer", new()
    {
        AccountName = "sto328",
        ContainerName = "container6185",
        ResourceGroupName = "res3376",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.storage.BlobContainer;
import com.pulumi.azurenative.storage.BlobContainerArgs;
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 blobContainer = new BlobContainer("blobContainer", BlobContainerArgs.builder()
            .accountName("sto328")
            .containerName("container6185")
            .resourceGroupName("res3376")
            .build());

    }
}
resources:
  blobContainer:
    type: azure-native:storage:BlobContainer
    properties:
      accountName: sto328
      containerName: container6185
      resourceGroupName: res3376

The accountName references the storage account that will host the container. The containerName must be between 3 and 63 characters, using only lowercase letters, numbers, and dashes. The resourceGroupName identifies where the storage account lives. Without additional properties, the container uses default settings: private access, no encryption scope enforcement, and no immutability policies.

Enforce encryption scope for all container writes

Organizations with strict data governance often need to ensure all blobs use a specific encryption scope, preventing users from overriding it.

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

const blobContainer = new azure_native.storage.BlobContainer("blobContainer", {
    accountName: "sto328",
    containerName: "container6185",
    defaultEncryptionScope: "encryptionscope185",
    denyEncryptionScopeOverride: true,
    resourceGroupName: "res3376",
});
import pulumi
import pulumi_azure_native as azure_native

blob_container = azure_native.storage.BlobContainer("blobContainer",
    account_name="sto328",
    container_name="container6185",
    default_encryption_scope="encryptionscope185",
    deny_encryption_scope_override=True,
    resource_group_name="res3376")
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := storage.NewBlobContainer(ctx, "blobContainer", &storage.BlobContainerArgs{
			AccountName:                 pulumi.String("sto328"),
			ContainerName:               pulumi.String("container6185"),
			DefaultEncryptionScope:      pulumi.String("encryptionscope185"),
			DenyEncryptionScopeOverride: pulumi.Bool(true),
			ResourceGroupName:           pulumi.String("res3376"),
		})
		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 blobContainer = new AzureNative.Storage.BlobContainer("blobContainer", new()
    {
        AccountName = "sto328",
        ContainerName = "container6185",
        DefaultEncryptionScope = "encryptionscope185",
        DenyEncryptionScopeOverride = true,
        ResourceGroupName = "res3376",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.storage.BlobContainer;
import com.pulumi.azurenative.storage.BlobContainerArgs;
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 blobContainer = new BlobContainer("blobContainer", BlobContainerArgs.builder()
            .accountName("sto328")
            .containerName("container6185")
            .defaultEncryptionScope("encryptionscope185")
            .denyEncryptionScopeOverride(true)
            .resourceGroupName("res3376")
            .build());

    }
}
resources:
  blobContainer:
    type: azure-native:storage:BlobContainer
    properties:
      accountName: sto328
      containerName: container6185
      defaultEncryptionScope: encryptionscope185
      denyEncryptionScopeOverride: true
      resourceGroupName: res3376

The defaultEncryptionScope property sets which encryption scope the container uses for all writes. When denyEncryptionScopeOverride is true, users cannot specify a different encryption scope when uploading blobs. This ensures consistent encryption across all container data, meeting compliance requirements that mandate specific key management.

Enable object-level immutability with versioning

Compliance and regulatory requirements often mandate write-once-read-many storage where blobs cannot be modified or deleted.

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

const blobContainer = new azure_native.storage.BlobContainer("blobContainer", {
    accountName: "sto328",
    containerName: "container6185",
    immutableStorageWithVersioning: {
        enabled: true,
    },
    resourceGroupName: "res3376",
});
import pulumi
import pulumi_azure_native as azure_native

blob_container = azure_native.storage.BlobContainer("blobContainer",
    account_name="sto328",
    container_name="container6185",
    immutable_storage_with_versioning={
        "enabled": True,
    },
    resource_group_name="res3376")
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := storage.NewBlobContainer(ctx, "blobContainer", &storage.BlobContainerArgs{
			AccountName:   pulumi.String("sto328"),
			ContainerName: pulumi.String("container6185"),
			ImmutableStorageWithVersioning: &storage.ImmutableStorageWithVersioningArgs{
				Enabled: pulumi.Bool(true),
			},
			ResourceGroupName: pulumi.String("res3376"),
		})
		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 blobContainer = new AzureNative.Storage.BlobContainer("blobContainer", new()
    {
        AccountName = "sto328",
        ContainerName = "container6185",
        ImmutableStorageWithVersioning = new AzureNative.Storage.Inputs.ImmutableStorageWithVersioningArgs
        {
            Enabled = true,
        },
        ResourceGroupName = "res3376",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.storage.BlobContainer;
import com.pulumi.azurenative.storage.BlobContainerArgs;
import com.pulumi.azurenative.storage.inputs.ImmutableStorageWithVersioningArgs;
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 blobContainer = new BlobContainer("blobContainer", BlobContainerArgs.builder()
            .accountName("sto328")
            .containerName("container6185")
            .immutableStorageWithVersioning(ImmutableStorageWithVersioningArgs.builder()
                .enabled(true)
                .build())
            .resourceGroupName("res3376")
            .build());

    }
}
resources:
  blobContainer:
    type: azure-native:storage:BlobContainer
    properties:
      accountName: sto328
      containerName: container6185
      immutableStorageWithVersioning:
        enabled: true
      resourceGroupName: res3376

The immutableStorageWithVersioning property enables object-level WORM policies. When enabled is true, the container supports time-based retention policies and legal holds at the blob level. This property is immutable; you can only set it to true at container creation time. Existing containers must undergo a migration process to enable this feature.

Beyond these examples

These snippets focus on specific container-level features: container creation and naming, encryption scope enforcement, and object-level immutability. They’re intentionally minimal rather than full storage solutions.

The examples reference pre-existing infrastructure such as storage accounts and resource groups, and encryption scopes for the encryption example. They focus on configuring the container rather than provisioning the storage account itself.

To keep things focused, common container patterns are omitted, including:

  • Public access levels (publicAccess)
  • Container metadata (metadata)
  • NFSv3 squash settings (enableNfsV3AllSquash, enableNfsV3RootSquash)
  • Lease management and legal holds

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

Let's create Azure Blob Storage Containers

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

Try Pulumi Cloud for FREE

Frequently Asked Questions

Naming & Constraints
What are the naming requirements for blob containers?
Container names must be 3-63 characters long, using only numbers, lowercase letters, and dashes. Every dash must be immediately preceded and followed by a letter or number.
What are the naming requirements for storage accounts?
Storage account names must be 3-24 characters long, using only numbers and lowercase letters.
Immutability & Lifecycle
Can I rename my blob container after creation?
No, containerName is immutable. To rename a container, you must create a new container with the desired name and migrate your data.
Can I change the storage account name after creation?
No, accountName is immutable. Changing the storage account requires creating a new storage account and migrating resources.
Can I enable object-level immutability on an existing container?
The immutableStorageWithVersioning property can only be set to true at container creation time. Existing containers must undergo a migration process to enable this feature.
Encryption & Security
How do I enforce a default encryption scope for all writes?
Set defaultEncryptionScope to your encryption scope name and denyEncryptionScopeOverride to true to prevent clients from overriding the default scope.
How do I control public access to my container?
Use the publicAccess property to specify whether data in the container may be accessed publicly and the level of access permitted.
Advanced Features
How do I enable NFSv3 squash settings on my container?
Use enableNfsV3RootSquash for root squash or enableNfsV3AllSquash for all squash on your blob container.

Using a different cloud?

Explore storage guides for other cloud providers: