Skip to main content
Jorge Bernhardt Jorge Bernhardt
  1. Posts/

Bicep - Enabling Malware Scanning & Sensitive Data Discovery in Storage Accounts

·888 words·5 mins· 100 views · 5 likes ·
Microsoft Defender Azure CLI Microsoft Microsoft Azure

Microsoft’s Defender for Storage has recently unveiled a significant security update, with two standout features being near-real-time malware scanning and sensitive data discovery. In this article, I will guide you on how to enable these features across all your Azure storage accounts using Bicep.

Important: To ensure all storage accounts in your subscription are protected, including future ones, it is recommended by Microsoft to enable Defender for Storage at the subscription level. However, it is also possible to enable and configure Microsoft Defender for Storage on specific storage accounts. This article provides detailed steps on how to make these changes at the subscription level.


Prerequisites #

Before you start, you’ll need the following to deploy and manage resources with Bicep:

  • You need Azure CLI version 2.20.0 or later to deploy Bicep files on your local machine.
  • A text editor or IDE of your choice (Visual Studio Code with Bicep extension is my recommendation)
Create the Bicep file>

Create the Bicep file #

The first step in deploying a Bicep template is to create the Bicep file that defines your resources. Create a new file named defenderForStorage.bicep. This file will contain the code needed to define and configure the deployment of your resources.

targetScope = 'subscription'

@description('Pricing tier for Microsoft Defender for Cloud.')
param pricingTier string = 'Standard'

@description('Optional sub-plan selected for a Standard pricing configuration.')
param subPlan string = 'DefenderForStorageV2'

@description('Enable or disable the On-upload malware scanning feature.')
param onUploadMalwareScanningEnabled bool = true

@description('Monthly cap in GB for malware scanning per storage account. Set to -1 for unlimited scanning.')
param malwareScanningCapGB int

@description('Enable or disable the Sensitive data discovery feature.')
param sensitiveDataDiscoveryEnabled bool = true

resource defenderForStorageSettings 'Microsoft.Security/pricings@2023-01-01' = {
  name: 'StorageAccounts'
  properties: {
    pricingTier: pricingTier
    subPlan: (pricingTier == 'Free') ? null : subPlan
    extensions: (pricingTier == 'Standard') ? [
        name: 'OnUploadMalwareScanning'
        isEnabled: string(onUploadMalwareScanningEnabled)
        additionalExtensionProperties: {
          CapGBPerMonthPerStorageAccount: malwareScanningCapGB
        name: 'SensitiveDataDiscovery'
        isEnabled: string(sensitiveDataDiscoveryEnabled)
    ] : []

output pricingTierApplied string =
output subPlanApplied string = (pricingTier == 'Standard') ? : 'N/A'
output onUploadMalwareScanningEnabledApplied string = (pricingTier == 'Standard') ?[0].isEnabled : 'N/A'
output malwareScanningCapGBApplied string = (pricingTier == 'Standard') ?[0].additionalExtensionProperties.CapGBPerMonthPerStorageAccount : 'N/A'
output sensitiveDataDiscoveryEnabledApplied string = (pricingTier == 'Standard') ?[1].isEnabled : 'N/A'

subPlan: When Standard is chosen for pricingTier, subPlan allows you to select a specific set of security features within that tier. In this case, the subPlan value of interest to us would be DefenderForStorageV2.

OnUploadMalwareScanning: This extension is enabled (isEnabled: ‘True’) and has an additional property CapGBPerMonthPerStorageAccount : To limit the amount of data scanned for malware each month per storage account, a maximum cap can be set using this parameter. If you want to allow unlimited scanning, simply assign the value of -1.

SensitiveDataDiscovery: This extension is enabled (isEnabled: ‘True’) but has no additional properties. It refers to enabling the feature for discovering sensitive data within the storage accounts.

Deployment scope>

Deployment scope #

In Bicep, you can target your deployment to a resource group, subscription, management group, or tenant. In this case, when enabling Microsoft Defender for storage, the valid deployment scopes are resource group or subscription. For this example, I’ll use a subscription as the scope.

Deploy the Bicep template using the Azure CLI>

Deploy the Bicep template using the Azure CLI #

Once your Bicep template is prepared, and you’ve selected your desired scope, you can proceed to deploy the template through the Azure CLI. To do so, execute the following commands.


Parameters #

Personalization is key to making your template reusable. With the parameters, you can easily tailor the template to your specific needs. You can use either inline parameters or a parameter file to pass parameter values. In my case, I will use a file to pass the parameters; here is an example.

    "$schema": "",
    "contentVersion": "",
    "parameters": {
      "pricingTier": {
        "value": "Standard"
      "subPlan": {
        "value": "DefenderForStorageV2"
      "onUploadMalwareScanningEnabled": {
        "value": true
      "malwareScanningCapGB": {
        "value": 100
      "sensitiveDataDiscoveryEnabled": {
        "value": true

Important: Please note that the parameter file stores parameter values in plain text format. If you need to include a parameter with sensitive data, it’s recommended to store the value in a secure key vault.

Preview changes>

Preview changes #

Before deploying a Bicep file, you can preview the changes that will occur to your resources. Using what-if operations does not change existing resources; it simply shows you an output that includes color-coded results that allow you to see different changes.

az deployment sub what-if \
--template-file <filename>.bicep \
--parameters @<filename>.paramaters.json \
--location <location> 
Deploy the Azure resource>

Deploy the Azure resource #

Finally, to deploy the template, run the following command.

az deployment sub create \
--template-file <filename>.bicep \
--parameters @<filename>.paramaters.json \
--location <location> 
Validate the deployment>

Validate the deployment #

To verify that the changes have been applied correctly, you can use the Azure portal or the command line tools. For the Azure CLI for example, use the following command.

az security pricing show \
--name "StorageAccounts" \
--query "[{Name:name, PricingTier:pricingTier, SubPlan:subPlan}]" \
--output table 

References and useful links #

Thank you for taking the time to read my post. I sincerely hope that you find it helpful.