Configure Azure Blob Storage Service Properties

The azure-native:storage:BlobServiceProperties resource, part of the Pulumi Azure Native provider, configures service-level settings for Azure Blob Storage: soft delete, versioning, change feed, CORS, and access tracking. This guide focuses on three capabilities: soft delete with permanent delete override, last access time tracking for lifecycle policies, and combined production settings.

This resource configures an existing storage account’s blob service. The storage account and resource group must already exist. The examples are intentionally small. Combine them with your own storage accounts and lifecycle policies.

Enable soft delete with permanent delete option

Teams protecting against accidental deletion enable soft delete to retain deleted blobs for a recovery period, while the allowPermanentDelete flag lets authorized users bypass soft delete for immediate removal of sensitive data.

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

const blobServiceProperties = new azure_native.storage.BlobServiceProperties("blobServiceProperties", {
    accountName: "sto8607",
    blobServicesName: "default",
    deleteRetentionPolicy: {
        allowPermanentDelete: true,
        days: 300,
        enabled: true,
    },
    isVersioningEnabled: true,
    resourceGroupName: "res4410",
});
import pulumi
import pulumi_azure_native as azure_native

blob_service_properties = azure_native.storage.BlobServiceProperties("blobServiceProperties",
    account_name="sto8607",
    blob_services_name="default",
    delete_retention_policy={
        "allow_permanent_delete": True,
        "days": 300,
        "enabled": True,
    },
    is_versioning_enabled=True,
    resource_group_name="res4410")
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.NewBlobServiceProperties(ctx, "blobServiceProperties", &storage.BlobServicePropertiesArgs{
			AccountName:      pulumi.String("sto8607"),
			BlobServicesName: pulumi.String("default"),
			DeleteRetentionPolicy: &storage.DeleteRetentionPolicyArgs{
				AllowPermanentDelete: pulumi.Bool(true),
				Days:                 pulumi.Int(300),
				Enabled:              pulumi.Bool(true),
			},
			IsVersioningEnabled: pulumi.Bool(true),
			ResourceGroupName:   pulumi.String("res4410"),
		})
		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 blobServiceProperties = new AzureNative.Storage.BlobServiceProperties("blobServiceProperties", new()
    {
        AccountName = "sto8607",
        BlobServicesName = "default",
        DeleteRetentionPolicy = new AzureNative.Storage.Inputs.DeleteRetentionPolicyArgs
        {
            AllowPermanentDelete = true,
            Days = 300,
            Enabled = true,
        },
        IsVersioningEnabled = true,
        ResourceGroupName = "res4410",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.storage.BlobServiceProperties;
import com.pulumi.azurenative.storage.BlobServicePropertiesArgs;
import com.pulumi.azurenative.storage.inputs.DeleteRetentionPolicyArgs;
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 blobServiceProperties = new BlobServiceProperties("blobServiceProperties", BlobServicePropertiesArgs.builder()
            .accountName("sto8607")
            .blobServicesName("default")
            .deleteRetentionPolicy(DeleteRetentionPolicyArgs.builder()
                .allowPermanentDelete(true)
                .days(300)
                .enabled(true)
                .build())
            .isVersioningEnabled(true)
            .resourceGroupName("res4410")
            .build());

    }
}
resources:
  blobServiceProperties:
    type: azure-native:storage:BlobServiceProperties
    properties:
      accountName: sto8607
      blobServicesName: default
      deleteRetentionPolicy:
        allowPermanentDelete: true
        days: 300
        enabled: true
      isVersioningEnabled: true
      resourceGroupName: res4410

When deleteRetentionPolicy is enabled, deleted blobs remain recoverable for the specified number of days. Setting allowPermanentDelete to true permits authorized operations to skip the retention period and delete immediately. The isVersioningEnabled property works alongside soft delete to preserve blob history.

Track last access time for lifecycle policies

Storage lifecycle policies can move or delete blobs based on when they were last accessed, reducing costs by tiering cold data automatically.

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

