Azure / deployment-stacks

Contains Deployment Stacks CLI scripts and releases
MIT License
87 stars 6 forks source link

DenyDelete locks cannot be set on Microsoft.Resources/tags #100

Closed lassehastrup closed 1 year ago

lassehastrup commented 1 year ago

Overview When deploying a deploymentStack using Powershell with a bicep file containing the Microsoft.Resources/tags resource and with the DenySettingMode set to 'DenyDelete' the deployment will fail:

Expected behavior I would expect the tags to receive the specified lock on the resource. The reason we use this is that we have 'default' tags specified on our LandingZones but we would still like our customers to add theier own resources.

Repro Environment Host OS: macOS 13.1 22C65 arm64 Powershell Version: 7.3.3

The bicep code where we get the existing tags:

@description('Get existing subscription tags and output them. Used to merge tags from blueprint with existing tags') resource existingTags 'Microsoft.Resources/tags@2021-04-01' existing = { name: 'default' }

Subscription Tags: "subscriptionTags": { "value": { "Environment": "Dev" } },

Union on tags:

resource res_tags 'Microsoft.Resources/tags@2021-04-01' = { name: 'default' properties: { tags: union(existingTags, subscriptionTags) } }

Powershell script to deploy:

$deploymentSplat = @{
        Name                           = "$LandingZone-DeploymentStack"
        TemplateFile                   = $BicepFilePath.FullName
        TemplateParameterFile          = $BicepParameterFilePath.FullName
        DenySettingsMode               = 'DenyDelete'
        DenySettingsExcludedActions    = @(
            'Microsoft.Network/virtualNetworks/subnets/*'
            'Microsoft.Insights/diagnosticSettings/*'
            'Microsoft.Advisor/configurations/*'
            'Microsoft.RecoveryServices/vaults/replicationFabrics/replicationProtectionContainers/replicationProtectedItems/*'
            'Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers/protectedItems/*'
            'Microsoft.Compute/virtualMachines/*'
        )

        DenySettingsApplyToChildScopes = $true
        Location                       = $Location
    }
    New-AzSubscriptionDeploymentStack @deploymentSplat -confirm:$false

Error received:

{
    "authorization": {
        "action": "Microsoft.Authorization/denyAssignments/write",
        "scope": "/subscriptions/fa3497ef-eb37-49ce-b7b6-f205a8a91c73/providers/Microsoft.Resources/tags/default/providers/Microsoft.Authorization/denyAssignments/df5617c9-fbe5-8c8c-1bd1-52a74830959c"
    },
    "correlationId": "6f5e780f-03a6-46d1-b801-52bcc6c28066",
    "description": "",
    "eventDataId": "3f3e04c0-54ef-4156-bbfd-0616d805a7e0",
    "eventName": {
        "value": "EndRequest",
        "localizedValue": "End request"
    },
    "category": {
        "value": "Administrative",
        "localizedValue": "Administrative"
    },
    "eventTimestamp": "2023-04-12T13:21:51.9686571Z",
    "id": "/subscriptions/xyz/providers/Microsoft.Resources/tags/default/providers/Microsoft.Authorization/denyAssignments/df5617c9-fbe5-8c8c-1bd1-52a74830959c/events/3f3e04c0-54ef-4156-bbfd-0616d805a7e0/ticks/638169025119686571",
    "level": "Error",
    "operationId": "1cfb472c-c299-4b40-9b86-dd79bffd96b0",
    "operationName": {
        "value": "Microsoft.Authorization/denyAssignments/write",
        "localizedValue": "Create deny assignment"
    },
    "resourceGroupName": "",
    "resourceProviderName": {
        "value": "Microsoft.Authorization",
        "localizedValue": "Microsoft.Authorization"
    },
    "resourceType": {
        "value": "Microsoft.Authorization/denyAssignments",
        "localizedValue": "Microsoft.Authorization/denyAssignments"
    },
    "resourceId": "/subscriptions/xyz/providers/Microsoft.Resources/tags/default/providers/Microsoft.Authorization/denyAssignments/df5617c9-fbe5-8c8c-1bd1-52a74830959c",
    "status": {
        "value": "Failed",
        "localizedValue": "Failed"
    },
    "subStatus": {
        "value": "NotFound",
        "localizedValue": "Not Found (HTTP Status Code: 404)"
    },
    "submissionTimestamp": "2023-04-12T13:22:59Z",
    "subscriptionId": "fa3497ef-eb37-49ce-b7b6-f205a8a91c73",
    "tenantId": "37732f27-626b-4ead-bb86-76f576b129b1",
    "properties": {
        "statusCode": "NotFound",
        "serviceRequestId": null,
        "statusMessage": "{\"error\":{\"code\":\"InvalidRequestUri\",\"message\":\"The request uri is invalid. Currently tags are not supported on proxy resource types.\"}}",
        "eventCategory": "Administrative",
        "entity": "/subscriptions/xyz/providers/Microsoft.Resources/tags/default/providers/Microsoft.Authorization/denyAssignments/df5617c9-fbe5-8c8c-1bd1-52a74830959c",
        "message": "Microsoft.Authorization/denyAssignments/write",
    },
    "relatedEvents": []
}
snarkywolverine commented 1 year ago

Thanks for the feedback - and for including the correlation ID in the issue.

Unfortunately, the scenario as you described (adding a deny assignment to tags) will not work currently, due to the way tags are designed. The good news is - work is already underway to make this possible in the future.

In the meantime, we will change Stacks so it doesn't try to create deny assignments for tags. That should allow the stack to complete end-to-end.

Let us know if you have any further questions on this. (I'll close this issue once that change is successfully deployed.)

snarkywolverine commented 1 year ago

The fix has been successfully deployed to all regions.