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 FREEFrequently Asked Questions
Naming & Constraints
Immutability & Lifecycle
containerName is immutable. To rename a container, you must create a new container with the desired name and migrate your data.accountName is immutable. Changing the storage account requires creating a new storage account and migrating resources.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
defaultEncryptionScope to your encryption scope name and denyEncryptionScopeOverride to true to prevent clients from overriding the default scope.publicAccess property to specify whether data in the container may be accessed publicly and the level of access permitted.Advanced Features
enableNfsV3RootSquash for root squash or enableNfsV3AllSquash for all squash on your blob container.