const blobServiceProperties = new azure_native.storage.BlobServiceProperties("blobServiceProperties", {
    accountName: "sto8607",
    blobServicesName: "default",
    lastAccessTimeTrackingPolicy: {
        blobType: ["blockBlob"],
        enable: true,
        name: azure_native.storage.Name.AccessTimeTracking,
        trackingGranularityInDays: 1,
    },
    resourceGroupName: "res4410",
});
import pulumi
import pulumi_azure_native as azure_native

blob_service_properties = azure_native.storage.BlobServiceProperties("blobServiceProperties",
    account_name="sto8607",
    blob_services_name="default",
    last_access_time_tracking_policy={
        "blob_type": ["blockBlob"],
        "enable": True,
        "name": azure_native.storage.Name.ACCESS_TIME_TRACKING,
        "tracking_granularity_in_days": 1,
    },
    resource_group_name="res4410")
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.NewBlobServiceProperties(ctx, "blobServiceProperties", &storage.BlobServicePropertiesArgs{
			AccountName:      pulumi.String("sto8607"),
			BlobServicesName: pulumi.String("default"),
			LastAccessTimeTrackingPolicy: &storage.LastAccessTimeTrackingPolicyArgs{
				BlobType: pulumi.StringArray{
					pulumi.String("blockBlob"),
				},
				Enable:                    pulumi.Bool(true),
				Name:                      pulumi.String(storage.NameAccessTimeTracking),
				TrackingGranularityInDays: pulumi.Int(1),
			},
			ResourceGroupName: pulumi.String("res4410"),
		})
		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 blobServiceProperties = new AzureNative.Storage.BlobServiceProperties("blobServiceProperties", new()
    {
        AccountName = "sto8607",
        BlobServicesName = "default",
        LastAccessTimeTrackingPolicy = new AzureNative.Storage.Inputs.LastAccessTimeTrackingPolicyArgs
        {
            BlobType = new[]
            {
                "blockBlob",
            },
            Enable = true,
            Name = AzureNative.Storage.Name.AccessTimeTracking,
            TrackingGranularityInDays = 1,
        },
        ResourceGroupName = "res4410",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.storage.BlobServiceProperties;
import com.pulumi.azurenative.storage.BlobServicePropertiesArgs;
import com.pulumi.azurenative.storage.inputs.LastAccessTimeTrackingPolicyArgs;
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 blobServiceProperties = new BlobServiceProperties("blobServiceProperties", BlobServicePropertiesArgs.builder()
            .accountName("sto8607")
            .blobServicesName("default")
            .lastAccessTimeTrackingPolicy(LastAccessTimeTrackingPolicyArgs.builder()
                .blobType("blockBlob")
                .enable(true)
                .name("AccessTimeTracking")
                .trackingGranularityInDays(1)
                .build())
            .resourceGroupName("res4410")
            .build());

    }
}
resources:
  blobServiceProperties:
    type: azure-native:storage:BlobServiceProperties
    properties:
      accountName: sto8607
      blobServicesName: default
      lastAccessTimeTrackingPolicy:
        blobType:
          - blockBlob
        enable: true
        name: AccessTimeTracking
        trackingGranularityInDays: 1
      resourceGroupName: res4410

The lastAccessTimeTrackingPolicy records read operations at the granularity you specify. Setting trackingGranularityInDays to 1 means access times update daily. The blobType array limits tracking to specific blob types; here, only block blobs are tracked. Lifecycle policies can then reference this access time to tier or delete cold data.

Configure comprehensive blob service settings

Production storage accounts typically combine soft delete, versioning, change feed for auditing, and CORS for browser access.

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

