This check flags Azure Monitor log profiles that keep activity log data for less than 365 days. Short retention means you lose the audit trail you need to investigate incidents and meet compliance requirements. Set the retention to at least 365 days (or 0 for unlimited) on the log profile.
Logs are only useful if they exist when you go looking for them. The Azure Activity Log records control-plane events across your subscription: who created a resource, who changed a network security group, who rotated a key, who deleted a storage account. When something goes wrong, that history is the first thing a responder reaches for. If your log profile is configured to throw that data away after 30 or 90 days, the trail goes cold right when you need it most.
The monitor_logretention check looks at your Azure Monitor log profiles and fails any that have a retention period set below 365 days.
What this check detects
Azure lets you archive the subscription-level Activity Log to a storage account through a log profile. The log profile carries a retention policy that controls how long those archived events are kept before Azure deletes them. The policy has two relevant fields:
- enabled — whether the retention policy is actually applied
- days — the number of days to retain logs, where
0means keep them forever
The check fails when a log profile has a retention policy with days set to a value between 1 and 364. A retention of 365 days or more passes, and a value of 0 (unlimited) also passes.
Note: Azure Monitor log profiles are the classic mechanism for exporting the Activity Log. Microsoft now recommends diagnostic settings for new deployments, but log profiles are still widely present in existing subscriptions and remain a valid signal for retention posture. The same 365-day reasoning applies to diagnostic settings that route logs to a storage account.
Why it matters
The 365-day mark is not arbitrary. It maps to how real investigations and audits play out.
Incident detection lags behind the breach
Attackers are not always loud. The industry average dwell time, the gap between initial compromise and detection, has historically run into the weeks and months. If a credential was leaked in March and you discover the misuse in August, a 90-day retention window means the events that explain how the attacker got in and what they touched are already gone. You are left reconstructing an incident from gaps.
Compliance frameworks expect a year
Several common frameworks require a minimum of one year of log retention, often with a portion kept readily searchable:
- PCI DSS requires at least one year of audit log history, with the most recent three months immediately available.
- CIS Microsoft Azure Foundations Benchmark recommends a log profile retention of 365 days or greater.
- HIPAA and SOC 2 auditors routinely expect to see a year or more of access and change records.
A short retention period turns into an audit finding, and audit findings turn into remediation deadlines and customer questions.
Forensics needs the boring middle
When you investigate, you rarely need just the day of the incident. You need the baseline before it, the change that introduced the weakness, and the activity after. That story usually spans months. Cutting retention to 30 days removes the context that makes raw events meaningful.
Warning: Increasing retention has a cost. Activity Log archive data lives in a storage account, and you pay for the storage it consumes plus any transactions. For most subscriptions this is small, but high-volume environments should estimate the delta before flipping retention to unlimited.
How to fix it
You can correct the retention period through the Azure CLI, the portal, or infrastructure as code. Choose the one that fits how your environment is managed.
Option 1: Azure CLI
First, list your existing log profiles to find the one in question:
az monitor log-profiles list --query "[].{name:name, retentionDays:retentionPolicy.days, enabled:retentionPolicy.enabled}" -o table
Azure permits a single log profile per subscription, named whatever it was created as (often default). Update its retention policy to 365 days:
az monitor log-profiles update \
--name "default" \
--set retentionPolicy.days=365 retentionPolicy.enabled=true
If you want unlimited retention, set the days to 0:
az monitor log-profiles update \
--name "default" \
--set retentionPolicy.days=0 retentionPolicy.enabled=true
Danger: Avoid deleting and recreating the log profile to change retention. Deleting it stops the Activity Log archive immediately, and any events generated while no profile exists are not captured retroactively. Always update in place.
Option 2: Azure Portal
- Open Monitor from the portal menu.
- Select Activity Log, then Export Activity Logs (or navigate to the legacy log profile settings).
- Open the storage-account export configuration for your subscription.
- Set the retention to 365 days or higher, or enable the option to retain data indefinitely.
- Save the configuration.
Option 3: Terraform
If you manage the log profile with the azurerm provider, set the retention policy explicitly so drift is corrected on the next apply:
resource "azurerm_monitor_log_profile" "default" {
name = "default"
categories = [
"Action",
"Delete",
"Write",
]
locations = [
"eastus",
"global",
]
storage_account_id = azurerm_storage_account.logs.id
retention_policy {
enabled = true
days = 365
}
}
Tip: For long-term archival and cost control, route the Activity Log to a storage account with lifecycle management rules that move older blobs to the Cool or Archive tier. You keep a full year of audit history while paying hot-tier prices only for recent data.
How to prevent it from happening again
Fixing one profile is easy. Keeping every subscription compliant as your estate grows requires a guardrail that catches drift automatically.
Azure Policy with auto-remediation
Azure Policy can audit retention settings and, with a deployIfNotExists policy, push the correct configuration onto subscriptions that fall out of line. A simple audit rule looks like this:
{
"if": {
"allOf": [
{
"field": "type",
"equals": "Microsoft.Insights/logProfiles"
},
{
"field": "Microsoft.Insights/logProfiles/retentionPolicy.days",
"less": 365
},
{
"not": {
"field": "Microsoft.Insights/logProfiles/retentionPolicy.days",
"equals": 0
}
}
]
},
"then": {
"effect": "audit"
}
}
Assign this at the management group level so every subscription beneath it inherits the rule. Start in audit mode to measure the blast radius, then graduate to a remediating effect once you trust the results.
Catch it in CI/CD
If your log profiles and diagnostic settings live in Terraform or Bicep, scan the plan before it merges. A policy-as-code tool such as Checkov, tfsec, or Conftest can fail the pipeline when retention drops below your threshold:
checkov -d ./infra --framework terraform
Write a custom Conftest rule if your tool of choice does not ship one for log profile retention:
# conftest test on a terraform plan json
conftest test plan.json --policy ./policy/retention.rego
Tip: Lensix runs the monitor_logretention check continuously, so even resources created outside your pipeline (click-ops, automation scripts, third-party tools) get flagged. Pair the CI gate for what you control with continuous scanning for everything else.
Best practices
- Set 365 days as the floor, not the target. If storage cost is not a concern, unlimited retention (days = 0) removes the risk of a future audit finding entirely.
- Separate hot and cold logs. Keep the last 90 days immediately queryable in a Log Analytics workspace and archive the rest to cheaper storage. This satisfies both the "readily available" and "long-term retention" sides of most compliance requirements.
- Lock down the log storage account. Long retention is useless if an attacker can wipe the archive. Enable a delete lock, restrict access with RBAC, and turn on immutable blob storage or soft delete so logs cannot be tampered with.
- Migrate from log profiles to diagnostic settings. Log profiles are the older mechanism. Diagnostic settings give you per-category routing to Log Analytics, Event Hubs, and storage simultaneously, and they apply the same retention thinking.
- Centralize logging across subscriptions. In a multi-subscription estate, forward Activity Logs to a single, hardened logging subscription. One place to retain, one place to secure, one place to query.
- Review retention against the longest framework you answer to. If you carry both PCI DSS and a contractual three-year requirement, the contract wins. Set retention to the strictest obligation.
Log retention is one of those settings that costs almost nothing to get right and a great deal to get wrong. The day you need a year of Activity Log history is the day you discover whether you configured it. Set the retention now, gate it in your pipeline, and let continuous scanning keep it honest.

