Azure Advisor - Update a recommendation suppression with Bicep
- Intro
- There is no separate “update” operation
- Update by redeploying with a new parameter value
- Verify the update
- Adapting this into a pipeline
Intro
This article is part of a series: Navigate to series page
In this post I show how to update an existing Azure Advisor recommendation suppression - most commonly to extend (or shorten) its TTL - by redeploying the same Bicep template from Part 3.
There is no separate “update” operation
The Advisor suppressions REST API only exposes PUT (create), GET (list/read), and DELETE. There is no dedicated update verb. The way you “update” a suppression is by sending another PUT request to the same resourceUri/recommendationId/name combination with different property values - Advisor overwrites the existing suppression in place.
This maps cleanly onto Bicep/ARM’s normal deployment behavior: as long as the resource name (and its parent scope) stays the same, redeploying the template is treated as an update to the existing resource rather than a new create.
Update by redeploying with a new parameter value
Take the same template from Part 3:
targetScope = 'subscription'
@description('The Advisor recommendation resource name (identifier, not always a GUID) to suppress.')
param recommendationId string
@description('A friendly, deterministic name for this suppression - must match the existing suppression to update it.')
param suppressionName string = 'reserved-instance-cost-suppression'
@description('Duration the suppression is valid for, in TimeSpan format d.hh:mm:ss.')
param ttl string = '90.00:00:00'
resource recommendation 'Microsoft.Advisor/recommendations@2023-01-01' existing = {
name: recommendationId
}
resource suppression 'Microsoft.Advisor/recommendations/suppressions@2023-01-01' = {
parent: recommendation
name: suppressionName
properties: {
suppressionId: guid(subscription().id, recommendationId, suppressionName)
ttl: ttl
}
}
To extend the suppression from 90 days to 180 days, redeploy with a new ttl value and the same suppressionName:
New-AzSubscriptionDeployment `
-Location "westeurope" `
-TemplateFile "./suppress-reserved-instance.bicep" `
-recommendationId $recommendationId `
-suppressionName "reserved-instance-cost-suppression" `
-ttl "180.00:00:00"
az deployment sub create \
--location westeurope \
--template-file ./suppress-reserved-instance.bicep \
--parameters recommendationId=$recommendationId suppressionName=reserved-instance-cost-suppression ttl="180.00:00:00"
Because suppressionId is derived deterministically with guid(subscription().id, recommendationId, suppressionName), it stays identical between the create and the update deployment - only ttl changes. This matters: if suppressionId changed on every deployment (for example if it were randomly generated), Advisor would still update the same suppression resource (name-based), but you’d lose the ability to correlate the suppression’s identity across deployments in your own records.
Verify the update
Query the suppression again and confirm expirationTimestamp moved out:
$verifyUri = "https://management.azure.com/subscriptions/$subscriptionId/providers/Microsoft.Advisor/recommendations/$recommendationId/suppressions/reserved-instance-cost-suppression?api-version=$apiVersion"
Invoke-RestMethod -Uri $verifyUri -Method Get -Headers $headers | ConvertTo-Json -Depth 10
Adapting this into a pipeline
A useful pattern is a scheduled pipeline that re-evaluates whether a suppression is still justified before extending it:
- On a schedule (for example monthly), read your
suppressions.json(or similar source-controlled list) that records each suppression’s business justification and a “review by” date. - If the justification is still valid, redeploy the Bicep template with an extended
ttland require a pull request approval for the change - this keeps the extension auditable instead of silently renewing forever. - If the justification has expired or is no longer valid, remove the suppression entry from your source file and let Part 5 - Delete a suppression clean it up.
This avoids the common failure mode with snoozed recommendations: a suppression is created once “temporarily” and then never revisited because nothing forces a re-review.
In the next post I cover removing a suppression entirely, including why this needs a slightly different approach than a normal Bicep resource deletion:
Azure Advisor - Delete a suppression
Have feedback on this post?
Send me a message and I'll get back to you.