const blobServiceProperties = new azure_native.storage.BlobServiceProperties("blobServiceProperties", {
    accountName: "sto8607",
    blobServicesName: "default",
    changeFeed: {
        enabled: true,
        retentionInDays: 7,
    },
    cors: {
        corsRules: [
            {
                allowedHeaders: [
                    "x-ms-meta-abc",
                    "x-ms-meta-data*",
                    "x-ms-meta-target*",
                ],
                allowedMethods: [
                    azure_native.storage.AllowedMethods.GET,
                    azure_native.storage.AllowedMethods.HEAD,
                    azure_native.storage.AllowedMethods.POST,
                    azure_native.storage.AllowedMethods.OPTIONS,
                    azure_native.storage.AllowedMethods.MERGE,
                    azure_native.storage.AllowedMethods.PUT,
                ],
                allowedOrigins: [
                    "http://www.contoso.com",
                    "http://www.fabrikam.com",
                ],
                exposedHeaders: ["x-ms-meta-*"],
                maxAgeInSeconds: 100,
            },
            {
                allowedHeaders: ["*"],
                allowedMethods: [azure_native.storage.AllowedMethods.GET],
                allowedOrigins: ["*"],
                exposedHeaders: ["*"],
                maxAgeInSeconds: 2,
            },
            {
                allowedHeaders: ["x-ms-meta-12345675754564*"],
                allowedMethods: [
                    azure_native.storage.AllowedMethods.GET,
                    azure_native.storage.AllowedMethods.PUT,
                ],
                allowedOrigins: [
                    "http://www.abc23.com",
                    "https://www.fabrikam.com/*",
                ],
                exposedHeaders: [
                    "x-ms-meta-abc",
                    "x-ms-meta-data*",
                    "x -ms-meta-target*",
                ],
                maxAgeInSeconds: 2000,
            },
        ],
    },
    defaultServiceVersion: "2017-07-29",
    deleteRetentionPolicy: {
        days: 300,
        enabled: true,
    },
    isVersioningEnabled: true,
    resourceGroupName: "res4410",
});
import pulumi
import pulumi_azure_native as azure_native

