Intermediate ⏱ 90 min 📋 12 Steps

Implement Cloud Security Posture Management

Enable Defender CSPM, create custom security initiatives, configure governance rules, map controls to regulatory frameworks, build a compliance dashboard, and automate remediation to manage cloud security posture at scale.

๐Ÿ“‹ Overview

About This Lab

Cloud Security Posture Management (CSPM) is a discipline within Defender for Cloud that continuously assesses your Azure resources against security benchmarks and regulatory frameworks. Defender CSPM extends foundational CSPM with attack path analysis, cloud security graph, governance rules, and advanced compliance mapping capabilities. In this lab you will enable the Defender CSPM plan, create custom security initiatives using Azure Policy, configure governance rules for recommendation ownership, and build compliance dashboards. You will also configure attack path analysis, build KQL queries for posture assessment, set up continuous export, and automate remediation with DeployIfNotExists policies. By the end of this lab, you will have a comprehensive CSPM strategy that covers posture assessment, governance, compliance mapping, and automated remediation.

๐Ÿข Enterprise Use Case

Scenario: Contoso Insurance operates 500 Azure resources spanning virtual machines, storage accounts, SQL databases, and App Services across three Azure regions. The company must meet multiple regulatory frameworks: PCI DSS for payment card processing, SOC 2 for service organization controls, and HIPAA for protected health information.

Each framework assigns different controls to the same underlying resources, creating a complex compliance matrix that the security team must manage and report against. The CISO requires automated governance so that each security recommendation has an assigned owner, a remediation deadline, and an escalation path. Auditors request quarterly compliance reports showing control coverage, remediation trends, and risk posture across all three frameworks.

Success criteria: Defender CSPM enabled, custom initiatives aligned to all three frameworks, governance rules assigning ownership, automated remediation for common misconfigurations, and auditor-ready reports.

๐ŸŽฏ What You Will Learn

  1. Differentiate between foundational CSPM and Defender CSPM capabilities
  2. Enable the Defender CSPM plan on an Azure subscription
  3. Create custom security initiatives with Azure Policy and assign them to subscriptions
  4. Configure governance rules that assign recommendation owners and set remediation deadlines
  5. Map security controls to PCI DSS, SOC 2, and HIPAA regulatory frameworks
  6. Write KQL queries to assess cloud security posture using the SecurityRecommendation table
  7. Configure attack path analysis to identify exploitable resource chains
  8. Build an Azure Monitor Workbook for cloud security posture visualization
  9. Set up continuous export of recommendations and compliance data to Log Analytics
  10. Automate remediation using Azure Policy DeployIfNotExists effects
  11. Generate compliance reports suitable for external auditors

๐Ÿ”‘ Why This Matters

Organizations with 500+ cloud resources cannot manually track security posture; automation and governance are essential. Regulatory compliance requires demonstrable evidence that controls are in place and misconfigurations are remediated within defined timeframes. Without CSPM, security teams lack visibility into which resources are non-compliant and which misconfigurations pose the greatest risk. Attack path analysis reveals how an attacker could chain together multiple low-severity misconfigurations to reach critical assets. Automated remediation with DeployIfNotExists policies ensures that new resources are born compliant, reducing the backlog of security findings.

โš™๏ธ Prerequisites

  • Azure Subscription: An active Azure subscription with at least one resource group containing resources to assess
  • Role: Security Admin or Contributor role on the subscription; Owner role is required for policy assignments
  • Completed Lab 01: Familiarity with Defender for Cloud basics from Lab 01: Enable Defender for Servers Plan 2
  • Azure CLI: Version 2.50 or later installed locally or use Azure Cloud Shell
  • PowerShell: Az.Security and Az.PolicyInsights modules installed
  • Log Analytics Workspace: An existing workspace or the ability to create one for continuous export
  • Portal Access: Access to the Azure portal with permissions to modify Defender for Cloud settings and assign policies
Note: Defender CSPM is a paid plan billed per resource per hour. Review the pricing page before enabling on production subscriptions. A free trial subscription works for this lab.

Step 1 ยท Understand CSPM vs CWP in Defender for Cloud

Defender for Cloud provides two complementary security disciplines: Cloud Security Posture Management (CSPM) and Cloud Workload Protection (CWP). Understanding the distinction is critical before configuring posture management.

Cloud Security Posture Management (CSPM)

  • Focuses on continuous assessment of resource configurations against security benchmarks
  • Identifies misconfigurations such as open storage accounts, missing encryption, and overly permissive network rules
  • Provides Secure Score, security recommendations, and compliance mapping to regulatory frameworks
  • Foundational CSPM is free and includes the Microsoft Cloud Security Benchmark and basic recommendations
  • Defender CSPM adds attack path analysis, cloud security graph, governance rules, and agentless scanning

