Blue Clouds
Blue Clouds

Reputation: 8161

Azure policy not creating roles for managed identity when deployed through devOps

I created an azure policy via devops . I had a role enabled as given below(storage contributor). The identity was created for the policy but there was no role assigned to it. So I had to manually create it to run the remediation task. Shouldn't the policy create the role itself? or the deployment?

 "roleDefinitionIds": [
                    "/providers/Microsoft.Authorization/roleDefinitions/17d1049b-9a84-46fb-8f53-869881c3d3ab"
                ],

We deploy it as an arm template using New-AzDeployment

This is the full template

{
  "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "policyDefinitionName": {
      "type": "string"
    }
  },
  "resources": [{
    "type": "Microsoft.Authorization/policyDefinitions",
    "name": "[parameters('policyDefinitionName')]",
    "apiVersion": "2019-09-01",
    "properties": {
        "displayName": "Deploy Soft-Delete for Blobs",
        "mode": "All",
        "description": "This policy enables soft-delete for blobs.",
        "parameters": {
            "retentionInDays": {
                "type": "Integer",
                "metadata": {
                    "displayName": "Retention in days",
                    "description": "This defines how long the deleted object should be retained for. Allowed values are 1 to 365."
                }
            }
        },
        "policyRule": {
            "if": {
                "allOf": [
                    {
                        "field": "type",
                        "equals": "Microsoft.Storage/storageAccounts"
                    },
                    {
                        "field": "kind",
                        "in": [
                            "Storage",
                            "StorageV2",
                            "BlobStorage",
                            "BlockBlobStorage"
                        ]
                    },
                    {
                        "field": "Microsoft.Storage/storageAccounts/isHnsEnabled",
                        "equals": false
                    },
                    
                ]
            },
            "then": {
                "effect": "DeployIfNotExists",
                "details": {
                    "type": "Microsoft.Storage/storageAccounts/blobServices",
                    "existenceCondition": {
                        "field": "Microsoft.Storage/storageAccounts/blobServices/default.deleteRetentionPolicy.enabled",
                        "equals": true
                    },
                    "roleDefinitionIds": [
                        "/providers/Microsoft.Authorization/roleDefinitions/17d1049b-9a84-46fb-8f53-869881c3d3ab"
                    ],
                    "deployment": {
                        "properties": {
                            "mode": "incremental",
                            "template": {
                                "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
                                "contentVersion": "1.0.0.0",
                                "parameters": {
                                    "storageAccountName": {
                                        "type": "string"
                                    },
                                    "retentionInDays": {
                                        "type": "int"
                                    }
                                },
                                "variables": {},
                                "resources": [
                                    {
                                        "name": "[[concat(parameters('storageAccountName'), '/default')]",
                                        "type": "Microsoft.Storage/storageAccounts/blobServices",
                                        "apiVersion": "2019-06-01",
                                        "properties": {
                                            "deleteRetentionPolicy": {
                                                "enabled": true,
                                                "days": "[[parameters('retentionInDays')]"
                                            }
                                        }
                                    }
                                ],
                                "outputs": {}
                            },
                            "parameters": {
                                "storageAccountName": {
                                    "value": "[[field('name')]"
                                },
                                "retentionInDays": {
                                    "value": "[[parameters('retentionInDays')]"
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    }]
}

Upvotes: 2

Views: 2848

Answers (1)

Rob S.
Rob S.

Reputation: 1156

  1. POLICY DEFINITION DEPLOYMENT
  2. (Optional) INITIATIVE DEFINTION DEPLOYMENT
  3. POLICY ASSIGNMENT DEPLOYMENT <- This is where you add your role assignment.

The role assignment must be made for the managed identity created by the policy assignment. If you create the policy assignment from the portal, I believe this is done automatically for you. An ARM template in DevOps will require a manual definition.

The policy assignment therefore must also be deployed with a role assignment.

I would recommend using a separate ARM template for assignments due to issues using "dependsOn" between definitions, initiatives, and assignments. Therefore your policy assignment template with the role assignment would stand alone and look something like the example template below.

I know it's not related to your question, but it's annoying enough to mention. In my experience, I've had to delay 2 minutes between definition deployments and subsequent initiative deployments and then another 2 minutes before assignment deployments in order to avoid 404 errors on dependencies.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {},
  "variables": {
      "scope": "[concat('/subscriptions/', subscription().subscriptionId, '/')]"
  },
  "resources": [
      {
          "type": "Microsoft.Authorization/policyAssignments",
          "apiVersion": "2019-09-01",
          "name": "my-policy-assignment",
          "location": "westus2",
          "identity": {
              "type": "SystemAssigned"
          },
          "properties": {
              "displayName": "My Policy Assignment",
              "policyDefinitionId": "[concat(variables('scope'), 'providers/Microsoft.Authorization/policySetDefinitions/my-policy-initiative')]",
              "scope": "[variables('scope')]",
              "notScopes": [],
              "parameters": {},
              "description": "This is an example assignment for a Stack Overflow post.",
              "metadata": {
                  "category": "My Category"
              }
          }
      },
      {
          "type": "Microsoft.Authorization/roleAssignments",
          "apiVersion": "2019-04-01-preview",
          "name": "b74efc56-19fa-44a3-9665-49b08f7c384d",
          "dependsOn": [
              "my-policy-assignment"
          ],
          "properties": {
              "roleDefinitionId": "[concat(subscription().id, '/providers/Microsoft.Authorization/roleDefinitions/', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]",
              "principalType": "ServicePrincipal",
              "delegatedManagedIdentityResourceId": "[concat(subscription().id, '/providers/Microsoft.Authorization/policyAssignments/', 'my-policy-assignment')]",
              "principalId": "[toLower(reference(concat('/providers/Microsoft.Authorization/policyAssignments/', 'my-policy-assignment'), '2018-05-01', 'Full' ).identity.principalId)]"
          }
      }
  ]
}

Upvotes: 2

Related Questions