blob_service_properties = azure_native.storage.BlobServiceProperties("blobServiceProperties",
    account_name="sto8607",
    blob_services_name="default",
    change_feed={
        "enabled": True,
        "retention_in_days": 7,
    },
    cors={
        "cors_rules": [
            {
                "allowed_headers": [
                    "x-ms-meta-abc",
                    "x-ms-meta-data*",
                    "x-ms-meta-target*",
                ],
                "allowed_methods": [
                    azure_native.storage.AllowedMethods.GET,
                    azure_native.storage.AllowedMethods.HEAD,
                    azure_native.storage.AllowedMethods.POST,
                    azure_native.storage.AllowedMethods.OPTIONS,
                    azure_native.storage.AllowedMethods.MERGE,
                    azure_native.storage.AllowedMethods.PUT,
                ],
                "allowed_origins": [
                    "http://www.contoso.com",
                    "http://www.fabrikam.com",
                ],
                "exposed_headers": ["x-ms-meta-*"],
                "max_age_in_seconds": 100,
            },
            {
                "allowed_headers": ["*"],
                "allowed_methods": [azure_native.storage.AllowedMethods.GET],
                "allowed_origins": ["*"],
                "exposed_headers": ["*"],
                "max_age_in_seconds": 2,
            },
            {
                "allowed_headers": ["x-ms-meta-12345675754564*"],
                "allowed_methods": [
                    azure_native.storage.AllowedMethods.GET,
                    azure_native.storage.AllowedMethods.PUT,
                ],
                "allowed_origins": [
                    "http://www.abc23.com",
                    "https://www.fabrikam.com/*",
                ],
                "exposed_headers": [
                    "x-ms-meta-abc",
                    "x-ms-meta-data*",
                    "x -ms-meta-target*",
                ],
                "max_age_in_seconds": 2000,
            },
        ],
    },
    default_service_version="2017-07-29",
    delete_retention_policy={
        "days": 300,
        "enabled": True,
    },
    is_versioning_enabled=True,
    resource_group_name="res4410")
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.NewBlobServiceProperties(ctx, "blobServiceProperties", &storage.BlobServicePropertiesArgs{
			AccountName:      pulumi.String("sto8607"),
			BlobServicesName: pulumi.String("default"),
			ChangeFeed: &storage.ChangeFeedArgs{
				Enabled:         pulumi.Bool(true),
				RetentionInDays: pulumi.Int(7),
			},
			Cors: &storage.CorsRulesArgs{
				CorsRules: storage.CorsRuleArray{
					&storage.CorsRuleArgs{
						AllowedHeaders: pulumi.StringArray{
							pulumi.String("x-ms-meta-abc"),
							pulumi.String("x-ms-meta-data*"),
							pulumi.String("x-ms-meta-target*"),
						},
						AllowedMethods: pulumi.StringArray{
							pulumi.String(storage.AllowedMethodsGET),
							pulumi.String(storage.AllowedMethodsHEAD),
							pulumi.String(storage.AllowedMethodsPOST),
							pulumi.String(storage.AllowedMethodsOPTIONS),
							pulumi.String(storage.AllowedMethodsMERGE),
							pulumi.String(storage.AllowedMethodsPUT),
						},
						AllowedOrigins: pulumi.StringArray{
							pulumi.String("http://www.contoso.com"),
							pulumi.String("http://www.fabrikam.com"),
						},
						ExposedHeaders: pulumi.StringArray{
							pulumi.String("x-ms-meta-*"),
						},
						MaxAgeInSeconds: pulumi.Int(100),
					},
					&storage.CorsRuleArgs{
						AllowedHeaders: pulumi.StringArray{
							pulumi.String("*"),
						},
						AllowedMethods: pulumi.StringArray{
							pulumi.String(storage.AllowedMethodsGET),
						},
						AllowedOrigins: pulumi.StringArray{
							pulumi.String("*"),
						},
						ExposedHeaders: pulumi.StringArray{
							pulumi.String("*"),
						},
						MaxAgeInSeconds: pulumi.Int(2),
					},
					&storage.CorsRuleArgs{
						AllowedHeaders: pulumi.StringArray{
							pulumi.String("x-ms-meta-12345675754564*"),
						},
						AllowedMethods: pulumi.StringArray{
							pulumi.String(storage.AllowedMethodsGET),
							pulumi.String(storage.AllowedMethodsPUT),
						},
						AllowedOrigins: pulumi.StringArray{
							pulumi.String("http://www.abc23.com"),
							pulumi.String("https://www.fabrikam.com/*"),
						},
						ExposedHeaders: pulumi.StringArray{
							pulumi.String("x-ms-meta-abc"),
							pulumi.String("x-ms-meta-data*"),
							pulumi.String("x -ms-meta-target*"),
						},
						MaxAgeInSeconds: pulumi.Int(2000),
					},
				},
			},
			DefaultServiceVersion: pulumi.String("2017-07-29"),
			DeleteRetentionPolicy: &storage.DeleteRetentionPolicyArgs{
				Days:    pulumi.Int(300),
				Enabled: pulumi.Bool(true),
			},
			IsVersioningEnabled: pulumi.Bool(true),
			ResourceGroupName:   pulumi.String("res4410"),
		})
		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 blobServiceProperties = new AzureNative.Storage.BlobServiceProperties("blobServiceProperties", new()
    {
        AccountName = "sto8607",
        BlobServicesName = "default",
        ChangeFeed = new AzureNative.Storage.Inputs.ChangeFeedArgs
        {
            Enabled = true,
            RetentionInDays = 7,
        },
        Cors = new AzureNative.Storage.Inputs.CorsRulesArgs
        {
            CorsRules = new[]
            {
                new AzureNative.Storage.Inputs.CorsRuleArgs
                {
                    AllowedHeaders = new[]
                    {
                        "x-ms-meta-abc",
                        "x-ms-meta-data*",
                        "x-ms-meta-target*",
                    },
                    AllowedMethods = new[]
                    {
                        AzureNative.Storage.AllowedMethods.GET,
                        AzureNative.Storage.AllowedMethods.HEAD,
                        AzureNative.Storage.AllowedMethods.POST,
                        AzureNative.Storage.AllowedMethods.OPTIONS,
                        AzureNative.Storage.AllowedMethods.MERGE,
                        AzureNative.Storage.AllowedMethods.PUT,
                    },
                    AllowedOrigins = new[]
                    {
                        "http://www.contoso.com",
                        "http://www.fabrikam.com",
                    },
                    ExposedHeaders = new[]
                    {
                        "x-ms-meta-*",
                    },
                    MaxAgeInSeconds = 100,
                },
                new AzureNative.Storage.Inputs.CorsRuleArgs
                {
                    AllowedHeaders = new[]
                    {
                        "*",
                    },
                    AllowedMethods = new[]
                    {
                        AzureNative.Storage.AllowedMethods.GET,
                    },
                    AllowedOrigins = new[]
                    {
                        "*",
                    },
                    ExposedHeaders = new[]
                    {
                        "*",
                    },
                    MaxAgeInSeconds = 2,
                },
                new AzureNative.Storage.Inputs.CorsRuleArgs
                {
                    AllowedHeaders = new[]
                    {
                        "x-ms-meta-12345675754564*",
                    },
                    AllowedMethods = new[]
                    {
                        AzureNative.Storage.AllowedMethods.GET,
                        AzureNative.Storage.AllowedMethods.PUT,
                    },
                    AllowedOrigins = new[]
                    {
                        "http://www.abc23.com",
                        "https://www.fabrikam.com/*",
                    },
                    ExposedHeaders = new[]
                    {
                        "x-ms-meta-abc",
                        "x-ms-meta-data*",
                        "x -ms-meta-target*",
                    },
                    MaxAgeInSeconds = 2000,
                },
            },
        },
        DefaultServiceVersion = "2017-07-29",
        DeleteRetentionPolicy = new AzureNative.Storage.Inputs.DeleteRetentionPolicyArgs
        {
            Days = 300,
            Enabled = true,
        },
        IsVersioningEnabled = true,
        ResourceGroupName = "res4410",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.storage.BlobServiceProperties;
import com.pulumi.azurenative.storage.BlobServicePropertiesArgs;
import com.pulumi.azurenative.storage.inputs.ChangeFeedArgs;
import com.pulumi.azurenative.storage.inputs.CorsRulesArgs;
import com.pulumi.azurenative.storage.inputs.DeleteRetentionPolicyArgs;
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 blobServiceProperties = new BlobServiceProperties("blobServiceProperties", BlobServicePropertiesArgs.builder()
            .accountName("sto8607")
            .blobServicesName("default")
            .changeFeed(ChangeFeedArgs.builder()
                .enabled(true)
                .retentionInDays(7)
                .build())
            .cors(CorsRulesArgs.builder()
                .corsRules(                
                    CorsRuleArgs.builder()
                        .allowedHeaders(                        
                            "x-ms-meta-abc",
                            "x-ms-meta-data*",
                            "x-ms-meta-target*")
                        .allowedMethods(                        
                            "GET",
                            "HEAD",
                            "POST",
                            "OPTIONS",
                            "MERGE",
                            "PUT")
                        .allowedOrigins(                        
                            "http://www.contoso.com",
                            "http://www.fabrikam.com")
                        .exposedHeaders("x-ms-meta-*")
                        .maxAgeInSeconds(100)
                        .build(),
                    CorsRuleArgs.builder()
                        .allowedHeaders("*")
                        .allowedMethods("GET")
                        .allowedOrigins("*")
                        .exposedHeaders("*")
                        .maxAgeInSeconds(2)
                        .build(),
                    CorsRuleArgs.builder()
                        .allowedHeaders("x-ms-meta-12345675754564*")
                        .allowedMethods(                        
                            "GET",
                            "PUT")
                        .allowedOrigins(                        
                            "http://www.abc23.com",
                            "https://www.fabrikam.com/*")
                        .exposedHeaders(                        
                            "x-ms-meta-abc",
                            "x-ms-meta-data*",
                            "x -ms-meta-target*")
                        .maxAgeInSeconds(2000)
                        .build())
                .build())
            .defaultServiceVersion("2017-07-29")
            .deleteRetentionPolicy(DeleteRetentionPolicyArgs.builder()
                .days(300)
                .enabled(true)
                .build())
            .isVersioningEnabled(true)
            .resourceGroupName("res4410")
            .build());

    }
}
resources:
  blobServiceProperties:
    type: azure-native:storage:BlobServiceProperties
    properties:
      accountName: sto8607
      blobServicesName: default
      changeFeed:
        enabled: true
        retentionInDays: 7
      cors:
        corsRules:
          - allowedHeaders:
              - x-ms-meta-abc
              - x-ms-meta-data*
              - x-ms-meta-target*
            allowedMethods:
              - GET
              - HEAD
              - POST
              - OPTIONS
              - MERGE
              - PUT
            allowedOrigins:
              - http://www.contoso.com
              - http://www.fabrikam.com
            exposedHeaders:
              - x-ms-meta-*
            maxAgeInSeconds: 100
          - allowedHeaders:
              - '*'
            allowedMethods:
              - GET
            allowedOrigins:
              - '*'
            exposedHeaders:
              - '*'
            maxAgeInSeconds: 2
          - allowedHeaders:
              - x-ms-meta-12345675754564*
            allowedMethods:
              - GET
              - PUT
            allowedOrigins:
              - http://www.abc23.com
              - https://www.fabrikam.com/*
            exposedHeaders:
              - x-ms-meta-abc
              - x-ms-meta-data*
              - x -ms-meta-target*
            maxAgeInSeconds: 2000
      defaultServiceVersion: 2017-07-29
      deleteRetentionPolicy:
        days: 300
        enabled: true
      isVersioningEnabled: true
      resourceGroupName: res4410