Cloud Workload Protection (CWP)

  • Focuses on runtime threat detection and response for specific workload types
  • Includes plans like Defender for Servers, Defender for Databases, Defender for Containers, and Defender for App Service
  • Detects active threats such as malware execution, brute-force attacks, and SQL injection attempts
  • Provides security alerts with investigation details and response recommendations

Foundational CSPM vs Defender CSPM

  • Foundational (Free): Secure Score, basic recommendations, Microsoft Cloud Security Benchmark
  • Defender CSPM (Paid): All foundational capabilities plus attack path analysis, cloud security graph, governance rules, agentless scanning for VMs, regulatory compliance mapping beyond the default benchmark, and data-aware security posture
Key Insight: CSPM and CWP are complementary. CSPM tells you what is misconfigured before an attack happens. CWP detects attacks that exploit those misconfigurations in real time. A mature security strategy uses both.

Step 2 ยท Enable Defender CSPM Plan

Enable the Defender CSPM plan on your subscription to unlock advanced posture management capabilities including attack path analysis and governance rules.

Enable via the Azure Portal

  1. Navigate to Microsoft Defender for Cloud in the Azure portal
  2. Select Environment settings from the left menu
  3. Expand your management group hierarchy and select your target subscription
  4. On the Defender plans page, locate the CSPM row
  5. Toggle the plan status to On
  6. Under Settings, verify that Agentless scanning for machines and Attack path analysis are enabled
  7. Click Save to apply the changes

Enable via Azure CLI

# Switch to the subscription where you want to enable CSPM.
az account set --subscription "YOUR_SUBSCRIPTION_ID"

# Enable the Defender CSPM (Cloud Security Posture Management) plan.
# "CloudPosture" is the API name for CSPM; Standard tier activates
# paid features: attack path analysis, governance rules, and agentless scanning.
az security pricing create \
  --name CloudPosture \
  --tier Standard

# Confirm the plan is active. Expect Tier = "Standard".
az security pricing show \
  --name CloudPosture \
  --query "{Plan:name, Tier:pricingTier}" \
  -o json

Enable via PowerShell

# Authenticate to Azure (opens browser login).
Connect-AzAccount
Set-AzContext -SubscriptionId "YOUR_SUBSCRIPTION_ID"

# Enable Defender CSPM. This turns on attack path analysis,
# governance rules, cloud security explorer, and agentless scanning.
Set-AzSecurityPricing -Name "CloudPosture" -PricingTier "Standard"

# Verify. PricingTier should show "Standard" (not "Free").
Get-AzSecurityPricing -Name "CloudPosture" | Format-List Name, PricingTier
Tip: The API name for the Defender CSPM plan is "CloudPosture." This is different from the portal display name. Use this value in all CLI and PowerShell automation scripts.

Step 3 ยท Review and Customize Security Initiatives

Security initiatives in Defender for Cloud are collections of Azure Policy definitions grouped by security domain. The default initiative is the Microsoft Cloud Security Benchmark (MCSB).

View the Default Initiative in the Portal

  1. Navigate to Defender for Cloud and select Environment settings
  2. Select your subscription and click Security policy
  3. The Microsoft Cloud Security Benchmark is assigned by default and cannot be removed
  4. Review the controls: Network Security, Identity Management, Data Protection, Asset Management, and others
  5. Click any control to see the individual policy definitions and their effect (Audit, Deny, DeployIfNotExists)

List Assigned Initiatives with Azure CLI

# Show every Azure Policy assignment on this subscription.
# Look for "SecurityCenterBuiltIn" - this is the Microsoft Cloud Security Benchmark
# that Defender for Cloud assigns automatically.
az policy assignment list \
  --scope "/subscriptions/YOUR_SUBSCRIPTION_ID" \
  --query "[].{Name:displayName, Id:name}" \
  -o table

# Inspect the default security benchmark assignment.
# EnforcementMode = "Default" means non-compliant resources are flagged
# but not blocked (audit only).
az policy assignment show \
  --name "SecurityCenterBuiltIn" \
  --scope "/subscriptions/YOUR_SUBSCRIPTION_ID" \
  --query "{Name:displayName, EnforcementMode:enforcementMode}" \
  -o json

Add a Regulatory Compliance Standard

  1. In the Security policy blade, click Add more standards
  2. Search for PCI DSS v4 and click Add
  3. Repeat for SOC 2 Type 2 and HIPAA/HITRUST
  4. Each standard maps existing recommendations to its controls without creating new policy definitions
  5. Allow 30 to 60 minutes for the compliance assessment to complete after adding a new standard
Important: Adding regulatory standards requires the Defender CSPM plan. Foundational CSPM only supports the default Microsoft Cloud Security Benchmark.

Step 4 ยท Create a Custom Security Initiative with Azure Policy

When built-in standards do not cover your organization's specific requirements, create a custom initiative that groups the exact policy definitions you need.

Custom Initiative JSON Definition

