Configure Azure Synapse SQL Pool Vulnerability Assessment

The azure-native:synapse:SqlPoolVulnerabilityAssessment resource, part of the Pulumi Azure Native provider, configures vulnerability assessment for a Synapse SQL pool: where scan results are stored and how often scans run. This guide focuses on three capabilities: storage authentication methods, recurring scan configuration, and email notification setup.

Vulnerability assessments belong to a SQL pool within a Synapse workspace and write scan results to an Azure Storage blob container. The examples are intentionally small. Combine them with your own Synapse infrastructure and storage accounts.

Store scan results using storage account access key

Most deployments start with the minimal configuration: pointing to a storage container where scan results will be written, using the storage account’s access key for authentication.

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

const sqlPoolVulnerabilityAssessment = new azure_native.synapse.SqlPoolVulnerabilityAssessment("sqlPoolVulnerabilityAssessment", {
    resourceGroupName: "vulnerabilityaseessmenttest-4799",
    sqlPoolName: "testdb",
    storageAccountAccessKey: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    storageContainerPath: "https://myStorage.blob.core.windows.net/vulnerability-assessment/",
    vulnerabilityAssessmentName: "default",
    workspaceName: "vulnerabilityaseessmenttest-6440",
});
import pulumi
import pulumi_azure_native as azure_native

