Back to blog
AzureBest PracticesCloud SecurityCompute & ContainersKubernetes

Defender for Containers Not Enabled: Why It Matters and How to Fix It

Learn why Microsoft Defender for Containers must be enabled on every Azure subscription, the risks of leaving it off, and how to fix and enforce it.

TL;DR

This check flags Azure subscriptions where Microsoft Defender for Containers is turned off, leaving AKS clusters, container registries, and Kubernetes workloads without runtime threat detection or image scanning. Enable it per subscription with az security pricing create -n Containers --tier standard.

Containers move fast, and so do the people trying to break into them. A misconfigured AKS cluster, a vulnerable base image, or a leaked service account token can all turn into a foothold in minutes. Microsoft Defender for Containers is Azure's first line of defense against exactly these problems, and when it is disabled, you lose visibility into a large chunk of your attack surface.

This Lensix check, defender_containers, looks at your subscription's Defender plan configuration and raises a finding when the Containers plan is not enabled.


What this check detects

The check inspects the Microsoft Defender for Cloud pricing tier for the Containers plan on each Azure subscription. If the plan is set to the Free tier (the default), the check fails. A passing result requires the plan to be set to Standard.

Concretely, Lensix queries the security pricing API and reads the pricingTier value for the resource named Containers. The two possible states are:

  • Free — Defender for Containers is off. No agentless scanning, no runtime threat detection, no registry image scanning.
  • Standard — Defender for Containers is on, with full coverage for AKS, Azure Container Registry, and connected Kubernetes clusters.

Note: Defender for Containers is a single plan that covers several capabilities at once: vulnerability assessment for container images in ACR, runtime threat protection for Kubernetes nodes and clusters, and control plane hardening recommendations. Enabling it switches all of these on together.


Why it matters

Container environments fail quietly. A cluster keeps serving traffic whether or not anyone is watching it for malicious activity. Without Defender for Containers, you are flying blind across three distinct risk areas.

Vulnerable images ship to production

Defender scans images pushed to Azure Container Registry and surfaces known CVEs before they reach a running pod. Turn it off and a base image with a critical OpenSSL or glibc vulnerability can sit in your registry for months, getting pulled into every new deployment.

No runtime threat detection

Once an attacker is inside a pod, they tend to do recognizable things: spawn a reverse shell, probe the Kubernetes API server, mount the host filesystem, or query the instance metadata endpoint to steal credentials. Defender for Containers ships with detections for these behaviors. Without it, the first sign of compromise might be a ransom note or a surprise crypto-mining bill.

Warning: Cryptomining is one of the most common outcomes of an exposed Kubernetes dashboard or an over-permissive service account. The compute cost often runs into thousands of dollars before anyone notices, because the workload looks like legitimate usage.

Control plane misconfigurations go unflagged

Defender continuously checks for risky Kubernetes settings: privileged containers, containers running as root, host network access, missing resource limits, and exposed dashboards. These map directly to real exploitation paths. A privileged container that reaches the host kernel can break out of its isolation entirely.

The cost of a single incident response engagement almost always dwarfs the monthly cost of the Defender plan. Detection is the cheap part of security.


How to fix it

Enabling Defender for Containers is a per-subscription setting. Pick the method that matches how you manage Azure.

Option 1: Azure CLI

The fastest path is a single command. Make sure you are targeting the correct subscription first.

# Confirm which subscription you are operating on
az account show --query "{name:name, id:id}" -o table

# Enable Defender for Containers (Standard tier)
az security pricing create \
  --name Containers \
  --tier Standard

Verify the change took effect:

az security pricing show --name Containers --query "pricingTier" -o tsv
# Expected output: Standard

Warning: The Standard tier is billed per vCore for protected Kubernetes nodes and per image scan for ACR. Costs scale with cluster size, so enabling it on a large fleet has a real, recurring price. Review the current Defender for Cloud pricing for your region before rolling out across every subscription.

Option 2: Azure Portal

  1. Open Microsoft Defender for Cloud in the Azure Portal.
  2. Go to Environment settings and select the target subscription.
  3. In the Defender plans view, find the Containers row.
  4. Toggle the plan to On.
  5. Click Settings on the Containers plan to confirm the included components (agentless discovery, registry scanning, runtime protection) are enabled.
  6. Click Save.

Option 3: Terraform

If you manage Defender through infrastructure as code, declare the plan explicitly so it cannot drift back to Free.

resource "azurerm_security_center_subscription_pricing" "containers" {
  tier          = "Standard"
  resource_type = "Containers"
}

Apply it the usual way:

terraform plan -out=defender.plan
terraform apply defender.plan

Tip: If you run dozens of subscriptions, do not loop CLI commands by hand. Use Azure Policy with the DeployIfNotExists effect (covered below) so new subscriptions inherit the setting automatically the moment they are created.

Deploy the Defender sensor for full runtime coverage

Enabling the plan covers agentless capabilities. For full runtime threat detection on AKS, Defender also installs a sensor (the Defender DaemonSet) on your clusters. On AKS this is handled automatically when the plan is on, but for Arc-connected Kubernetes you may need to enable the extension explicitly. Confirm the sensor is healthy from the Defender for Cloud recommendations page after enabling the plan.


How to prevent it from happening again

Fixing one subscription is easy. Keeping every subscription compliant as your organization grows is the real challenge. The answer is policy-as-code.

Azure Policy with DeployIfNotExists

Microsoft ships a built-in policy that configures Defender for Containers automatically. Assign it at the management group level so it applies to every current and future subscription underneath.

# Find the built-in policy definition for enabling Defender for Containers
az policy definition list \
  --query "[?contains(displayName, 'Defender for Containers')].{name:name, displayName:displayName}" \
  -o table

# Assign it at a management group scope
az policy assignment create \
  --name "enable-defender-containers" \
  --display-name "Enable Defender for Containers" \
  --policy "" \
  --scope "/providers/Microsoft.Management/managementGroups/" \
  --location eastus \
  --mi-system-assigned \
  --role "Security Admin"

Note: DeployIfNotExists policies need a managed identity with permission to make the change. That is why the assignment above creates a system-assigned identity and grants it the Security Admin role. Without the role assignment, the remediation task fails silently.

Remediate existing non-compliant subscriptions

A new policy only enforces going forward. Trigger a remediation task to fix subscriptions that are already out of compliance.

az policy remediation create \
  --name "remediate-defender-containers" \
  --policy-assignment "enable-defender-containers" \
  --resource-discovery-mode ReEvaluateCompliance

Gate it in CI/CD

If your subscription baseline lives in Terraform, add a check to your pipeline that fails the build when the Containers plan is missing or set to Free. A simple post-apply assertion works:

tier=$(az security pricing show --name Containers --query "pricingTier" -o tsv)
if [ "$tier" != "Standard" ]; then
  echo "Defender for Containers is not enabled. Failing pipeline."
  exit 1
fi

Tip: Lensix runs the defender_containers check continuously, so you get an alert the moment a subscription drifts back to Free, even if someone disables the plan manually outside your pipeline. Pair the automated policy with continuous monitoring and you close the loop.


Best practices

Enabling the plan is the baseline. To get real value out of Defender for Containers, treat it as part of a broader container security posture.

  • Enable it everywhere you run containers, not just production. Attackers love dev and staging clusters precisely because they are less monitored and often share network paths to production.
  • Act on registry scan findings before deploy, not after. Wire Defender's image vulnerability results into your build pipeline so a critical CVE blocks the release rather than generating a ticket later.
  • Fix the high-signal control plane recommendations first. Privileged containers, host path mounts, and exposed Kubernetes dashboards are the findings most directly tied to breakout and lateral movement.
  • Route Defender alerts to where your team already works. Connect Defender for Cloud to your SIEM or send alerts to a monitored channel. An alert nobody reads is not detection.
  • Keep the Defender sensor healthy. Runtime detections depend on the agent running on your nodes. Add a recurring check that the sensor DaemonSet is present and reporting on every cluster.
  • Combine it with network policy and least-privilege RBAC. Defender tells you when something is wrong. Network segmentation and tight RBAC limit how far an attacker gets in the first place.

Danger: Do not disable Defender for Containers to cut costs without a replacement in place. Running a public-facing Kubernetes cluster with no runtime threat detection and no image scanning is one of the fastest ways to end up hosting a cryptominer or leaking customer data. If budget is the concern, scope the plan carefully rather than turning it off entirely.

Defender for Containers is one of those controls where the value is invisible right up until the moment it saves you. Turn it on, enforce it with policy, and let Lensix keep watch for drift.