{
  "properties": {
    "displayName": "Contoso Insurance. Cloud Security Baseline",
    "description": "Custom security initiative for Contoso Insurance covering PCI DSS, SOC 2, and HIPAA requirements across all Azure resources.",
    "metadata": {
      "category": "Security Center",
      "version": "1.0.0"
    },
    "policyDefinitions": [
      {
        "policyDefinitionId": "/providers/Microsoft.Authorization/policyDefinitions/404c3081-a854-4457-ae30-26a93ef643f9",
        "policyDefinitionReferenceId": "secureTransferToStorageAccounts",
        "parameters": {}
      },
      {
        "policyDefinitionId": "/providers/Microsoft.Authorization/policyDefinitions/22bee202-a82f-4305-9a2a-6d7f44d4dedb",
        "policyDefinitionReferenceId": "allowedLocations",
        "parameters": {
          "listOfAllowedLocations": {
            "value": ["eastus", "westus2", "westeurope"]
          }
        }
      },
      {
        "policyDefinitionId": "/providers/Microsoft.Authorization/policyDefinitions/0961003e-5a0a-4549-abde-af6a37f2724d",
        "policyDefinitionReferenceId": "auditVMsWithoutDiskEncryption",
        "parameters": {}
      },
      {
        "policyDefinitionId": "/providers/Microsoft.Authorization/policyDefinitions/a6fb4358-5bf4-4ad7-ba82-2cd2f41ce5e9",
        "policyDefinitionReferenceId": "sqlAuditingEnabled",
        "parameters": {}
      }
    ]
  }
}

Create and Assign the Initiative with Azure CLI

# Upload the JSON file as a custom initiative (policy set) definition.
# --definitions points to the JSON file containing the policy definitions array.
az policy set-definition create \
  --name "contoso-security-baseline" \
  --display-name "Contoso Insurance. Cloud Security Baseline" \
  --description "Custom initiative for PCI DSS, SOC 2, and HIPAA" \
  --definitions @initiative-definitions.json \
  --subscription "YOUR_SUBSCRIPTION_ID"

# Assign the initiative to the subscription so policies begin evaluating.
# --enforcement-mode Default = audit mode (flags non-compliance without blocking).
az policy assignment create \
  --name "contoso-baseline-assignment" \
  --display-name "Contoso Security Baseline Assignment" \
  --policy-set-definition "contoso-security-baseline" \
  --scope "/subscriptions/YOUR_SUBSCRIPTION_ID" \
  --enforcement-mode Default

Verify the Assignment

# Confirm the Contoso initiative assignment was created successfully.
az policy assignment list \
  --scope "/subscriptions/YOUR_SUBSCRIPTION_ID" \
  --query "[?contains(displayName,'Contoso')].{Name:displayName, Enforcement:enforcementMode}" \
  -o table

# Trigger an immediate compliance evaluation (normally runs every ~24 hours).
# --no-wait returns immediately; the scan runs asynchronously in the background.
az policy state trigger-scan \
  --subscription "YOUR_SUBSCRIPTION_ID" \
  --no-wait
Tip: Save your initiative JSON definition in source control. This allows you to version your security baseline and deploy it across multiple subscriptions using CI/CD pipelines.

Step 5 ยท Configure Governance Rules for Recommendation Ownership

Governance rules in Defender for Cloud let you assign owners to security recommendations, set remediation deadlines, and send email notifications. This ensures accountability and tracks remediation progress.

Create a Governance Rule in the Portal

  1. Navigate to Defender for Cloud and select Environment settings
  2. Select your subscription, then click Governance rules
  3. Click Create governance rule
  4. Set the Rule name to "High Severity. 14 Day Remediation"
  5. Under Scope, select the target subscription
  6. Under Conditions, set Severity to High
  7. Set Owner to "By resource tag" and specify the tag key as "SecurityOwner"
  8. Set Remediation timeframe to 14 days
  9. Enable Email notifications so owners are alerted when new recommendations are assigned
  10. Set Grace period notification to send reminders 7 days before the deadline
  11. Click Create to save the rule

Create Additional Rules for Medium and Low Severity

  • Create a second rule: "Medium Severity. 30 Day Remediation" with a 30-day deadline
  • Create a third rule: "Low Severity. 90 Day Remediation" with a 90-day deadline
  • This tiered approach ensures that the most critical findings are addressed first while still tracking lower-severity items

Tag Resources for Owner Assignment

# Assign any Azure resource a "SecurityOwner" tag so governance rules
# can automatically route new recommendations to the right person.
az tag update \
  --resource-id "/subscriptions/YOUR_SUBSCRIPTION_ID/resourceGroups/rg-production/providers/Microsoft.Compute/virtualMachines/vm-web-01" \
  --operation Merge \
  --tags SecurityOwner="alice@contoso.com"

# Bulk-tag every VM in a resource group with a team-level owner.
# The for-loop iterates all VM IDs and merges the tag non-destructively.
for vm in $(az vm list -g rg-production --query "[].id" -o tsv); do
  az tag update --resource-id "$vm" --operation Merge \
    --tags SecurityOwner="infra-team@contoso.com"
done
Tip: Governance rules require the Defender CSPM plan. The rules evaluate automatically as new recommendations appear, ensuring continuous accountability without manual triage.

Step 6 ยท Map Security Controls to Regulatory Frameworks

Regulatory compliance in Defender for Cloud maps your security recommendations to framework-specific controls. This step shows how to interpret and work with the compliance dashboard for PCI DSS, SOC 2, and HIPAA.

Navigate the Compliance Dashboard

  1. In Defender for Cloud, select Regulatory compliance from the left menu
  2. The dashboard displays each assigned standard with a compliance percentage
  3. Click a standard (for example, PCI DSS v4) to see the list of controls
  4. Each control shows the number of passed, failed, and not-applicable assessments
  5. Click a specific control to see the underlying recommendations and affected resources

Understand Control Mapping

  • PCI DSS Requirement 1: Install and maintain network security controls. maps to NSG, firewall, and network segmentation recommendations
  • PCI DSS Requirement 3: Protect stored account data. maps to encryption at rest and key management recommendations
  • SOC 2 CC6.1: Logical and physical access controls. maps to identity, RBAC, and MFA recommendations
  • HIPAA 164.312(a)(1): Access control. maps to authentication and authorization recommendations
  • HIPAA 164.312(e)(1): Transmission security. maps to TLS/SSL and encryption in transit recommendations

Query Compliance State with Azure CLI

# List all regulatory compliance standards currently configured.
# State = "Enabled" means Defender for Cloud is evaluating against that standard.
az security regulatory-compliance-standards list \
  --query "[].{Standard:name, State:state}" \
  -o table

# Show each PCI DSS v4 control with pass/fail counts.
# Controls with high FailedAssessments need immediate remediation attention.
az security regulatory-compliance-controls list \
  --standard-name "PCI-DSS-4" \
  --query "[].{Control:name, State:state, Passed:passedAssessments, Failed:failedAssessments}" \
  -o table

# Drill into a specific control (e.g., Control 1: network security).
# Shows which individual assessments (recommendations) are passing or failing.
az security regulatory-compliance-assessments list \
  --standard-name "PCI-DSS-4" \
  --control-name "1" \
  --query "[].{Assessment:name, State:state, ResourceCount:resourceCount}" \
  -o table
Important: Compliance percentages reflect the status of automated assessments only. Some controls require manual attestation (for example, physical security or employee background checks) and will show as "Manual" in the dashboard.

Step 7 ยท Build Custom KQL Queries for Posture Assessment

KQL queries against the SecurityRecommendation and SecurityAlert tables in Log Analytics provide deep visibility into your security posture. These queries power dashboards, alerts, and executive reports.

Top Unhealthy Recommendations by Resource Count

// Find the 20 recommendations affecting the most resources.
// AffectedResources = distinct count of non-compliant resources per recommendation.
// Use this to prioritise: fixing one recommendation may resolve hundreds of findings.
SecurityRecommendation
| where TimeGenerated > ago(1d)
| where RecommendationState == "Unhealthy"
| summarize AffectedResources = dcount(ResourceId) by
    RecommendationDisplayName, RecommendationSeverity
| order by AffectedResources desc
| take 20

Posture Trend Over 30 Days

// Track security posture improvement over 30 days.
// Healthy = resources passing all checks; Unhealthy = resources with open findings.
// CompliancePercent trending upward means your remediation efforts are working.
// Use this as a line chart in Azure Workbooks for executive reporting.
SecurityRecommendation
| where TimeGenerated > ago(30d)
| summarize
    Healthy = dcountif(ResourceId, RecommendationState == "Healthy"),
    Unhealthy = dcountif(ResourceId, RecommendationState == "Unhealthy")
    by bin(TimeGenerated, 1d)
| extend CompliancePercent = round(100.0 * Healthy / (Healthy + Unhealthy), 1)
| order by TimeGenerated asc
| project TimeGenerated, Healthy, Unhealthy, CompliancePercent

Resource Groups with the Most Findings

// Identify the resource groups with the most security findings.
// split(ResourceId, "/")[4] extracts the resource-group name from the ARM path.
// Resource groups at the top of this list should be reviewed first  - 
// they represent the biggest concentration of security debt.
SecurityRecommendation
| where TimeGenerated > ago(1d)
| where RecommendationState == "Unhealthy"
| extend ResourceGroup = tostring(split(ResourceId, "/")[4])
| summarize FindingCount = count() by ResourceGroup, RecommendationSeverity
| order by FindingCount desc
| take 15

Encryption and Network Security Posture