This configuration enables multiple features together. The changeFeed property records all blob operations for auditing, retaining events for the specified days. The cors property defines rules for cross-origin browser requests: which origins, methods, and headers are allowed. The defaultServiceVersion sets the API version for requests that don’t specify one. All these features operate independently but share the same blob service configuration.

Beyond these examples

These snippets focus on specific blob service features: soft delete and versioning, last access time tracking, and change feed and CORS configuration. They’re intentionally minimal rather than full storage solutions.

The examples reference pre-existing infrastructure such as Azure storage accounts and resource groups. They focus on configuring the blob service rather than provisioning the storage account itself.

To keep things focused, common blob service patterns are omitted, including:

  • Container-level soft delete (containerDeleteRetentionPolicy)
  • Point-in-time restore (restorePolicy)
  • Automatic snapshot policies (automaticSnapshotPolicyEnabled)

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

Let's configure Azure Blob Storage Service Properties

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

Try Pulumi Cloud for FREE

Frequently Asked Questions

Resource Configuration & Constraints
Why must blobServicesName always be 'default'?
The blobServicesName parameter only accepts the value default and cannot be changed after creation.
What properties can't I change after creating the resource?
Three properties are immutable: accountName, blobServicesName, and resourceGroupName. You must recreate the resource to change any of these.
What are the naming requirements for storage accounts?
Storage account names must be between 3 and 24 characters in length and use only numbers and lowercase letters.
Data Protection & Retention
Should I use automaticSnapshotPolicyEnabled or isVersioningEnabled?
Use isVersioningEnabled for new configurations. The automaticSnapshotPolicyEnabled property is deprecated.
How do I enable soft delete for blobs?
Configure deleteRetentionPolicy with enabled: true and specify the retention period in days (e.g., 300 days).
What does allowPermanentDelete do in the delete retention policy?
When set to true in deleteRetentionPolicy, it allows permanent deletion of soft-deleted blobs before the retention period expires.
How do I enable change feed for blob events?
Set changeFeed with enabled: true and optionally specify retentionInDays for how long to keep change feed events.
How do I enable blob versioning?
Set isVersioningEnabled: true to enable versioning for blobs in the storage account.
Access & CORS Configuration
How many CORS rules can I configure?
You can include up to five CorsRule elements. If no rules are included, all CORS rules will be deleted and CORS will be disabled.
How do I track last access time for blobs?
Configure lastAccessTimeTrackingPolicy with enable: true, specify blobType (e.g., blockBlob), and set trackingGranularityInDays (e.g., 1 for daily tracking).

Using a different cloud?

Explore storage guides for other cloud providers: