Azure waste

Multi-region Cosmos DB account outside production

A Cosmos DB account replicated across regions, or writing to several, while tagged non-production.
The agent reports this
Reversible
Why it happens

Azure Cosmos DB provisions the account's throughput separately in every region it is replicated to, so a second region doubles the throughput bill before a single extra request is served. Multi-region writes costs more again: the retail catalogue prices 100 RU/s at $0.008 an hour and 100 Multi-master RU/s at $0.016, exactly double, so enabling it doubles the rate in every region including the first. A development or test account rarely needs either, and Microsoft documents adding and removing regions on an existing account, so the remedy is a configuration change rather than a rebuild. This check reports the regions and the measured rates and deliberately does not compute a saving: provisioned throughput lives on databases and containers rather than on the account, so the agent can verify the multiplier but not the quantity, and a figure built from a rate and a guess would be worse than none.

Paste this into Resource Graph Explorer in the Azure portal.

resources
| where type =~ 'microsoft.documentdb/databaseaccounts'
// Scope below matches CloudFinOpsPro policy DEFAULTS: exclusions.protectTag, environment.tagKeys,
// environment.allowedTagValues, and allowUntagged false so an untagged resource counts as production.
// If your policy.yaml differs, edit the three lines below or this will disagree with your own agent.
| where tolower(tostring(coalesce(tags['cfop:protect'], ''))) !in ('true', 'yes', '1')
| extend cfopEnv = tolower(trim(' ', tostring(coalesce(tags['Environment'], tags['environment'], tags['env'], ''))))
| where cfopEnv in ('dev', 'development', 'test', 'qa', 'sandbox', 'nonprod', 'non-prod', 'staging')
// locations is readOnly and lists every region the account is replicated to. Either condition
// costs: an extra region provisions the throughput again, multi-region writes doubles the rate.
| extend regions = array_length(properties.locations)
| extend multiRegionWrites = tobool(properties.enableMultipleWriteLocations)
| where regions > 1 or multiRegionWrites == true
// Deliberately no dollar arithmetic, and not only because rates go stale: provisioned throughput
// lives on databases and containers, so the account cannot tell you how many RU/s are multiplied.
| project name, resourceGroup, location, regions, multiRegionWrites,
          capacityMode = iff(isnull(properties.capacity.totalThroughputLimit), 'unset', tostring(properties.capacity.totalThroughputLimit)),
          environment = cfopEnv

Azure Cosmos DB provisions an account's throughput separately in every region it is replicated to, so a second region doubles the throughput bill before a single extra request is served. Multi-region writes costs more again: verified against the retail API, East US prices 100 RU/s at $0.008 an hour and 100 Multi-master RU/s at $0.016, exactly double, so enabling it doubles the rate in every region including the first. Both meter names also appear priced at zero, which are free-tier rows, so the agent rejects a zero-priced match rather than reporting the rate as free. This query returns no dollar figure and neither does the check, for a reason beyond staleness: provisioned throughput lives on databases and containers rather than on the account, so the multiplier can be verified and the quantity cannot, and a figure built from a known rate and a guessed quantity would be worse than none. The account's totalThroughputLimit is projected for context, but it is documented as a ceiling on what may be provisioned rather than a reading of what is. Microsoft documents adding and removing regions on an existing account, so the remedy is a configuration change. Serverless accounts can have neither setting, so they never appear here. This is a structural test, so what it returns is what the check reports.

Applies to microsoft.documentdb/databaseaccounts
What the agent does about it

A Cosmos DB account replicated across regions, or writing to several, while tagged non-production.

It will not fix this one

It reports this and takes no action. A check only earns the right to change something once the action behind it can re-read live state before it fires and knows the way back.