// Measure encryption and network security compliance for each recommendation.
// ComplianceRate = percentage of resources meeting the control.
// Rates below 90% signal areas where data-in-transit or network exposure
// controls need urgent attention (relevant to PCI DSS 4.1 and HIPAA 164.312(e)).
SecurityRecommendation
| where TimeGenerated > ago(1d)
| where RecommendationDisplayName has_any (
    "encryption", "TLS", "SSL", "HTTPS",
    "network security group", "public access", "firewall"
)
| summarize
    HealthyCount = countif(RecommendationState == "Healthy"),
    UnhealthyCount = countif(RecommendationState == "Unhealthy")
    by RecommendationDisplayName
| extend ComplianceRate = round(100.0 * HealthyCount / (HealthyCount + UnhealthyCount), 1)
| order by UnhealthyCount desc
Tip: These queries require continuous export to be configured (Step 10). Without it, the SecurityRecommendation table in Log Analytics will be empty.

Step 8 ยท Configure Attack Path Analysis

Attack path analysis uses the cloud security graph to identify sequences of misconfigurations that an attacker could exploit to reach high-value targets. This capability is exclusive to the Defender CSPM plan.

View Attack Paths in the Portal

  1. In Defender for Cloud, select Attack path analysis from the left menu
  2. The dashboard shows discovered attack paths sorted by risk level
  3. Click an attack path to see the full chain: entry point, intermediate steps, and target resource
  4. Review the graph visualization showing how misconfigurations connect
  5. Each node in the path shows the specific misconfiguration and the recommendation to fix it

Common Attack Path Scenarios

  • Internet-exposed VM with high privileges: A VM with a public IP, open management ports, and a managed identity with Contributor role on the subscription
  • Storage account with sensitive data: A publicly accessible storage account containing PII, reachable from a compromised web application
  • Lateral movement through key vault: A compromised VM whose managed identity has access to a key vault containing database connection strings
  • Over-permissioned service principal: An App Service with a service principal that has Owner role, accessible through an unpatched web framework

Query Attack Paths with the Cloud Security Graph

// Cloud Security Explorer query: Find VMs exposed to the internet
// with high-privilege managed identities
//
// Navigate to: Defender for Cloud > Cloud Security Explorer
// Build the query:
//   Source: Virtual Machines
//   Condition 1: Has public IP address
//   Condition 2: Has managed identity with role assignment
//   Condition 3: Role is Contributor or Owner
//
// This identifies attack paths where a compromised VM could
// escalate privileges through its managed identity
Key Insight: Attack path analysis aggregates individually low-severity findings into high-risk chains. A VM with a public IP (medium severity) combined with an over-permissioned identity (medium severity) becomes a critical attack path. Prioritize remediating attack paths over individual recommendations.

Step 9 ยท Create a Cloud Security Posture Workbook

Azure Monitor Workbooks provide interactive dashboards for visualizing your cloud security posture. You will build a workbook that displays posture trends, top recommendations, and compliance status.

Create the Workbook

  1. Navigate to Azure Monitor in the Azure portal and select Workbooks
  2. Click New to create a blank workbook
  3. Click Add and select Add text; enter the title "Cloud Security Posture Dashboard"
  4. Click Add and select Add query
  5. Set the data source to Logs and select your Log Analytics workspace

Workbook Panel 1: Posture Summary

// Posture Summary tile: single-row overview of total, healthy, and unhealthy
// resource counts with an overall PostureScore percentage.
// Display as a Tile visualization in Workbooks.
SecurityRecommendation
| where TimeGenerated > ago(1d)
| summarize
    TotalResources = dcount(ResourceId),
    Healthy = dcountif(ResourceId, RecommendationState == "Healthy"),
    Unhealthy = dcountif(ResourceId, RecommendationState == "Unhealthy")
| extend PostureScore = round(100.0 * Healthy / TotalResources, 1)

Workbook Panel 2: Severity Distribution

// Severity Distribution tile: count of unhealthy resources per severity level.
// Display as a Pie chart so stakeholders instantly see the High vs. Medium balance.
SecurityRecommendation
| where TimeGenerated > ago(1d)
| where RecommendationState == "Unhealthy"
| summarize Count = dcount(ResourceId) by RecommendationSeverity
| order by Count desc

Workbook Panel 3: 30-Day Trend Line

// 30-Day Trend tile: daily count of unhealthy resources.
// Display as a Line chart. A downward trend confirms remediation progress;
// a spike may indicate new resources deployed without security controls.
SecurityRecommendation
| where TimeGenerated > ago(30d)
| summarize Unhealthy = dcountif(ResourceId, RecommendationState == "Unhealthy")
    by bin(TimeGenerated, 1d)
| order by TimeGenerated asc
  1. Set the visualization type for Panel 1 to Tiles
  2. Set Panel 2 to Pie chart for severity distribution
  3. Set Panel 3 to Line chart for trend visualization
  4. Click Save and name the workbook "CSPM Posture Dashboard"
  5. Pin the workbook to an Azure Dashboard for quick access
Tip: Share the workbook with your security team by saving it to a shared resource group. Workbooks support parameterized filters so users can drill down by subscription, resource group, or severity.

Step 10 ยท Set Up Continuous Export to Log Analytics

Continuous export streams Defender for Cloud recommendations, alerts, and compliance data to a Log Analytics workspace. This is required for the KQL queries and workbooks you built in previous steps.

Configure via the Portal

  1. In Defender for Cloud, select Environment settings
  2. Select your subscription and click Continuous export
  3. Select the Log Analytics workspace tab
  4. Under Exported data types, enable: Security recommendations, Secure Score, Regulatory compliance, and Security alerts
  5. Set the Export frequency to streaming (real-time updates)
  6. Select your target Log Analytics workspace
  7. Click Save to start the export

Configure via Azure CLI

# Create a continuous export automation that streams recommendations,
# secure scores, and compliance data to your Log Analytics workspace.
# This populates the SecurityRecommendation and SecureScores tables
# used by the KQL queries and Workbook panels in this lab.
az security automation create \
  --name "export-to-log-analytics" \
  --resource-group "rg-security" \
  --scopes "[{\"description\":\"Subscription\",\"scopePath\":\"/subscriptions/YOUR_SUBSCRIPTION_ID\"}]" \
  --sources "[{\"eventSource\":\"Assessments\"},{\"eventSource\":\"SecureScores\"},{\"eventSource\":\"RegulatoryComplianceAssessment\"}]" \
  --actions "[{\"actionType\":\"Workspace\",\"workspaceResourceId\":\"/subscriptions/YOUR_SUBSCRIPTION_ID/resourceGroups/rg-security/providers/Microsoft.OperationalInsights/workspaces/law-security\"}]"

Configure via PowerShell

# Build the continuous export configuration object in PowerShell.
# Three event sources ensure you capture:
#   Assessments - individual security recommendations per resource.
#   SecureScores - aggregate posture scores per subscription.
#   RegulatoryComplianceAssessment - per-control compliance status.
$scope = @{
    Description = "Subscription scope"
    ScopePath = "/subscriptions/YOUR_SUBSCRIPTION_ID"
}

$source = @(
    @{ EventSource = "Assessments" },
    @{ EventSource = "SecureScores" },
    @{ EventSource = "RegulatoryComplianceAssessment" }
)

# Replace with your actual Log Analytics workspace resource ID.
$workspaceId = "/subscriptions/YOUR_SUBSCRIPTION_ID/resourceGroups/rg-security/providers/Microsoft.OperationalInsights/workspaces/law-security"

# Assemble the REST API request body and deploy via Invoke-AzRestMethod.
$body = @{
    properties = @{
        scopes = @($scope)
        sources = $source
        actions = @(@{
            actionType = "Workspace"
            workspaceResourceId = $workspaceId
        })
    }
} | ConvertTo-Json -Depth 10

# Send the PUT request to create the export automation resource.
Invoke-AzRestMethod -Method PUT `
  -Path "/subscriptions/YOUR_SUBSCRIPTION_ID/resourceGroups/rg-security/providers/Microsoft.Security/automations/export-to-la?api-version=2019-01-01-preview" `
  -Payload $body

Verify Data Is Flowing

// Verify continuous export is working: check for data ingested in the last hour.
// If Count > 0, the export pipeline is healthy.
// Allow 15-30 minutes after initial setup before running this check.
SecurityRecommendation
| where TimeGenerated > ago(1h)
| summarize Count = count() by RecommendationState
| order by Count desc
Important: Continuous export may take 15 to 30 minutes to begin populating data in Log Analytics. If you see no data after an hour, verify the workspace resource ID and check that the export configuration status shows "Enabled."

Step 11 ยท Automate Remediation with Azure Policy DeployIfNotExists

DeployIfNotExists (DINE) policies automatically remediate non-compliant resources by deploying the required configuration. This ensures new resources are born compliant and reduces the security team's manual workload.

Example: Enforce HTTPS on Storage Accounts

{
  "mode": "All",
  "policyRule": {
    "if": {
      "allOf": [
        {
          "field": "type",
          "equals": "Microsoft.Storage/storageAccounts"
        },
        {
          "field": "Microsoft.Storage/storageAccounts/supportsHttpsTrafficOnly",
          "notEquals": true
        }
      ]
    },
    "then": {
      "effect": "DeployIfNotExists",
      "details": {
        "type": "Microsoft.Storage/storageAccounts",
        "existenceCondition": {
          "field": "Microsoft.Storage/storageAccounts/supportsHttpsTrafficOnly",
          "equals": true
        },
        "roleDefinitionIds": [
          "/providers/Microsoft.Authorization/roleDefinitions/17d1049b-9a84-46fb-8f53-869881c3d3ab"
        ],
        "deployment": {
          "properties": {
            "mode": "incremental",
            "template": {
              "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
              "contentVersion": "1.0.0.0",
              "resources": [
                {
                  "type": "Microsoft.Storage/storageAccounts",
                  "apiVersion": "2023-01-01",
                  "name": "[field('name')]",
                  "location": "[field('location')]",
                  "properties": {
                    "supportsHttpsTrafficOnly": true
                  }
                }
              ]
            }
          }
        }
      }
    }
  }
}

Assign the Policy and Create a Remediation Task

# Create a custom policy definition from the JSON rule file above.
# This policy uses the DeployIfNotExists effect to automatically enable
# HTTPS on any storage account that has it disabled.
az policy definition create \
  --name "enforce-https-storage" \
  --display-name "Enforce HTTPS on Storage Accounts" \
  --mode All \
  --rules @policy-rule.json \
  --subscription "YOUR_SUBSCRIPTION_ID"

# Assign the policy. --mi-system-assigned creates a managed identity
# so the policy engine can deploy the remediation ARM template.
az policy assignment create \
  --name "enforce-https-storage-assignment" \
  --display-name "Enforce HTTPS on Storage Accounts" \
  --policy "enforce-https-storage" \
  --scope "/subscriptions/YOUR_SUBSCRIPTION_ID" \
  --mi-system-assigned \
  --location "eastus"

# Fix existing non-compliant storage accounts with a remediation task.
# This triggers the DeployIfNotExists template on every non-compliant resource.
az policy remediation create \
  --name "remediate-https-storage" \
  --policy-assignment "enforce-https-storage-assignment" \
  --resource-group "rg-production"

# Monitor remediation progress. Status = "Succeeded" when all resources are fixed.
az policy remediation show \
  --name "remediate-https-storage" \
  --resource-group "rg-production" \
  --query "{Status:provisioningState, Deployed:deploymentStatus.totalDeployments}" \
  -o json

Monitor Remediation with PowerShell

# Group policy evaluation results by compliance state.
# Expected output: "Compliant" and "NonCompliant" counts.
# 100% Compliant means the DINE policy has remediated all storage accounts.
Get-AzPolicyState -SubscriptionId "YOUR_SUBSCRIPTION_ID" `
  -Filter "PolicyDefinitionName eq 'enforce-https-storage'" |
  Group-Object ComplianceState |
  Select-Object Name, Count

# List the specific resources still failing the HTTPS policy.
# Use this to investigate why certain storage accounts were not auto-remediated
# (e.g., resource locks, insufficient managed identity permissions).
Get-AzPolicyState -SubscriptionId "YOUR_SUBSCRIPTION_ID" `
  -Filter "PolicyDefinitionName eq 'enforce-https-storage' and ComplianceState eq 'NonCompliant'" |
  Select-Object ResourceId, ComplianceState, Timestamp
Tip: DeployIfNotExists policies require a managed identity with sufficient permissions to deploy the remediation template. The role definition ID in the policy must match the permissions needed. For storage account modifications, use the Storage Account Contributor role.

Step 12 ยท Generate a Compliance Report for Auditors

Auditors require evidence of security controls, compliance status, and remediation activities. This step shows how to generate comprehensive reports from Defender for Cloud and Log Analytics.

Export from the Compliance Dashboard

  1. Navigate to Defender for Cloud and select Regulatory compliance
  2. Select the standard you want to report on (for example, PCI DSS v4)
  3. Click Download report at the top of the page
  4. Choose PDF for executive summaries or CSV for detailed control-level data
  5. The report includes: overall compliance percentage, control status, affected resources, and remediation recommendations

KQL Query: Compliance Summary Across All Frameworks

// Compliance summary: pass/fail counts and compliance percentage per framework.
// CompliancePercent below 80% indicates significant gaps needing remediation.
// Export this output as evidence for auditors during compliance assessments.
SecurityRegulatoryCompliance
| where TimeGenerated > ago(1d)
| summarize
    PassedControls = countif(State == "Passed"),
    FailedControls = countif(State == "Failed"),
    SkippedControls = countif(State == "Skipped")
    by ComplianceStandard = RecommendationName
| extend CompliancePercent = round(
    100.0 * PassedControls / (PassedControls + FailedControls), 1)
| project ComplianceStandard, PassedControls, FailedControls,
    SkippedControls, CompliancePercent
| order by CompliancePercent asc

KQL Query: Remediation Activity Log

// Track weekly remediation velocity over the past 90 days.
// RemediatedCount = distinct resources that moved to "Healthy" state each week.
// An increasing count demonstrates steady security improvement to auditors.
SecurityRecommendation
| where TimeGenerated > ago(90d)
| where RecommendationState == "Healthy"
| summarize RemediatedCount = dcount(ResourceId)
    by bin(TimeGenerated, 7d), RecommendationSeverity
| order by TimeGenerated asc
| project WeekOf = TimeGenerated, Severity = RecommendationSeverity,
    RemediatedCount

Generate a Report via Azure CLI

# Export all compliance standards with their enabled/disabled state to CSV.
az security regulatory-compliance-standards list \
  --query "[].{Standard:name, State:state}" \
  -o csv > compliance-standards.csv

# Export only the failing PCI DSS controls with pass/fail counts.
# Share this file with auditors as evidence of control gaps.
az security regulatory-compliance-controls list \
  --standard-name "PCI-DSS-4" \
  --query "[?state=='Failed'].{Control:name, Failed:failedAssessments, Passed:passedAssessments}" \
  -o csv > pci-dss-failed-controls.csv

# Export all unhealthy (non-compliant) recommendations with severity and resource.
# This provides the full remediation backlog for the security team.
az security assessment list \
  --query "[?properties.status.code=='Unhealthy'].{Name:properties.displayName, Severity:properties.metadata.severity, Resource:properties.resourceDetails.id}" \
  -o csv > unhealthy-recommendations.csv

Auditor Report Checklist

  • Executive Summary: Overall compliance percentage for each framework with trend data
  • Control Status: Detailed breakdown of passed, failed, and manual controls per standard
  • Remediation Evidence: Timeline showing when findings were discovered and when they were resolved
  • Governance Proof: Screenshot or export of governance rules showing assigned owners and deadlines
  • Automated Controls: List of DeployIfNotExists policies with remediation task results
  • Exception Documentation: Formal risk acceptance for any controls marked as exempt with business justification
Tip: Schedule monthly compliance exports using Azure Automation or Logic Apps. This creates an audit trail and demonstrates continuous compliance monitoring to auditors.

Summary

What You Accomplished

  • Understood the difference between CSPM (posture assessment) and CWP (runtime protection) in Defender for Cloud
  • Enabled the Defender CSPM plan on your subscription using the portal, Azure CLI, and PowerShell
  • Reviewed the default Microsoft Cloud Security Benchmark and added PCI DSS, SOC 2, and HIPAA standards
  • Created a custom security initiative using Azure Policy with targeted policy definitions
  • Configured governance rules with tiered remediation deadlines (14, 30, and 90 days) based on severity
  • Mapped security controls to three regulatory frameworks and navigated the compliance dashboard
  • Built KQL queries for posture trend analysis, severity distribution, and resource group compliance
  • Configured attack path analysis to identify exploitable chains of misconfigurations
  • Created an Azure Monitor Workbook with posture summary, severity distribution, and trend visualization
  • Set up continuous export to stream recommendations and compliance data to Log Analytics
  • Automated remediation with a DeployIfNotExists policy for HTTPS enforcement on storage accounts
  • Generated compliance reports for auditors with executive summaries and control-level detail

Cost Considerations

  • Defender CSPM is billed per resource per hour; review current pricing on the Azure pricing page
  • Continuous export to Log Analytics incurs data ingestion costs based on the volume of data streamed
  • Azure Policy evaluation is free; however, DeployIfNotExists deployments may create billable resources
  • If you are using this in a lab environment, disable the Defender CSPM plan after completing the lab

Cleanup (Lab Environment Only)

  • Disable Defender CSPM: navigate to Environment settings, toggle the CSPM plan to Off
  • Remove custom policy assignments: az policy assignment delete --name "contoso-baseline-assignment"
  • Remove the custom initiative: az policy set-definition delete --name "contoso-security-baseline"
  • Delete continuous export configurations and remediation tasks created during the lab

Next Steps

  • Next Lab: Configure Defender for Containers
  • Integrate Defender for Cloud alerts with Microsoft Sentinel for unified SIEM/SOAR workflows
  • Explore data-aware security posture to discover and protect sensitive data in storage and databases
  • Implement DevOps security posture to scan infrastructure-as-code templates before deployment
  • Build automated compliance reporting pipelines using Azure Logic Apps and the Defender for Cloud API

๐Ÿ“š Documentation Resources

ResourceDescription
Cloud Security Posture Management overviewUnderstand CSPM capabilities and posture assessment fundamentals
Enable enhanced security features in Defender for CloudActivate paid Defender plans for advanced security capabilities
Identify and remediate attack pathsDiscover exploitable resource chains across your cloud environment
Configure governance rules for recommendationsAssign owners and remediation deadlines to security recommendations
Create custom security initiatives and policiesBuild tailored policy sets for organization-specific requirements
Regulatory compliance dashboardTrack compliance against PCI DSS, SOC 2, and HIPAA standards
Continuous export of Defender for Cloud dataStream recommendations and alerts to Log Analytics or Event Hub
Azure Policy DeployIfNotExists effectAuto-remediate misconfigurations using policy-driven deployments
Secure Score and security controlsMeasure and improve your cloud security posture over time
Microsoft Defender for Cloud pricingReview CSPM plan billing and cost optimization options
← All Labs Next Lab →