The azure-native:sql:ExtendedDatabaseBlobAuditingPolicy resource, part of the Pulumi Azure Native provider, defines audit logging configuration for an Azure SQL database: its destination (Azure Monitor or blob storage), action groups, and retention settings. This guide focuses on three capabilities: Azure Monitor integration, blob storage archival, and selective auditing with action groups and predicates.
Audit policies reference existing SQL servers, databases, and storage accounts. When using Azure Monitor as a destination, you must configure Diagnostic Settings separately. The examples are intentionally small. Combine them with your own SQL infrastructure and monitoring setup.
Send audit events to Azure Monitor
Compliance teams often route SQL audit events to Azure Monitor for centralized log analysis and alerting, integrating with existing monitoring infrastructure.
import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";
const extendedDatabaseBlobAuditingPolicy = new azure_native.sql.ExtendedDatabaseBlobAuditingPolicy("extendedDatabaseBlobAuditingPolicy", {
blobAuditingPolicyName: "default",
databaseName: "testdb",
isAzureMonitorTargetEnabled: true,
resourceGroupName: "blobauditingtest-4799",
serverName: "blobauditingtest-6440",
state: azure_native.sql.BlobAuditingPolicyState.Enabled,
});
import pulumi
import pulumi_azure_native as azure_native
extended_database_blob_auditing_policy = azure_native.sql.ExtendedDatabaseBlobAuditingPolicy("extendedDatabaseBlobAuditingPolicy",
blob_auditing_policy_name="default",
database_name="testdb",
is_azure_monitor_target_enabled=True,
resource_group_name="blobauditingtest-4799",
server_name="blobauditingtest-6440",
state=azure_native.sql.BlobAuditingPolicyState.ENABLED)
package main
import (
sql "github.com/pulumi/pulumi-azure-native-sdk/sql/v3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := sql.NewExtendedDatabaseBlobAuditingPolicy(ctx, "extendedDatabaseBlobAuditingPolicy", &sql.ExtendedDatabaseBlobAuditingPolicyArgs{
BlobAuditingPolicyName: pulumi.String("default"),
DatabaseName: pulumi.String("testdb"),
IsAzureMonitorTargetEnabled: pulumi.Bool(true),
ResourceGroupName: pulumi.String("blobauditingtest-4799"),
ServerName: pulumi.String("blobauditingtest-6440"),
State: sql.BlobAuditingPolicyStateEnabled,
})
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 extendedDatabaseBlobAuditingPolicy = new AzureNative.Sql.ExtendedDatabaseBlobAuditingPolicy("extendedDatabaseBlobAuditingPolicy", new()
{
BlobAuditingPolicyName = "default",
DatabaseName = "testdb",
IsAzureMonitorTargetEnabled = true,
ResourceGroupName = "blobauditingtest-4799",
ServerName = "blobauditingtest-6440",
State = AzureNative.Sql.BlobAuditingPolicyState.Enabled,
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.sql.ExtendedDatabaseBlobAuditingPolicy;
import com.pulumi.azurenative.sql.ExtendedDatabaseBlobAuditingPolicyArgs;
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 extendedDatabaseBlobAuditingPolicy = new ExtendedDatabaseBlobAuditingPolicy("extendedDatabaseBlobAuditingPolicy", ExtendedDatabaseBlobAuditingPolicyArgs.builder()
.blobAuditingPolicyName("default")
.databaseName("testdb")
.isAzureMonitorTargetEnabled(true)
.resourceGroupName("blobauditingtest-4799")
.serverName("blobauditingtest-6440")
.state("Enabled")
.build());
}
}
resources:
extendedDatabaseBlobAuditingPolicy:
type: azure-native:sql:ExtendedDatabaseBlobAuditingPolicy
properties:
blobAuditingPolicyName: default
databaseName: testdb
isAzureMonitorTargetEnabled: true
resourceGroupName: blobauditingtest-4799
serverName: blobauditingtest-6440
state: Enabled
When isAzureMonitorTargetEnabled is true and state is Enabled, audit events flow to Azure Monitor Logs. You must separately create Diagnostic Settings with the SQLSecurityAuditEvents category on the database. The policy itself doesn’t configure storage; it only enables the Azure Monitor destination.
Store audit logs in blob storage
Organizations with long-term retention requirements write audit logs directly to blob storage for archival or external analysis.
import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";
const extendedDatabaseBlobAuditingPolicy = new azure_native.sql.ExtendedDatabaseBlobAuditingPolicy("extendedDatabaseBlobAuditingPolicy", {
blobAuditingPolicyName: "default",
databaseName: "testdb",
resourceGroupName: "blobauditingtest-4799",
serverName: "blobauditingtest-6440",
state: azure_native.sql.BlobAuditingPolicyState.Enabled,
storageAccountAccessKey: "sdlfkjabc+sdlfkjsdlkfsjdfLDKFTERLKFDFKLjsdfksjdflsdkfD2342309432849328476458/3RSD==",
storageEndpoint: "https://mystorage.blob.core.windows.net",
});
import pulumi
import pulumi_azure_native as azure_native
extended_database_blob_auditing_policy = azure_native.sql.ExtendedDatabaseBlobAuditingPolicy("extendedDatabaseBlobAuditingPolicy",
blob_auditing_policy_name="default",
database_name="testdb",
resource_group_name="blobauditingtest-4799",
server_name="blobauditingtest-6440",
state=azure_native.sql.BlobAuditingPolicyState.ENABLED,
storage_account_access_key="sdlfkjabc+sdlfkjsdlkfsjdfLDKFTERLKFDFKLjsdfksjdflsdkfD2342309432849328476458/3RSD==",
storage_endpoint="https://mystorage.blob.core.windows.net")
package main
import (
sql "github.com/pulumi/pulumi-azure-native-sdk/sql/v3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := sql.NewExtendedDatabaseBlobAuditingPolicy(ctx, "extendedDatabaseBlobAuditingPolicy", &sql.ExtendedDatabaseBlobAuditingPolicyArgs{
BlobAuditingPolicyName: pulumi.String("default"),
DatabaseName: pulumi.String("testdb"),
ResourceGroupName: pulumi.String("blobauditingtest-4799"),
ServerName: pulumi.String("blobauditingtest-6440"),
State: sql.BlobAuditingPolicyStateEnabled,
StorageAccountAccessKey: pulumi.String("sdlfkjabc+sdlfkjsdlkfsjdfLDKFTERLKFDFKLjsdfksjdflsdkfD2342309432849328476458/3RSD=="),
StorageEndpoint: pulumi.String("https://mystorage.blob.core.windows.net"),
})
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 extendedDatabaseBlobAuditingPolicy = new AzureNative.Sql.ExtendedDatabaseBlobAuditingPolicy("extendedDatabaseBlobAuditingPolicy", new()
{
BlobAuditingPolicyName = "default",
DatabaseName = "testdb",
ResourceGroupName = "blobauditingtest-4799",
ServerName = "blobauditingtest-6440",
State = AzureNative.Sql.BlobAuditingPolicyState.Enabled,
StorageAccountAccessKey = "sdlfkjabc+sdlfkjsdlkfsjdfLDKFTERLKFDFKLjsdfksjdflsdkfD2342309432849328476458/3RSD==",
StorageEndpoint = "https://mystorage.blob.core.windows.net",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.sql.ExtendedDatabaseBlobAuditingPolicy;
import com.pulumi.azurenative.sql.ExtendedDatabaseBlobAuditingPolicyArgs;
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 extendedDatabaseBlobAuditingPolicy = new ExtendedDatabaseBlobAuditingPolicy("extendedDatabaseBlobAuditingPolicy", ExtendedDatabaseBlobAuditingPolicyArgs.builder()
.blobAuditingPolicyName("default")
.databaseName("testdb")
.resourceGroupName("blobauditingtest-4799")
.serverName("blobauditingtest-6440")
.state("Enabled")
.storageAccountAccessKey("sdlfkjabc+sdlfkjsdlkfsjdfLDKFTERLKFDFKLjsdfksjdflsdkfD2342309432849328476458/3RSD==")
.storageEndpoint("https://mystorage.blob.core.windows.net")
.build());
}
}
resources:
extendedDatabaseBlobAuditingPolicy:
type: azure-native:sql:ExtendedDatabaseBlobAuditingPolicy
properties:
blobAuditingPolicyName: default
databaseName: testdb
resourceGroupName: blobauditingtest-4799
serverName: blobauditingtest-6440
state: Enabled
storageAccountAccessKey: sdlfkjabc+sdlfkjsdlkfsjdfLDKFTERLKFDFKLjsdfksjdflsdkfD2342309432849328476458/3RSD==
storageEndpoint: https://mystorage.blob.core.windows.net
The storageEndpoint property points to your blob storage account, and storageAccountAccessKey provides authentication. When state is Enabled with a storage endpoint, audit events write to blob storage. This configuration uses access key authentication; Managed Identity authentication is available but not shown here.
Configure selective auditing with action groups and filters
Security teams often need granular control over what gets audited, filtering by specific actions or SQL predicates to reduce log volume.
import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";
const extendedDatabaseBlobAuditingPolicy = new azure_native.sql.ExtendedDatabaseBlobAuditingPolicy("extendedDatabaseBlobAuditingPolicy", {
auditActionsAndGroups: [
"DATABASE_LOGOUT_GROUP",
"DATABASE_ROLE_MEMBER_CHANGE_GROUP",
"UPDATE on database::TestDatabaseName by public",
],
blobAuditingPolicyName: "default",
databaseName: "testdb",
isAzureMonitorTargetEnabled: true,
isStorageSecondaryKeyInUse: false,
predicateExpression: "statement = 'select 1'",
queueDelayMs: 4000,
resourceGroupName: "blobauditingtest-4799",
retentionDays: 6,
serverName: "blobauditingtest-6440",
state: azure_native.sql.BlobAuditingPolicyState.Enabled,
storageAccountAccessKey: "sdlfkjabc+sdlfkjsdlkfsjdfLDKFTERLKFDFKLjsdfksjdflsdkfD2342309432849328476458/3RSD==",
storageAccountSubscriptionId: "00000000-1234-0000-5678-000000000000",
storageEndpoint: "https://mystorage.blob.core.windows.net",
});
import pulumi
import pulumi_azure_native as azure_native
extended_database_blob_auditing_policy = azure_native.sql.ExtendedDatabaseBlobAuditingPolicy("extendedDatabaseBlobAuditingPolicy",
audit_actions_and_groups=[
"DATABASE_LOGOUT_GROUP",
"DATABASE_ROLE_MEMBER_CHANGE_GROUP",
"UPDATE on database::TestDatabaseName by public",
],
blob_auditing_policy_name="default",
database_name="testdb",
is_azure_monitor_target_enabled=True,
is_storage_secondary_key_in_use=False,
predicate_expression="statement = 'select 1'",
queue_delay_ms=4000,
resource_group_name="blobauditingtest-4799",
retention_days=6,
server_name="blobauditingtest-6440",
state=azure_native.sql.BlobAuditingPolicyState.ENABLED,
storage_account_access_key="sdlfkjabc+sdlfkjsdlkfsjdfLDKFTERLKFDFKLjsdfksjdflsdkfD2342309432849328476458/3RSD==",
storage_account_subscription_id="00000000-1234-0000-5678-000000000000",
storage_endpoint="https://mystorage.blob.core.windows.net")
package main
import (
sql "github.com/pulumi/pulumi-azure-native-sdk/sql/v3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := sql.NewExtendedDatabaseBlobAuditingPolicy(ctx, "extendedDatabaseBlobAuditingPolicy", &sql.ExtendedDatabaseBlobAuditingPolicyArgs{
AuditActionsAndGroups: pulumi.StringArray{
pulumi.String("DATABASE_LOGOUT_GROUP"),
pulumi.String("DATABASE_ROLE_MEMBER_CHANGE_GROUP"),
pulumi.String("UPDATE on database::TestDatabaseName by public"),
},
BlobAuditingPolicyName: pulumi.String("default"),
DatabaseName: pulumi.String("testdb"),
IsAzureMonitorTargetEnabled: pulumi.Bool(true),
IsStorageSecondaryKeyInUse: pulumi.Bool(false),
PredicateExpression: pulumi.String("statement = 'select 1'"),
QueueDelayMs: pulumi.Int(4000),
ResourceGroupName: pulumi.String("blobauditingtest-4799"),
RetentionDays: pulumi.Int(6),
ServerName: pulumi.String("blobauditingtest-6440"),
State: sql.BlobAuditingPolicyStateEnabled,
StorageAccountAccessKey: pulumi.String("sdlfkjabc+sdlfkjsdlkfsjdfLDKFTERLKFDFKLjsdfksjdflsdkfD2342309432849328476458/3RSD=="),
StorageAccountSubscriptionId: pulumi.String("00000000-1234-0000-5678-000000000000"),
StorageEndpoint: pulumi.String("https://mystorage.blob.core.windows.net"),
})
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 extendedDatabaseBlobAuditingPolicy = new AzureNative.Sql.ExtendedDatabaseBlobAuditingPolicy("extendedDatabaseBlobAuditingPolicy", new()
{
AuditActionsAndGroups = new[]
{
"DATABASE_LOGOUT_GROUP",
"DATABASE_ROLE_MEMBER_CHANGE_GROUP",
"UPDATE on database::TestDatabaseName by public",
},
BlobAuditingPolicyName = "default",
DatabaseName = "testdb",
IsAzureMonitorTargetEnabled = true,
IsStorageSecondaryKeyInUse = false,
PredicateExpression = "statement = 'select 1'",
QueueDelayMs = 4000,
ResourceGroupName = "blobauditingtest-4799",
RetentionDays = 6,
ServerName = "blobauditingtest-6440",
State = AzureNative.Sql.BlobAuditingPolicyState.Enabled,
StorageAccountAccessKey = "sdlfkjabc+sdlfkjsdlkfsjdfLDKFTERLKFDFKLjsdfksjdflsdkfD2342309432849328476458/3RSD==",
StorageAccountSubscriptionId = "00000000-1234-0000-5678-000000000000",
StorageEndpoint = "https://mystorage.blob.core.windows.net",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.sql.ExtendedDatabaseBlobAuditingPolicy;
import com.pulumi.azurenative.sql.ExtendedDatabaseBlobAuditingPolicyArgs;
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 extendedDatabaseBlobAuditingPolicy = new ExtendedDatabaseBlobAuditingPolicy("extendedDatabaseBlobAuditingPolicy", ExtendedDatabaseBlobAuditingPolicyArgs.builder()
.auditActionsAndGroups(
"DATABASE_LOGOUT_GROUP",
"DATABASE_ROLE_MEMBER_CHANGE_GROUP",
"UPDATE on database::TestDatabaseName by public")
.blobAuditingPolicyName("default")
.databaseName("testdb")
.isAzureMonitorTargetEnabled(true)
.isStorageSecondaryKeyInUse(false)
.predicateExpression("statement = 'select 1'")
.queueDelayMs(4000)
.resourceGroupName("blobauditingtest-4799")
.retentionDays(6)
.serverName("blobauditingtest-6440")
.state("Enabled")
.storageAccountAccessKey("sdlfkjabc+sdlfkjsdlkfsjdfLDKFTERLKFDFKLjsdfksjdflsdkfD2342309432849328476458/3RSD==")
.storageAccountSubscriptionId("00000000-1234-0000-5678-000000000000")
.storageEndpoint("https://mystorage.blob.core.windows.net")
.build());
}
}
resources:
extendedDatabaseBlobAuditingPolicy:
type: azure-native:sql:ExtendedDatabaseBlobAuditingPolicy
properties:
auditActionsAndGroups:
- DATABASE_LOGOUT_GROUP
- DATABASE_ROLE_MEMBER_CHANGE_GROUP
- UPDATE on database::TestDatabaseName by public
blobAuditingPolicyName: default
databaseName: testdb
isAzureMonitorTargetEnabled: true
isStorageSecondaryKeyInUse: false
predicateExpression: statement = 'select 1'
queueDelayMs: 4000
resourceGroupName: blobauditingtest-4799
retentionDays: 6
serverName: blobauditingtest-6440
state: Enabled
storageAccountAccessKey: sdlfkjabc+sdlfkjsdlkfsjdfLDKFTERLKFDFKLjsdfksjdflsdkfD2342309432849328476458/3RSD==
storageAccountSubscriptionId: 00000000-1234-0000-5678-000000000000
storageEndpoint: https://mystorage.blob.core.windows.net
The auditActionsAndGroups property specifies which database operations to capture. Action groups like DATABASE_LOGOUT_GROUP and DATABASE_ROLE_MEMBER_CHANGE_GROUP track authentication and permission changes; specific actions like “UPDATE on database::TestDatabaseName by public” target individual operations. The predicateExpression filters events by SQL conditions (here, “statement = ‘select 1’”). The queueDelayMs property controls how long audit actions can buffer before processing, and retentionDays sets how long logs remain in storage.
Beyond these examples
These snippets focus on specific auditing policy features: Azure Monitor and blob storage destinations, action groups and predicate filtering, and retention and queue delay tuning. They’re intentionally minimal rather than full compliance solutions.
The examples reference pre-existing infrastructure such as SQL servers and databases, storage accounts with access keys, and Azure Monitor Diagnostic Settings (for Azure Monitor destination). They focus on configuring the audit policy rather than provisioning the surrounding infrastructure.
To keep things focused, common auditing patterns are omitted, including:
- Managed Identity authentication (isManagedIdentityInUse)
- Secondary storage key usage (isStorageSecondaryKeyInUse)
- Cross-subscription storage (storageAccountSubscriptionId)
These omissions are intentional: the goal is to illustrate how each auditing feature is wired, not provide drop-in compliance modules. See the ExtendedDatabaseBlobAuditingPolicy resource reference for all available configuration options.
Let's configure Azure SQL Database Blob Auditing Policies
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Configuration & Requirements
state to Enabled. You must also provide either storageEndpoint (for blob storage auditing) or set isAzureMonitorTargetEnabled to true (for Azure Monitor auditing).state to Enabled, provide storageEndpoint (e.g., https://MyAccount.blob.core.windows.net), and storageAccountAccessKey.state to Enabled and isAzureMonitorTargetEnabled to true.Audit Actions & Groups
BATCH_COMPLETED_GROUP, SUCCESSFUL_DATABASE_AUTHENTICATION_GROUP, and FAILED_DATABASE_AUTHENTICATION_GROUP. This combination audits all queries, stored procedures, and login attempts.Storage & Authentication
isManagedIdentityInUse to true and omit storageAccountAccessKey. Prerequisites: assign the SQL Server a system-assigned managed identity in Azure Active Directory, then grant the identity ‘Storage Blob Data Contributor’ RBAC role on the storage account.retentionDays to specify the number of days to keep audit logs in the storage account.queueDelayMs specifies how long (in milliseconds) before audit actions are forced to be processed. The default minimum is 1000 (1 second) and the maximum is 2,147,483,647.Azure Monitor & Advanced Configuration
state to Enabled and isAzureMonitorTargetEnabled to true. You must also manually create Diagnostic Settings with the SQLSecurityAuditEvents diagnostic logs category on the database using REST API or PowerShell.blobAuditingPolicyName, databaseName, resourceGroupName, and serverName.