The azure-native:storage:BlobInventoryPolicy resource, part of the Pulumi Azure Native provider, defines automated inventory reporting for blob storage accounts: scheduling, filtering, schema selection, and destination configuration. This guide focuses on three capabilities: daily and weekly inventory schedules, prefix-based filtering and blob type selection, and schema customization for HNS and non-HNS accounts.
Blob inventory policies belong to storage accounts and write reports to destination containers. The examples are intentionally small. Combine them with your own storage account configuration and downstream report processing.
Generate daily blob inventories with filtering
Teams managing large storage accounts need visibility into blob metadata to track costs and plan lifecycle policies. Blob inventory policies automate this by generating scheduled reports in CSV or Parquet format.
import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";
const blobInventoryPolicy = new azure_native.storage.BlobInventoryPolicy("blobInventoryPolicy", {
accountName: "sto9699",
blobInventoryPolicyName: "default",
policy: {
enabled: true,
rules: [
{
definition: {
filters: {
blobTypes: [
"blockBlob",
"appendBlob",
"pageBlob",
],
creationTime: {
lastNDays: 1000,
},
includeBlobVersions: true,
includeSnapshots: true,
prefixMatch: [
"inventoryprefix1",
"inventoryprefix2",
],
},
format: azure_native.storage.Format.Csv,
objectType: azure_native.storage.ObjectType.Blob,
schedule: azure_native.storage.Schedule.Daily,
schemaFields: [
"Name",
"Creation-Time",
"Last-Modified",
"Content-Length",
"Content-MD5",
"BlobType",
"AccessTier",
"AccessTierChangeTime",
"Snapshot",
"VersionId",
"IsCurrentVersion",
"Metadata",
],
},
destination: "container1",
enabled: true,
name: "inventoryPolicyRule1",
},
{
definition: {
format: azure_native.storage.Format.Parquet,
objectType: azure_native.storage.ObjectType.Container,
schedule: azure_native.storage.Schedule.Weekly,
schemaFields: [
"Name",
"Last-Modified",
"Metadata",
"LeaseStatus",
"LeaseState",
"LeaseDuration",
"PublicAccess",
"HasImmutabilityPolicy",
"HasLegalHold",
],
},
destination: "container2",
enabled: true,
name: "inventoryPolicyRule2",
},
],
type: azure_native.storage.InventoryRuleType.Inventory,
},
resourceGroupName: "res7687",
});
import pulumi
import pulumi_azure_native as azure_native
blob_inventory_policy = azure_native.storage.BlobInventoryPolicy("blobInventoryPolicy",
account_name="sto9699",
blob_inventory_policy_name="default",
policy={
"enabled": True,
"rules": [
{
"definition": {
"filters": {
"blob_types": [
"blockBlob",
"appendBlob",
"pageBlob",
],
"creation_time": {
"last_n_days": 1000,
},
"include_blob_versions": True,
"include_snapshots": True,
"prefix_match": [
"inventoryprefix1",
"inventoryprefix2",
],
},
"format": azure_native.storage.Format.CSV,
"object_type": azure_native.storage.ObjectType.BLOB,
"schedule": azure_native.storage.Schedule.DAILY,
"schema_fields": [
"Name",
"Creation-Time",
"Last-Modified",
"Content-Length",
"Content-MD5",
"BlobType",
"AccessTier",
"AccessTierChangeTime",
"Snapshot",
"VersionId",
"IsCurrentVersion",
"Metadata",
],
},
"destination": "container1",
"enabled": True,
"name": "inventoryPolicyRule1",
},
{
"definition": {
"format": azure_native.storage.Format.PARQUET,
"object_type": azure_native.storage.ObjectType.CONTAINER,
"schedule": azure_native.storage.Schedule.WEEKLY,
"schema_fields": [
"Name",
"Last-Modified",
"Metadata",
"LeaseStatus",
"LeaseState",
"LeaseDuration",
"PublicAccess",
"HasImmutabilityPolicy",
"HasLegalHold",
],
},
"destination": "container2",
"enabled": True,
"name": "inventoryPolicyRule2",
},
],
"type": azure_native.storage.InventoryRuleType.INVENTORY,
},
resource_group_name="res7687")
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.NewBlobInventoryPolicy(ctx, "blobInventoryPolicy", &storage.BlobInventoryPolicyArgs{
AccountName: pulumi.String("sto9699"),
BlobInventoryPolicyName: pulumi.String("default"),
Policy: &storage.BlobInventoryPolicySchemaArgs{
Enabled: pulumi.Bool(true),
Rules: storage.BlobInventoryPolicyRuleArray{
&storage.BlobInventoryPolicyRuleArgs{
Definition: &storage.BlobInventoryPolicyDefinitionArgs{
Filters: &storage.BlobInventoryPolicyFilterArgs{
BlobTypes: pulumi.StringArray{
pulumi.String("blockBlob"),
pulumi.String("appendBlob"),
pulumi.String("pageBlob"),
},
CreationTime: &storage.BlobInventoryCreationTimeArgs{
LastNDays: pulumi.Int(1000),
},
IncludeBlobVersions: pulumi.Bool(true),
IncludeSnapshots: pulumi.Bool(true),
PrefixMatch: pulumi.StringArray{
pulumi.String("inventoryprefix1"),
pulumi.String("inventoryprefix2"),
},
},
Format: pulumi.String(storage.FormatCsv),
ObjectType: pulumi.String(storage.ObjectTypeBlob),
Schedule: pulumi.String(storage.ScheduleDaily),
SchemaFields: pulumi.StringArray{
pulumi.String("Name"),
pulumi.String("Creation-Time"),
pulumi.String("Last-Modified"),
pulumi.String("Content-Length"),
pulumi.String("Content-MD5"),
pulumi.String("BlobType"),
pulumi.String("AccessTier"),
pulumi.String("AccessTierChangeTime"),
pulumi.String("Snapshot"),
pulumi.String("VersionId"),
pulumi.String("IsCurrentVersion"),
pulumi.String("Metadata"),
},
},
Destination: pulumi.String("container1"),
Enabled: pulumi.Bool(true),
Name: pulumi.String("inventoryPolicyRule1"),
},
&storage.BlobInventoryPolicyRuleArgs{
Definition: &storage.BlobInventoryPolicyDefinitionArgs{
Format: pulumi.String(storage.FormatParquet),
ObjectType: pulumi.String(storage.ObjectTypeContainer),
Schedule: pulumi.String(storage.ScheduleWeekly),
SchemaFields: pulumi.StringArray{
pulumi.String("Name"),
pulumi.String("Last-Modified"),
pulumi.String("Metadata"),
pulumi.String("LeaseStatus"),
pulumi.String("LeaseState"),
pulumi.String("LeaseDuration"),
pulumi.String("PublicAccess"),
pulumi.String("HasImmutabilityPolicy"),
pulumi.String("HasLegalHold"),
},
},
Destination: pulumi.String("container2"),
Enabled: pulumi.Bool(true),
Name: pulumi.String("inventoryPolicyRule2"),
},
},
Type: pulumi.String(storage.InventoryRuleTypeInventory),
},
ResourceGroupName: pulumi.String("res7687"),
})
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 blobInventoryPolicy = new AzureNative.Storage.BlobInventoryPolicy("blobInventoryPolicy", new()
{
AccountName = "sto9699",
BlobInventoryPolicyName = "default",
Policy = new AzureNative.Storage.Inputs.BlobInventoryPolicySchemaArgs
{
Enabled = true,
Rules = new[]
{
new AzureNative.Storage.Inputs.BlobInventoryPolicyRuleArgs
{
Definition = new AzureNative.Storage.Inputs.BlobInventoryPolicyDefinitionArgs
{
Filters = new AzureNative.Storage.Inputs.BlobInventoryPolicyFilterArgs
{
BlobTypes = new[]
{
"blockBlob",
"appendBlob",
"pageBlob",
},
CreationTime = new AzureNative.Storage.Inputs.BlobInventoryCreationTimeArgs
{
LastNDays = 1000,
},
IncludeBlobVersions = true,
IncludeSnapshots = true,
PrefixMatch = new[]
{
"inventoryprefix1",
"inventoryprefix2",
},
},
Format = AzureNative.Storage.Format.Csv,
ObjectType = AzureNative.Storage.ObjectType.Blob,
Schedule = AzureNative.Storage.Schedule.Daily,
SchemaFields = new[]
{
"Name",
"Creation-Time",
"Last-Modified",
"Content-Length",
"Content-MD5",
"BlobType",
"AccessTier",
"AccessTierChangeTime",
"Snapshot",
"VersionId",
"IsCurrentVersion",
"Metadata",
},
},
Destination = "container1",
Enabled = true,
Name = "inventoryPolicyRule1",
},
new AzureNative.Storage.Inputs.BlobInventoryPolicyRuleArgs
{
Definition = new AzureNative.Storage.Inputs.BlobInventoryPolicyDefinitionArgs
{
Format = AzureNative.Storage.Format.Parquet,
ObjectType = AzureNative.Storage.ObjectType.Container,
Schedule = AzureNative.Storage.Schedule.Weekly,
SchemaFields = new[]
{
"Name",
"Last-Modified",
"Metadata",
"LeaseStatus",
"LeaseState",
"LeaseDuration",
"PublicAccess",
"HasImmutabilityPolicy",
"HasLegalHold",
},
},
Destination = "container2",
Enabled = true,
Name = "inventoryPolicyRule2",
},
},
Type = AzureNative.Storage.InventoryRuleType.Inventory,
},
ResourceGroupName = "res7687",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.storage.BlobInventoryPolicy;
import com.pulumi.azurenative.storage.BlobInventoryPolicyArgs;
import com.pulumi.azurenative.storage.inputs.BlobInventoryPolicySchemaArgs;
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 blobInventoryPolicy = new BlobInventoryPolicy("blobInventoryPolicy", BlobInventoryPolicyArgs.builder()
.accountName("sto9699")
.blobInventoryPolicyName("default")
.policy(BlobInventoryPolicySchemaArgs.builder()
.enabled(true)
.rules(
BlobInventoryPolicyRuleArgs.builder()
.definition(BlobInventoryPolicyDefinitionArgs.builder()
.filters(BlobInventoryPolicyFilterArgs.builder()
.blobTypes(
"blockBlob",
"appendBlob",
"pageBlob")
.creationTime(BlobInventoryCreationTimeArgs.builder()
.lastNDays(1000)
.build())
.includeBlobVersions(true)
.includeSnapshots(true)
.prefixMatch(
"inventoryprefix1",
"inventoryprefix2")
.build())
.format("Csv")
.objectType("Blob")
.schedule("Daily")
.schemaFields(
"Name",
"Creation-Time",
"Last-Modified",
"Content-Length",
"Content-MD5",
"BlobType",
"AccessTier",
"AccessTierChangeTime",
"Snapshot",
"VersionId",
"IsCurrentVersion",
"Metadata")
.build())
.destination("container1")
.enabled(true)
.name("inventoryPolicyRule1")
.build(),
BlobInventoryPolicyRuleArgs.builder()
.definition(BlobInventoryPolicyDefinitionArgs.builder()
.format("Parquet")
.objectType("Container")
.schedule("Weekly")
.schemaFields(
"Name",
"Last-Modified",
"Metadata",
"LeaseStatus",
"LeaseState",
"LeaseDuration",
"PublicAccess",
"HasImmutabilityPolicy",
"HasLegalHold")
.build())
.destination("container2")
.enabled(true)
.name("inventoryPolicyRule2")
.build())
.type("Inventory")
.build())
.resourceGroupName("res7687")
.build());
}
}
resources:
blobInventoryPolicy:
type: azure-native:storage:BlobInventoryPolicy
properties:
accountName: sto9699
blobInventoryPolicyName: default
policy:
enabled: true
rules:
- definition:
filters:
blobTypes:
- blockBlob
- appendBlob
- pageBlob
creationTime:
lastNDays: 1000
includeBlobVersions: true
includeSnapshots: true
prefixMatch:
- inventoryprefix1
- inventoryprefix2
format: Csv
objectType: Blob
schedule: Daily
schemaFields:
- Name
- Creation-Time
- Last-Modified
- Content-Length
- Content-MD5
- BlobType
- AccessTier
- AccessTierChangeTime
- Snapshot
- VersionId
- IsCurrentVersion
- Metadata
destination: container1
enabled: true
name: inventoryPolicyRule1
- definition:
format: Parquet
objectType: Container
schedule: Weekly
schemaFields:
- Name
- Last-Modified
- Metadata
- LeaseStatus
- LeaseState
- LeaseDuration
- PublicAccess
- HasImmutabilityPolicy
- HasLegalHold
destination: container2
enabled: true
name: inventoryPolicyRule2
type: Inventory
resourceGroupName: res7687
The policy runs on the schedule you specify (Daily or Weekly) and writes inventory reports to the destination container. Each rule defines an objectType (Blob or Container), a format (Csv or Parquet), and schemaFields that determine which metadata columns appear in the report. The filters property narrows the scope using prefixMatch for path filtering, blobTypes to include only specific blob types, and boolean flags like includeBlobVersions and includeSnapshots to control version and snapshot inclusion.
Include deleted blobs in hierarchical namespace accounts
Hierarchical namespace accounts used for Data Lake Storage Gen2 require additional schema fields to track deletion metadata and file system properties.
import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";
const blobInventoryPolicy = new azure_native.storage.BlobInventoryPolicy("blobInventoryPolicy", {
accountName: "sto9699",
blobInventoryPolicyName: "default",
policy: {
enabled: true,
rules: [
{
definition: {
filters: {
blobTypes: [
"blockBlob",
"appendBlob",
"pageBlob",
],
excludePrefix: [
"excludeprefix1",
"excludeprefix2",
],
includeBlobVersions: true,
includeDeleted: true,
includeSnapshots: true,
prefixMatch: [
"inventoryprefix1",
"inventoryprefix2",
],
},
format: azure_native.storage.Format.Csv,
objectType: azure_native.storage.ObjectType.Blob,
schedule: azure_native.storage.Schedule.Daily,
schemaFields: [
"Name",
"Creation-Time",
"Last-Modified",
"Content-Length",
"Content-MD5",
"BlobType",
"AccessTier",
"AccessTierChangeTime",
"Snapshot",
"VersionId",
"IsCurrentVersion",
"ContentType",
"ContentEncoding",
"ContentLanguage",
"ContentCRC64",
"CacheControl",
"Metadata",
"DeletionId",
"Deleted",
"DeletedTime",
"RemainingRetentionDays",
],
},
destination: "container1",
enabled: true,
name: "inventoryPolicyRule1",
},
{
definition: {
format: azure_native.storage.Format.Parquet,
objectType: azure_native.storage.ObjectType.Container,
schedule: azure_native.storage.Schedule.Weekly,
schemaFields: [
"Name",
"Last-Modified",
"Metadata",
"LeaseStatus",
"LeaseState",
"LeaseDuration",
"PublicAccess",
"HasImmutabilityPolicy",
"HasLegalHold",
"Etag",
"DefaultEncryptionScope",
"DenyEncryptionScopeOverride",
"ImmutableStorageWithVersioningEnabled",
"Deleted",
"Version",
"DeletedTime",
"RemainingRetentionDays",
],
},
destination: "container2",
enabled: true,
name: "inventoryPolicyRule2",
},
],
type: azure_native.storage.InventoryRuleType.Inventory,
},
resourceGroupName: "res7687",
});
import pulumi
import pulumi_azure_native as azure_native
blob_inventory_policy = azure_native.storage.BlobInventoryPolicy("blobInventoryPolicy",
account_name="sto9699",
blob_inventory_policy_name="default",
policy={
"enabled": True,
"rules": [
{
"definition": {
"filters": {
"blob_types": [
"blockBlob",
"appendBlob",
"pageBlob",
],
"exclude_prefix": [
"excludeprefix1",
"excludeprefix2",
],
"include_blob_versions": True,
"include_deleted": True,
"include_snapshots": True,
"prefix_match": [
"inventoryprefix1",
"inventoryprefix2",
],
},
"format": azure_native.storage.Format.CSV,
"object_type": azure_native.storage.ObjectType.BLOB,
"schedule": azure_native.storage.Schedule.DAILY,
"schema_fields": [
"Name",
"Creation-Time",
"Last-Modified",
"Content-Length",
"Content-MD5",
"BlobType",
"AccessTier",
"AccessTierChangeTime",
"Snapshot",
"VersionId",
"IsCurrentVersion",
"ContentType",
"ContentEncoding",
"ContentLanguage",
"ContentCRC64",
"CacheControl",
"Metadata",
"DeletionId",
"Deleted",
"DeletedTime",
"RemainingRetentionDays",
],
},
"destination": "container1",
"enabled": True,
"name": "inventoryPolicyRule1",
},
{
"definition": {
"format": azure_native.storage.Format.PARQUET,
"object_type": azure_native.storage.ObjectType.CONTAINER,
"schedule": azure_native.storage.Schedule.WEEKLY,
"schema_fields": [
"Name",
"Last-Modified",
"Metadata",
"LeaseStatus",
"LeaseState",
"LeaseDuration",
"PublicAccess",
"HasImmutabilityPolicy",
"HasLegalHold",
"Etag",
"DefaultEncryptionScope",
"DenyEncryptionScopeOverride",
"ImmutableStorageWithVersioningEnabled",
"Deleted",
"Version",
"DeletedTime",
"RemainingRetentionDays",
],
},
"destination": "container2",
"enabled": True,
"name": "inventoryPolicyRule2",
},
],
"type": azure_native.storage.InventoryRuleType.INVENTORY,
},
resource_group_name="res7687")
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.NewBlobInventoryPolicy(ctx, "blobInventoryPolicy", &storage.BlobInventoryPolicyArgs{
AccountName: pulumi.String("sto9699"),
BlobInventoryPolicyName: pulumi.String("default"),
Policy: &storage.BlobInventoryPolicySchemaArgs{
Enabled: pulumi.Bool(true),
Rules: storage.BlobInventoryPolicyRuleArray{
&storage.BlobInventoryPolicyRuleArgs{
Definition: &storage.BlobInventoryPolicyDefinitionArgs{
Filters: &storage.BlobInventoryPolicyFilterArgs{
BlobTypes: pulumi.StringArray{
pulumi.String("blockBlob"),
pulumi.String("appendBlob"),
pulumi.String("pageBlob"),
},
ExcludePrefix: pulumi.StringArray{
pulumi.String("excludeprefix1"),
pulumi.String("excludeprefix2"),
},
IncludeBlobVersions: pulumi.Bool(true),
IncludeDeleted: pulumi.Bool(true),
IncludeSnapshots: pulumi.Bool(true),
PrefixMatch: pulumi.StringArray{
pulumi.String("inventoryprefix1"),
pulumi.String("inventoryprefix2"),
},
},
Format: pulumi.String(storage.FormatCsv),
ObjectType: pulumi.String(storage.ObjectTypeBlob),
Schedule: pulumi.String(storage.ScheduleDaily),
SchemaFields: pulumi.StringArray{
pulumi.String("Name"),
pulumi.String("Creation-Time"),
pulumi.String("Last-Modified"),
pulumi.String("Content-Length"),
pulumi.String("Content-MD5"),
pulumi.String("BlobType"),
pulumi.String("AccessTier"),
pulumi.String("AccessTierChangeTime"),
pulumi.String("Snapshot"),
pulumi.String("VersionId"),
pulumi.String("IsCurrentVersion"),
pulumi.String("ContentType"),
pulumi.String("ContentEncoding"),
pulumi.String("ContentLanguage"),
pulumi.String("ContentCRC64"),
pulumi.String("CacheControl"),
pulumi.String("Metadata"),
pulumi.String("DeletionId"),
pulumi.String("Deleted"),
pulumi.String("DeletedTime"),
pulumi.String("RemainingRetentionDays"),
},
},
Destination: pulumi.String("container1"),
Enabled: pulumi.Bool(true),
Name: pulumi.String("inventoryPolicyRule1"),
},
&storage.BlobInventoryPolicyRuleArgs{
Definition: &storage.BlobInventoryPolicyDefinitionArgs{
Format: pulumi.String(storage.FormatParquet),
ObjectType: pulumi.String(storage.ObjectTypeContainer),
Schedule: pulumi.String(storage.ScheduleWeekly),
SchemaFields: pulumi.StringArray{
pulumi.String("Name"),
pulumi.String("Last-Modified"),
pulumi.String("Metadata"),
pulumi.String("LeaseStatus"),
pulumi.String("LeaseState"),
pulumi.String("LeaseDuration"),
pulumi.String("PublicAccess"),
pulumi.String("HasImmutabilityPolicy"),
pulumi.String("HasLegalHold"),
pulumi.String("Etag"),
pulumi.String("DefaultEncryptionScope"),
pulumi.String("DenyEncryptionScopeOverride"),
pulumi.String("ImmutableStorageWithVersioningEnabled"),
pulumi.String("Deleted"),
pulumi.String("Version"),
pulumi.String("DeletedTime"),
pulumi.String("RemainingRetentionDays"),
},
},
Destination: pulumi.String("container2"),
Enabled: pulumi.Bool(true),
Name: pulumi.String("inventoryPolicyRule2"),
},
},
Type: pulumi.String(storage.InventoryRuleTypeInventory),
},
ResourceGroupName: pulumi.String("res7687"),
})
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 blobInventoryPolicy = new AzureNative.Storage.BlobInventoryPolicy("blobInventoryPolicy", new()
{
AccountName = "sto9699",
BlobInventoryPolicyName = "default",
Policy = new AzureNative.Storage.Inputs.BlobInventoryPolicySchemaArgs
{
Enabled = true,
Rules = new[]
{
new AzureNative.Storage.Inputs.BlobInventoryPolicyRuleArgs
{
Definition = new AzureNative.Storage.Inputs.BlobInventoryPolicyDefinitionArgs
{
Filters = new AzureNative.Storage.Inputs.BlobInventoryPolicyFilterArgs
{
BlobTypes = new[]
{
"blockBlob",
"appendBlob",
"pageBlob",
},
ExcludePrefix = new[]
{
"excludeprefix1",
"excludeprefix2",
},
IncludeBlobVersions = true,
IncludeDeleted = true,
IncludeSnapshots = true,
PrefixMatch = new[]
{
"inventoryprefix1",
"inventoryprefix2",
},
},
Format = AzureNative.Storage.Format.Csv,
ObjectType = AzureNative.Storage.ObjectType.Blob,
Schedule = AzureNative.Storage.Schedule.Daily,
SchemaFields = new[]
{
"Name",
"Creation-Time",
"Last-Modified",
"Content-Length",
"Content-MD5",
"BlobType",
"AccessTier",
"AccessTierChangeTime",
"Snapshot",
"VersionId",
"IsCurrentVersion",
"ContentType",
"ContentEncoding",
"ContentLanguage",
"ContentCRC64",
"CacheControl",
"Metadata",
"DeletionId",
"Deleted",
"DeletedTime",
"RemainingRetentionDays",
},
},
Destination = "container1",
Enabled = true,
Name = "inventoryPolicyRule1",
},
new AzureNative.Storage.Inputs.BlobInventoryPolicyRuleArgs
{
Definition = new AzureNative.Storage.Inputs.BlobInventoryPolicyDefinitionArgs
{
Format = AzureNative.Storage.Format.Parquet,
ObjectType = AzureNative.Storage.ObjectType.Container,
Schedule = AzureNative.Storage.Schedule.Weekly,
SchemaFields = new[]
{
"Name",
"Last-Modified",
"Metadata",
"LeaseStatus",
"LeaseState",
"LeaseDuration",
"PublicAccess",
"HasImmutabilityPolicy",
"HasLegalHold",
"Etag",
"DefaultEncryptionScope",
"DenyEncryptionScopeOverride",
"ImmutableStorageWithVersioningEnabled",
"Deleted",
"Version",
"DeletedTime",
"RemainingRetentionDays",
},
},
Destination = "container2",
Enabled = true,
Name = "inventoryPolicyRule2",
},
},
Type = AzureNative.Storage.InventoryRuleType.Inventory,
},
ResourceGroupName = "res7687",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.storage.BlobInventoryPolicy;
import com.pulumi.azurenative.storage.BlobInventoryPolicyArgs;
import com.pulumi.azurenative.storage.inputs.BlobInventoryPolicySchemaArgs;
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 blobInventoryPolicy = new BlobInventoryPolicy("blobInventoryPolicy", BlobInventoryPolicyArgs.builder()
.accountName("sto9699")
.blobInventoryPolicyName("default")
.policy(BlobInventoryPolicySchemaArgs.builder()
.enabled(true)
.rules(
BlobInventoryPolicyRuleArgs.builder()
.definition(BlobInventoryPolicyDefinitionArgs.builder()
.filters(BlobInventoryPolicyFilterArgs.builder()
.blobTypes(
"blockBlob",
"appendBlob",
"pageBlob")
.excludePrefix(
"excludeprefix1",
"excludeprefix2")
.includeBlobVersions(true)
.includeDeleted(true)
.includeSnapshots(true)
.prefixMatch(
"inventoryprefix1",
"inventoryprefix2")
.build())
.format("Csv")
.objectType("Blob")
.schedule("Daily")
.schemaFields(
"Name",
"Creation-Time",
"Last-Modified",
"Content-Length",
"Content-MD5",
"BlobType",
"AccessTier",
"AccessTierChangeTime",
"Snapshot",
"VersionId",
"IsCurrentVersion",
"ContentType",
"ContentEncoding",
"ContentLanguage",
"ContentCRC64",
"CacheControl",
"Metadata",
"DeletionId",
"Deleted",
"DeletedTime",
"RemainingRetentionDays")
.build())
.destination("container1")
.enabled(true)
.name("inventoryPolicyRule1")
.build(),
BlobInventoryPolicyRuleArgs.builder()
.definition(BlobInventoryPolicyDefinitionArgs.builder()
.format("Parquet")
.objectType("Container")
.schedule("Weekly")
.schemaFields(
"Name",
"Last-Modified",
"Metadata",
"LeaseStatus",
"LeaseState",
"LeaseDuration",
"PublicAccess",
"HasImmutabilityPolicy",
"HasLegalHold",
"Etag",
"DefaultEncryptionScope",
"DenyEncryptionScopeOverride",
"ImmutableStorageWithVersioningEnabled",
"Deleted",
"Version",
"DeletedTime",
"RemainingRetentionDays")
.build())
.destination("container2")
.enabled(true)
.name("inventoryPolicyRule2")
.build())
.type("Inventory")
.build())
.resourceGroupName("res7687")
.build());
}
}
resources:
blobInventoryPolicy:
type: azure-native:storage:BlobInventoryPolicy
properties:
accountName: sto9699
blobInventoryPolicyName: default
policy:
enabled: true
rules:
- definition:
filters:
blobTypes:
- blockBlob
- appendBlob
- pageBlob
excludePrefix:
- excludeprefix1
- excludeprefix2
includeBlobVersions: true
includeDeleted: true
includeSnapshots: true
prefixMatch:
- inventoryprefix1
- inventoryprefix2
format: Csv
objectType: Blob
schedule: Daily
schemaFields:
- Name
- Creation-Time
- Last-Modified
- Content-Length
- Content-MD5
- BlobType
- AccessTier
- AccessTierChangeTime
- Snapshot
- VersionId
- IsCurrentVersion
- ContentType
- ContentEncoding
- ContentLanguage
- ContentCRC64
- CacheControl
- Metadata
- DeletionId
- Deleted
- DeletedTime
- RemainingRetentionDays
destination: container1
enabled: true
name: inventoryPolicyRule1
- definition:
format: Parquet
objectType: Container
schedule: Weekly
schemaFields:
- Name
- Last-Modified
- Metadata
- LeaseStatus
- LeaseState
- LeaseDuration
- PublicAccess
- HasImmutabilityPolicy
- HasLegalHold
- Etag
- DefaultEncryptionScope
- DenyEncryptionScopeOverride
- ImmutableStorageWithVersioningEnabled
- Deleted
- Version
- DeletedTime
- RemainingRetentionDays
destination: container2
enabled: true
name: inventoryPolicyRule2
type: Inventory
resourceGroupName: res7687
When includeDeleted is true, the inventory includes soft-deleted blobs alongside active ones. The schemaFields array includes DeletionId, DeletedTime, and RemainingRetentionDays to track deletion lifecycle. The excludePrefix property filters out paths you don’t want in the report, complementing prefixMatch for fine-grained control. HNS accounts support additional fields like Etag and encryption scope settings that aren’t available in standard accounts.
Track deleted blobs and tags in standard accounts
Standard blob storage accounts without hierarchical namespace support blob tags and different deletion tracking fields.
import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";
const blobInventoryPolicy = new azure_native.storage.BlobInventoryPolicy("blobInventoryPolicy", {
accountName: "sto9699",
blobInventoryPolicyName: "default",
policy: {
enabled: true,
rules: [
{
definition: {
filters: {
blobTypes: [
"blockBlob",
"appendBlob",
"pageBlob",
],
excludePrefix: [
"excludeprefix1",
"excludeprefix2",
],
includeBlobVersions: true,
includeDeleted: true,
includeSnapshots: true,
prefixMatch: [
"inventoryprefix1",
"inventoryprefix2",
],
},
format: azure_native.storage.Format.Csv,
objectType: azure_native.storage.ObjectType.Blob,
schedule: azure_native.storage.Schedule.Daily,
schemaFields: [
"Name",
"Creation-Time",
"Last-Modified",
"Content-Length",
"Content-MD5",
"BlobType",
"AccessTier",
"AccessTierChangeTime",
"Snapshot",
"VersionId",
"IsCurrentVersion",
"Tags",
"ContentType",
"ContentEncoding",
"ContentLanguage",
"ContentCRC64",
"CacheControl",
"Metadata",
"Deleted",
"RemainingRetentionDays",
],
},
destination: "container1",
enabled: true,
name: "inventoryPolicyRule1",
},
{
definition: {
format: azure_native.storage.Format.Parquet,
objectType: azure_native.storage.ObjectType.Container,
schedule: azure_native.storage.Schedule.Weekly,
schemaFields: [
"Name",
"Last-Modified",
"Metadata",
"LeaseStatus",
"LeaseState",
"LeaseDuration",
"PublicAccess",
"HasImmutabilityPolicy",
"HasLegalHold",
"Etag",
"DefaultEncryptionScope",
"DenyEncryptionScopeOverride",
"ImmutableStorageWithVersioningEnabled",
"Deleted",
"Version",
"DeletedTime",
"RemainingRetentionDays",
],
},
destination: "container2",
enabled: true,
name: "inventoryPolicyRule2",
},
],
type: azure_native.storage.InventoryRuleType.Inventory,
},
resourceGroupName: "res7687",
});
import pulumi
import pulumi_azure_native as azure_native
blob_inventory_policy = azure_native.storage.BlobInventoryPolicy("blobInventoryPolicy",
account_name="sto9699",
blob_inventory_policy_name="default",
policy={
"enabled": True,
"rules": [
{
"definition": {
"filters": {
"blob_types": [
"blockBlob",
"appendBlob",
"pageBlob",
],
"exclude_prefix": [
"excludeprefix1",
"excludeprefix2",
],
"include_blob_versions": True,
"include_deleted": True,
"include_snapshots": True,
"prefix_match": [
"inventoryprefix1",
"inventoryprefix2",
],
},
"format": azure_native.storage.Format.CSV,
"object_type": azure_native.storage.ObjectType.BLOB,
"schedule": azure_native.storage.Schedule.DAILY,
"schema_fields": [
"Name",
"Creation-Time",
"Last-Modified",
"Content-Length",
"Content-MD5",
"BlobType",
"AccessTier",
"AccessTierChangeTime",
"Snapshot",
"VersionId",
"IsCurrentVersion",
"Tags",
"ContentType",
"ContentEncoding",
"ContentLanguage",
"ContentCRC64",
"CacheControl",
"Metadata",
"Deleted",
"RemainingRetentionDays",
],
},
"destination": "container1",
"enabled": True,
"name": "inventoryPolicyRule1",
},
{
"definition": {
"format": azure_native.storage.Format.PARQUET,
"object_type": azure_native.storage.ObjectType.CONTAINER,
"schedule": azure_native.storage.Schedule.WEEKLY,
"schema_fields": [
"Name",
"Last-Modified",
"Metadata",
"LeaseStatus",
"LeaseState",
"LeaseDuration",
"PublicAccess",
"HasImmutabilityPolicy",
"HasLegalHold",
"Etag",
"DefaultEncryptionScope",
"DenyEncryptionScopeOverride",
"ImmutableStorageWithVersioningEnabled",
"Deleted",
"Version",
"DeletedTime",
"RemainingRetentionDays",
],
},
"destination": "container2",
"enabled": True,
"name": "inventoryPolicyRule2",
},
],
"type": azure_native.storage.InventoryRuleType.INVENTORY,
},
resource_group_name="res7687")
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.NewBlobInventoryPolicy(ctx, "blobInventoryPolicy", &storage.BlobInventoryPolicyArgs{
AccountName: pulumi.String("sto9699"),
BlobInventoryPolicyName: pulumi.String("default"),
Policy: &storage.BlobInventoryPolicySchemaArgs{
Enabled: pulumi.Bool(true),
Rules: storage.BlobInventoryPolicyRuleArray{
&storage.BlobInventoryPolicyRuleArgs{
Definition: &storage.BlobInventoryPolicyDefinitionArgs{
Filters: &storage.BlobInventoryPolicyFilterArgs{
BlobTypes: pulumi.StringArray{
pulumi.String("blockBlob"),
pulumi.String("appendBlob"),
pulumi.String("pageBlob"),
},
ExcludePrefix: pulumi.StringArray{
pulumi.String("excludeprefix1"),
pulumi.String("excludeprefix2"),
},
IncludeBlobVersions: pulumi.Bool(true),
IncludeDeleted: pulumi.Bool(true),
IncludeSnapshots: pulumi.Bool(true),
PrefixMatch: pulumi.StringArray{
pulumi.String("inventoryprefix1"),
pulumi.String("inventoryprefix2"),
},
},
Format: pulumi.String(storage.FormatCsv),
ObjectType: pulumi.String(storage.ObjectTypeBlob),
Schedule: pulumi.String(storage.ScheduleDaily),
SchemaFields: pulumi.StringArray{
pulumi.String("Name"),
pulumi.String("Creation-Time"),
pulumi.String("Last-Modified"),
pulumi.String("Content-Length"),
pulumi.String("Content-MD5"),
pulumi.String("BlobType"),
pulumi.String("AccessTier"),
pulumi.String("AccessTierChangeTime"),
pulumi.String("Snapshot"),
pulumi.String("VersionId"),
pulumi.String("IsCurrentVersion"),
pulumi.String("Tags"),
pulumi.String("ContentType"),
pulumi.String("ContentEncoding"),
pulumi.String("ContentLanguage"),
pulumi.String("ContentCRC64"),
pulumi.String("CacheControl"),
pulumi.String("Metadata"),
pulumi.String("Deleted"),
pulumi.String("RemainingRetentionDays"),
},
},
Destination: pulumi.String("container1"),
Enabled: pulumi.Bool(true),
Name: pulumi.String("inventoryPolicyRule1"),
},
&storage.BlobInventoryPolicyRuleArgs{
Definition: &storage.BlobInventoryPolicyDefinitionArgs{
Format: pulumi.String(storage.FormatParquet),
ObjectType: pulumi.String(storage.ObjectTypeContainer),
Schedule: pulumi.String(storage.ScheduleWeekly),
SchemaFields: pulumi.StringArray{
pulumi.String("Name"),
pulumi.String("Last-Modified"),
pulumi.String("Metadata"),
pulumi.String("LeaseStatus"),
pulumi.String("LeaseState"),
pulumi.String("LeaseDuration"),
pulumi.String("PublicAccess"),
pulumi.String("HasImmutabilityPolicy"),
pulumi.String("HasLegalHold"),
pulumi.String("Etag"),
pulumi.String("DefaultEncryptionScope"),
pulumi.String("DenyEncryptionScopeOverride"),
pulumi.String("ImmutableStorageWithVersioningEnabled"),
pulumi.String("Deleted"),
pulumi.String("Version"),
pulumi.String("DeletedTime"),
pulumi.String("RemainingRetentionDays"),
},
},
Destination: pulumi.String("container2"),
Enabled: pulumi.Bool(true),
Name: pulumi.String("inventoryPolicyRule2"),
},
},
Type: pulumi.String(storage.InventoryRuleTypeInventory),
},
ResourceGroupName: pulumi.String("res7687"),
})
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 blobInventoryPolicy = new AzureNative.Storage.BlobInventoryPolicy("blobInventoryPolicy", new()
{
AccountName = "sto9699",
BlobInventoryPolicyName = "default",
Policy = new AzureNative.Storage.Inputs.BlobInventoryPolicySchemaArgs
{
Enabled = true,
Rules = new[]
{
new AzureNative.Storage.Inputs.BlobInventoryPolicyRuleArgs
{
Definition = new AzureNative.Storage.Inputs.BlobInventoryPolicyDefinitionArgs
{
Filters = new AzureNative.Storage.Inputs.BlobInventoryPolicyFilterArgs
{
BlobTypes = new[]
{
"blockBlob",
"appendBlob",
"pageBlob",
},
ExcludePrefix = new[]
{
"excludeprefix1",
"excludeprefix2",
},
IncludeBlobVersions = true,
IncludeDeleted = true,
IncludeSnapshots = true,
PrefixMatch = new[]
{
"inventoryprefix1",
"inventoryprefix2",
},
},
Format = AzureNative.Storage.Format.Csv,
ObjectType = AzureNative.Storage.ObjectType.Blob,
Schedule = AzureNative.Storage.Schedule.Daily,
SchemaFields = new[]
{
"Name",
"Creation-Time",
"Last-Modified",
"Content-Length",
"Content-MD5",
"BlobType",
"AccessTier",
"AccessTierChangeTime",
"Snapshot",
"VersionId",
"IsCurrentVersion",
"Tags",
"ContentType",
"ContentEncoding",
"ContentLanguage",
"ContentCRC64",
"CacheControl",
"Metadata",
"Deleted",
"RemainingRetentionDays",
},
},
Destination = "container1",
Enabled = true,
Name = "inventoryPolicyRule1",
},
new AzureNative.Storage.Inputs.BlobInventoryPolicyRuleArgs
{
Definition = new AzureNative.Storage.Inputs.BlobInventoryPolicyDefinitionArgs
{
Format = AzureNative.Storage.Format.Parquet,
ObjectType = AzureNative.Storage.ObjectType.Container,
Schedule = AzureNative.Storage.Schedule.Weekly,
SchemaFields = new[]
{
"Name",
"Last-Modified",
"Metadata",
"LeaseStatus",
"LeaseState",
"LeaseDuration",
"PublicAccess",
"HasImmutabilityPolicy",
"HasLegalHold",
"Etag",
"DefaultEncryptionScope",
"DenyEncryptionScopeOverride",
"ImmutableStorageWithVersioningEnabled",
"Deleted",
"Version",
"DeletedTime",
"RemainingRetentionDays",
},
},
Destination = "container2",
Enabled = true,
Name = "inventoryPolicyRule2",
},
},
Type = AzureNative.Storage.InventoryRuleType.Inventory,
},
ResourceGroupName = "res7687",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.storage.BlobInventoryPolicy;
import com.pulumi.azurenative.storage.BlobInventoryPolicyArgs;
import com.pulumi.azurenative.storage.inputs.BlobInventoryPolicySchemaArgs;
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 blobInventoryPolicy = new BlobInventoryPolicy("blobInventoryPolicy", BlobInventoryPolicyArgs.builder()
.accountName("sto9699")
.blobInventoryPolicyName("default")
.policy(BlobInventoryPolicySchemaArgs.builder()
.enabled(true)
.rules(
BlobInventoryPolicyRuleArgs.builder()
.definition(BlobInventoryPolicyDefinitionArgs.builder()
.filters(BlobInventoryPolicyFilterArgs.builder()
.blobTypes(
"blockBlob",
"appendBlob",
"pageBlob")
.excludePrefix(
"excludeprefix1",
"excludeprefix2")
.includeBlobVersions(true)
.includeDeleted(true)
.includeSnapshots(true)
.prefixMatch(
"inventoryprefix1",
"inventoryprefix2")
.build())
.format("Csv")
.objectType("Blob")
.schedule("Daily")
.schemaFields(
"Name",
"Creation-Time",
"Last-Modified",
"Content-Length",
"Content-MD5",
"BlobType",
"AccessTier",
"AccessTierChangeTime",
"Snapshot",
"VersionId",
"IsCurrentVersion",
"Tags",
"ContentType",
"ContentEncoding",
"ContentLanguage",
"ContentCRC64",
"CacheControl",
"Metadata",
"Deleted",
"RemainingRetentionDays")
.build())
.destination("container1")
.enabled(true)
.name("inventoryPolicyRule1")
.build(),
BlobInventoryPolicyRuleArgs.builder()
.definition(BlobInventoryPolicyDefinitionArgs.builder()
.format("Parquet")
.objectType("Container")
.schedule("Weekly")
.schemaFields(
"Name",
"Last-Modified",
"Metadata",
"LeaseStatus",
"LeaseState",
"LeaseDuration",
"PublicAccess",
"HasImmutabilityPolicy",
"HasLegalHold",
"Etag",
"DefaultEncryptionScope",
"DenyEncryptionScopeOverride",
"ImmutableStorageWithVersioningEnabled",
"Deleted",
"Version",
"DeletedTime",
"RemainingRetentionDays")
.build())
.destination("container2")
.enabled(true)
.name("inventoryPolicyRule2")
.build())
.type("Inventory")
.build())
.resourceGroupName("res7687")
.build());
}
}
resources:
blobInventoryPolicy:
type: azure-native:storage:BlobInventoryPolicy
properties:
accountName: sto9699
blobInventoryPolicyName: default
policy:
enabled: true
rules:
- definition:
filters:
blobTypes:
- blockBlob
- appendBlob
- pageBlob
excludePrefix:
- excludeprefix1
- excludeprefix2
includeBlobVersions: true
includeDeleted: true
includeSnapshots: true
prefixMatch:
- inventoryprefix1
- inventoryprefix2
format: Csv
objectType: Blob
schedule: Daily
schemaFields:
- Name
- Creation-Time
- Last-Modified
- Content-Length
- Content-MD5
- BlobType
- AccessTier
- AccessTierChangeTime
- Snapshot
- VersionId
- IsCurrentVersion
- Tags
- ContentType
- ContentEncoding
- ContentLanguage
- ContentCRC64
- CacheControl
- Metadata
- Deleted
- RemainingRetentionDays
destination: container1
enabled: true
name: inventoryPolicyRule1
- definition:
format: Parquet
objectType: Container
schedule: Weekly
schemaFields:
- Name
- Last-Modified
- Metadata
- LeaseStatus
- LeaseState
- LeaseDuration
- PublicAccess
- HasImmutabilityPolicy
- HasLegalHold
- Etag
- DefaultEncryptionScope
- DenyEncryptionScopeOverride
- ImmutableStorageWithVersioningEnabled
- Deleted
- Version
- DeletedTime
- RemainingRetentionDays
destination: container2
enabled: true
name: inventoryPolicyRule2
type: Inventory
resourceGroupName: res7687
In non-HNS accounts, the Tags schema field captures blob index tags for cost allocation and compliance tracking. The Deleted and RemainingRetentionDays fields track soft-delete status without the DeletionId field used in HNS accounts. This configuration demonstrates how schema requirements differ between account types: HNS accounts use DeletionId, while standard accounts use Tags and simpler deletion tracking.
Beyond these examples
These snippets focus on specific inventory policy features: blob and container inventory generation, filtering by prefix and blob type and deletion status, and schema customization for HNS and non-HNS accounts. They’re intentionally minimal rather than full storage management solutions.
The examples reference pre-existing infrastructure such as Azure storage accounts with resource groups and destination containers for inventory reports. They focus on configuring the inventory policy rather than provisioning the storage account or processing the generated reports.
To keep things focused, common inventory patterns are omitted, including:
- Creation time filtering (creationTime.lastNDays)
- Multiple policies per storage account
- Inventory report consumption and parsing
- Integration with Azure Monitor or Log Analytics
These omissions are intentional: the goal is to illustrate how each inventory feature is wired, not provide drop-in storage analytics modules. See the BlobInventoryPolicy resource reference for all available configuration options.
Let's configure Azure Blob Storage Inventory Policies
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Policy Configuration
blobInventoryPolicyName parameter only accepts default as a value. Always use default when creating or managing blob inventory policies.policy.rules array. Each rule can have its own objectType, schedule, filters, and destination container.Inventory Rules & Object Types
objectType determines the inventory scope and available schema fields. Blob inventories individual blobs with fields like Content-Length, BlobType, and AccessTier. Container inventories containers with fields like LeaseStatus, PublicAccess, and HasImmutabilityPolicy.filters property to scope your inventory. Available filters include blobTypes (blockBlob, appendBlob, pageBlob), prefixMatch, excludePrefix, includeBlobVersions, includeSnapshots, includeDeleted, and creationTime with lastNDays.objectType. For Blob inventories, you can include fields like Name, Creation-Time, Content-Length, BlobType, AccessTier, Metadata, and more. For Container inventories, fields include Name, LeaseStatus, PublicAccess, HasImmutabilityPolicy, and others.Output & Scheduling
Csv and Parquet. You can schedule inventory generation Daily or Weekly. Specify the destination container where reports will be stored.Account-Specific Behavior
DeletionId schema field for blob inventories, while non-HNS accounts support the Tags field instead. Other schema fields remain the same.includeDeleted: true in your filters. You can also include deletion-related schema fields like Deleted, DeletedTime, and RemainingRetentionDays.