sql_pool_vulnerability_assessment = azure_native.synapse.SqlPoolVulnerabilityAssessment("sqlPoolVulnerabilityAssessment",
    resource_group_name="vulnerabilityaseessmenttest-4799",
    sql_pool_name="testdb",
    storage_account_access_key="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    storage_container_path="https://myStorage.blob.core.windows.net/vulnerability-assessment/",
    vulnerability_assessment_name="default",
    workspace_name="vulnerabilityaseessmenttest-6440")
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := synapse.NewSqlPoolVulnerabilityAssessment(ctx, "sqlPoolVulnerabilityAssessment", &synapse.SqlPoolVulnerabilityAssessmentArgs{
			ResourceGroupName:           pulumi.String("vulnerabilityaseessmenttest-4799"),
			SqlPoolName:                 pulumi.String("testdb"),
			StorageAccountAccessKey:     pulumi.String("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"),
			StorageContainerPath:        pulumi.String("https://myStorage.blob.core.windows.net/vulnerability-assessment/"),
			VulnerabilityAssessmentName: pulumi.String("default"),
			WorkspaceName:               pulumi.String("vulnerabilityaseessmenttest-6440"),
		})
		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 sqlPoolVulnerabilityAssessment = new AzureNative.Synapse.SqlPoolVulnerabilityAssessment("sqlPoolVulnerabilityAssessment", new()
    {
        ResourceGroupName = "vulnerabilityaseessmenttest-4799",
        SqlPoolName = "testdb",
        StorageAccountAccessKey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
        StorageContainerPath = "https://myStorage.blob.core.windows.net/vulnerability-assessment/",
        VulnerabilityAssessmentName = "default",
        WorkspaceName = "vulnerabilityaseessmenttest-6440",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.synapse.SqlPoolVulnerabilityAssessment;
import com.pulumi.azurenative.synapse.SqlPoolVulnerabilityAssessmentArgs;
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 sqlPoolVulnerabilityAssessment = new SqlPoolVulnerabilityAssessment("sqlPoolVulnerabilityAssessment", SqlPoolVulnerabilityAssessmentArgs.builder()
            .resourceGroupName("vulnerabilityaseessmenttest-4799")
            .sqlPoolName("testdb")
            .storageAccountAccessKey("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
            .storageContainerPath("https://myStorage.blob.core.windows.net/vulnerability-assessment/")
            .vulnerabilityAssessmentName("default")
            .workspaceName("vulnerabilityaseessmenttest-6440")
            .build());

    }
}
resources:
  sqlPoolVulnerabilityAssessment:
    type: azure-native:synapse:SqlPoolVulnerabilityAssessment
    properties:
      resourceGroupName: vulnerabilityaseessmenttest-4799
      sqlPoolName: testdb
      storageAccountAccessKey: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
      storageContainerPath: https://myStorage.blob.core.windows.net/vulnerability-assessment/
      vulnerabilityAssessmentName: default
      workspaceName: vulnerabilityaseessmenttest-6440

The storageContainerPath property specifies the blob container URL where Azure writes scan results. The storageAccountAccessKey provides write access to that container. The assessment runs on the SQL pool specified by sqlPoolName within the workspace specified by workspaceName.

Store scan results using SAS token authentication

When you want to grant time-limited access to scan results without sharing the full storage account key, use a SAS token instead.

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

const sqlPoolVulnerabilityAssessment = new azure_native.synapse.SqlPoolVulnerabilityAssessment("sqlPoolVulnerabilityAssessment", {
    resourceGroupName: "vulnerabilityaseessmenttest-4799",
    sqlPoolName: "testdb",
    storageContainerPath: "https://myStorage.blob.core.windows.net/vulnerability-assessment/",
    storageContainerSasKey: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    vulnerabilityAssessmentName: "default",
    workspaceName: "vulnerabilityaseessmenttest-6440",
});
import pulumi
import pulumi_azure_native as azure_native

sql_pool_vulnerability_assessment = azure_native.synapse.SqlPoolVulnerabilityAssessment("sqlPoolVulnerabilityAssessment",
    resource_group_name="vulnerabilityaseessmenttest-4799",
    sql_pool_name="testdb",
    storage_container_path="https://myStorage.blob.core.windows.net/vulnerability-assessment/",
    storage_container_sas_key="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    vulnerability_assessment_name="default",
    workspace_name="vulnerabilityaseessmenttest-6440")
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := synapse.NewSqlPoolVulnerabilityAssessment(ctx, "sqlPoolVulnerabilityAssessment", &synapse.SqlPoolVulnerabilityAssessmentArgs{
			ResourceGroupName:           pulumi.String("vulnerabilityaseessmenttest-4799"),
			SqlPoolName:                 pulumi.String("testdb"),
			StorageContainerPath:        pulumi.String("https://myStorage.blob.core.windows.net/vulnerability-assessment/"),
			StorageContainerSasKey:      pulumi.String("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"),
			VulnerabilityAssessmentName: pulumi.String("default"),
			WorkspaceName:               pulumi.String("vulnerabilityaseessmenttest-6440"),
		})
		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 sqlPoolVulnerabilityAssessment = new AzureNative.Synapse.SqlPoolVulnerabilityAssessment("sqlPoolVulnerabilityAssessment", new()
    {
        ResourceGroupName = "vulnerabilityaseessmenttest-4799",
        SqlPoolName = "testdb",
        StorageContainerPath = "https://myStorage.blob.core.windows.net/vulnerability-assessment/",
        StorageContainerSasKey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
        VulnerabilityAssessmentName = "default",
        WorkspaceName = "vulnerabilityaseessmenttest-6440",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.synapse.SqlPoolVulnerabilityAssessment;
import com.pulumi.azurenative.synapse.SqlPoolVulnerabilityAssessmentArgs;
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 sqlPoolVulnerabilityAssessment = new SqlPoolVulnerabilityAssessment("sqlPoolVulnerabilityAssessment", SqlPoolVulnerabilityAssessmentArgs.builder()
            .resourceGroupName("vulnerabilityaseessmenttest-4799")
            .sqlPoolName("testdb")
            .storageContainerPath("https://myStorage.blob.core.windows.net/vulnerability-assessment/")
            .storageContainerSasKey("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
            .vulnerabilityAssessmentName("default")
            .workspaceName("vulnerabilityaseessmenttest-6440")
            .build());

    }
}
resources:
  sqlPoolVulnerabilityAssessment:
    type: azure-native:synapse:SqlPoolVulnerabilityAssessment
    properties:
      resourceGroupName: vulnerabilityaseessmenttest-4799
      sqlPoolName: testdb
      storageContainerPath: https://myStorage.blob.core.windows.net/vulnerability-assessment/
      storageContainerSasKey: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
      vulnerabilityAssessmentName: default
      workspaceName: vulnerabilityaseessmenttest-6440

The storageContainerSasKey property replaces storageAccountAccessKey with a shared access signature token. This approach limits access duration and scope. Generate a SAS token with write permissions to the container before creating the assessment.

Configure recurring scans with email notifications

Production deployments typically enable recurring scans and configure email notifications to alert security teams when new vulnerabilities are detected.

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

const sqlPoolVulnerabilityAssessment = new azure_native.synapse.SqlPoolVulnerabilityAssessment("sqlPoolVulnerabilityAssessment", {
    recurringScans: {
        emailSubscriptionAdmins: true,
        emails: [
            "email1@mail.com",
            "email2@mail.com",
        ],
        isEnabled: true,
    },
    resourceGroupName: "vulnerabilityaseessmenttest-4799",
    sqlPoolName: "testdb",
    storageAccountAccessKey: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    storageContainerPath: "https://myStorage.blob.core.windows.net/vulnerability-assessment/",
    storageContainerSasKey: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    vulnerabilityAssessmentName: "default",
    workspaceName: "vulnerabilityaseessmenttest-6440",
});
import pulumi
import pulumi_azure_native as azure_native

sql_pool_vulnerability_assessment = azure_native.synapse.SqlPoolVulnerabilityAssessment("sqlPoolVulnerabilityAssessment",
    recurring_scans={
        "email_subscription_admins": True,
        "emails": [
            "email1@mail.com",
            "email2@mail.com",
        ],
        "is_enabled": True,
    },
    resource_group_name="vulnerabilityaseessmenttest-4799",
    sql_pool_name="testdb",
    storage_account_access_key="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    storage_container_path="https://myStorage.blob.core.windows.net/vulnerability-assessment/",
    storage_container_sas_key="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    vulnerability_assessment_name="default",
    workspace_name="vulnerabilityaseessmenttest-6440")
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := synapse.NewSqlPoolVulnerabilityAssessment(ctx, "sqlPoolVulnerabilityAssessment", &synapse.SqlPoolVulnerabilityAssessmentArgs{
			RecurringScans: &synapse.VulnerabilityAssessmentRecurringScansPropertiesArgs{
				EmailSubscriptionAdmins: pulumi.Bool(true),
				Emails: pulumi.StringArray{
					pulumi.String("email1@mail.com"),
					pulumi.String("email2@mail.com"),
				},
				IsEnabled: pulumi.Bool(true),
			},
			ResourceGroupName:           pulumi.String("vulnerabilityaseessmenttest-4799"),
			SqlPoolName:                 pulumi.String("testdb"),
			StorageAccountAccessKey:     pulumi.String("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"),
			StorageContainerPath:        pulumi.String("https://myStorage.blob.core.windows.net/vulnerability-assessment/"),
			StorageContainerSasKey:      pulumi.String("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"),
			VulnerabilityAssessmentName: pulumi.String("default"),
			WorkspaceName:               pulumi.String("vulnerabilityaseessmenttest-6440"),
		})
		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 sqlPoolVulnerabilityAssessment = new AzureNative.Synapse.SqlPoolVulnerabilityAssessment("sqlPoolVulnerabilityAssessment", new()
    {
        RecurringScans = new AzureNative.Synapse.Inputs.VulnerabilityAssessmentRecurringScansPropertiesArgs
        {
            EmailSubscriptionAdmins = true,
            Emails = new[]
            {
                "email1@mail.com",
                "email2@mail.com",
            },
            IsEnabled = true,
        },
        ResourceGroupName = "vulnerabilityaseessmenttest-4799",
        SqlPoolName = "testdb",
        StorageAccountAccessKey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
        StorageContainerPath = "https://myStorage.blob.core.windows.net/vulnerability-assessment/",
        StorageContainerSasKey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
        VulnerabilityAssessmentName = "default",
        WorkspaceName = "vulnerabilityaseessmenttest-6440",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.synapse.SqlPoolVulnerabilityAssessment;
import com.pulumi.azurenative.synapse.SqlPoolVulnerabilityAssessmentArgs;
import com.pulumi.azurenative.synapse.inputs.VulnerabilityAssessmentRecurringScansPropertiesArgs;
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 sqlPoolVulnerabilityAssessment = new SqlPoolVulnerabilityAssessment("sqlPoolVulnerabilityAssessment", SqlPoolVulnerabilityAssessmentArgs.builder()
            .recurringScans(VulnerabilityAssessmentRecurringScansPropertiesArgs.builder()
                .emailSubscriptionAdmins(true)
                .emails(                
                    "email1@mail.com",
                    "email2@mail.com")
                .isEnabled(true)
                .build())
            .resourceGroupName("vulnerabilityaseessmenttest-4799")
            .sqlPoolName("testdb")
            .storageAccountAccessKey("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
            .storageContainerPath("https://myStorage.blob.core.windows.net/vulnerability-assessment/")
            .storageContainerSasKey("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
            .vulnerabilityAssessmentName("default")
            .workspaceName("vulnerabilityaseessmenttest-6440")
            .build());

    }
}
resources:
  sqlPoolVulnerabilityAssessment:
    type: azure-native:synapse:SqlPoolVulnerabilityAssessment
    properties:
      recurringScans:
        emailSubscriptionAdmins: true
        emails:
          - email1@mail.com
          - email2@mail.com
        isEnabled: true
      resourceGroupName: vulnerabilityaseessmenttest-4799
      sqlPoolName: testdb
      storageAccountAccessKey: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
      storageContainerPath: https://myStorage.blob.core.windows.net/vulnerability-assessment/
      storageContainerSasKey: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
      vulnerabilityAssessmentName: default
      workspaceName: vulnerabilityaseessmenttest-6440

The recurringScans property enables automated scanning. Set isEnabled to true to activate recurring scans. The emails array specifies recipients for scan results, and emailSubscriptionAdmins sends notifications to subscription administrators. This configuration extends the basic storage setup from earlier examples with automation and alerting.

Beyond these examples

These snippets focus on specific vulnerability assessment features: storage authentication, recurring scan configuration, and email notification setup. They’re intentionally minimal rather than full security monitoring solutions.

The examples reference pre-existing infrastructure such as Synapse workspace and SQL pool, Azure Storage account with blob container, and storage access credentials. They focus on configuring the assessment rather than provisioning the surrounding infrastructure.

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

  • Baseline configuration and exception rules
  • Integration with Azure Security Center
  • Custom scan schedules beyond isEnabled toggle
  • Scan result retention policies

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

Let's configure Azure Synapse SQL Pool Vulnerability Assessment

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

Try Pulumi Cloud for FREE

Frequently Asked Questions

Storage & Authentication
What's the difference between using a storage account access key and a SAS key?
You must provide either storageAccountAccessKey or storageContainerSasKey for authentication, but not both. Use storageAccountAccessKey for full storage account access, or storageContainerSasKey for limited, time-bound access to the specific container.
What format should the storage container path use?
Use a blob storage URL format like https://myStorage.blob.core.windows.net/vulnerability-assessment/. This path holds the vulnerability assessment scan results.
Can I skip configuring storage if my server has a vulnerability assessment policy?
The storageContainerPath is required only if the server-level vulnerability assessment policy doesn’t set one. If a server-level policy exists with storage configured, you can omit this property.
Recurring Scans & Notifications
How do I enable recurring vulnerability scans?
Configure the recurringScans property with isEnabled set to true. You can optionally include email addresses in the emails array and set emailSubscriptionAdmins to notify subscription administrators.
Can I send scan results to multiple email addresses?
Yes, provide an array of email addresses in recurringScans.emails. Example 1 shows configuring multiple recipients like ["email1@mail.com", "email2@mail.com"].
Resource Configuration
What properties can't be changed after creating the vulnerability assessment?
The resourceGroupName, sqlPoolName, vulnerabilityAssessmentName, and workspaceName properties are immutable and require resource replacement if changed.
What should I name my vulnerability assessment?
All examples use "default" as the vulnerabilityAssessmentName. This appears to be the standard naming convention for SQL pool vulnerability assessments.

Using a different cloud?

Explore security guides for other cloud providers: