Azure policy fails to deploy a policy assignment with deployIfNotExists - azure

I have a resource whitelist policy defined as follows:
{
"properties": {
"displayName": "Deny resource creation if not in whitelist",
"policyType": "Custom",
"mode": "Indexed",
"description": "This policy denies the creation resources which are not allowed in the whitelist.",
"policyRule": {
"if": {
"not": {
"field": "type",
"in": [
"Microsoft.KeyVault/vaults",
"Microsoft.Storage/storageAccounts"
]
}
},
"then": {
"effect": "Deny"
}
}
},
"id": "<POLICYDEFINITIONID>",
"type": "Microsoft.Authorization/policyDefinitions",
"name": "Deny_resource_creation_if_not_in_whitelist",
}
This policy works as expected when assigned to a resource group.
I also have a second policy assigned at the subscription level to deploy the first policy on resource groups with names starting with "rg-*":
{
"properties": {
"displayName": "Deploy resource whitelist policy",
"policyType": "Custom",
"mode": "All",
"description": "This policy assigns the resource whitelist policy to resource groups starting with rg-*.",
"policyRule": {
"if": {
"allOf": [
{
"equals": "Microsoft.Resources/subscriptions/resourceGroups",
"field": "type"
},
{
"field": "name",
"like": "rg-*"
}
]
},
"then": {
"details": {
"deployment": {
"properties": {
"mode": "incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [
{
"apiVersion": "2022-06-01",
"name": "[guid('<POLICYDEFINITIONID>', resourceGroup().name)]",
"properties": {
"displayName": "Deny resource creation if not in whitelist",
"enforcementMode": "Default",
"policyDefinitionId": "<POLICYDEFINITIONID>"
},
"type": "Microsoft.Authorization/policyAssignments"
}
]
}
}
},
"evaluationDelay": "AfterProvisioning",
"roleDefinitionIds": [
"/providers/Microsoft.Authorization/roleDefinitions/8e3af657-a8ff-443c-a75c-2fe8c4bcb635"
],
"type": "Microsoft.Authorization/policyAssignments"
},
"effect": "DeployIfNotExists"
}
}
},
"id": "",
"type": "Microsoft.Authorization/policyDefinitions",
"name": "Deploy_resource_whitelist_policy",
}
The second policy is evaluated, I can see a successful deployIfNotExists event but in fact the assignment is not created.
A few additional facts:
I successfully deployed the policy assignment ARM template from the Azure portal
When replacing the policy assignment ARM template with a simple storage account ARM template it works, a storage account is created in the resource group.
Any help would be much appreciated.

Your policy assignment in the example seems to be missing a scope property to assign it to the given resourcegroup. Try adding a scope property to the policy assignment.
"template": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [
{
"apiVersion": "2022-06-01",
"name": "[guid('<POLICYDEFINITIONID>', resourceGroup().name)]",
"properties": {
"displayName": "Deny resource creation if not in whitelist",
"enforcementMode": "Default",
"policyDefinitionId": "<POLICYDEFINITIONID>"
"scope": "[subscriptionResourceId('Microsoft.Resources/resourceGroups', resourceGroup().name)]"
},
"type": "Microsoft.Authorization/policyAssignments"
}```

I finally solved this using only the first policy and a value expression condition:
{
"properties": {
"displayName": "Deny resource creation if not in whitelist",
"policyType": "Custom",
"mode": "Indexed",
"description": "This policy denies the creation resources which are not allowed in the whitelist.",
"policyRule": {
"if": {
"allOf": [
{
"field": "type",
"notIn": [
"Microsoft.KeyVault/vaults",
"Microsoft.Storage/storageAccounts"
]
},
{
"value": "[resourceGroup().name]",
"like": "rg-*"
}
]
},
"then": {
"effect": "Deny"
}
}
},
"id": "<POLICYDEFINITIONID>",
"type": "Microsoft.Authorization/policyDefinitions",
"name": "Deny_resource_creation_if_not_in_whitelist",
}

Related

Azure policy to create locks on all vm's in a subscription

I am using this code below to attempt to lock just the VM's in a subscription, but the effect is to place a lock on the Resource Groups. How can I make this apply only to vm's only and not the RG?
{
"properties": {
"displayName": "All Azure Vm's should be Delete Locked",
"mode": "Indexed",
"description": "This policy will add an CanNotDelete Resource Lock.",
"metadata": {
"version": "1.1.0",
"category": "Compute"
},
"parameters": {
"effect" : {
"type" : "String",
"metadata" : {
"displayName" : "Effect",
"description" : "Enable a Delete Lock"
},
"allowedValues" : [
"CanNotDelete",
"ReadOnly",
"NotSpecified"
],
"defaultValue": "CanNotDelete"
}
},
"policyRule": {
"if": {
"allOf": [
{
"field": "type",
"equals": "Microsoft.Compute/virtualMachines"
}
]
},
"then": {
"effect": "auditIfNotExists",
"details": {
"type": "Microsoft.Authorization/locks",
"existenceCondition": {
"field": "Microsoft.Authorization/locks/level",
"equals": "CanNotDelete"
}
}
}
}
}
}
Created a policy to place locks on Virtual machines in Azure. Locks are placed on the Resource Group, which does lock the vm, but I only want the lock on the vm and not the resource group.
You are missing the deployment part of deployment template.
https://learn.microsoft.com/en-us/azure/governance/policy/samples/pattern-deploy-resources#deployment-template
You can only assign the resource lock on a single resource, if you do not want to assign it on the resource group:
https://learn.microsoft.com/en-us/azure/azure-resource-manager/templates/scope-extension-resources?tabs=azure-cli#apply-to-resource
For a single resource resource lock, then you need to use and define a scope:
https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/lock-resources?tabs=json#template
Under the "resources": [ you can do multiple deployments, see code #2:
#1
{
"properties": {
"displayName": "All Azure Vm's should be Delete Locked",
"description": "This policy will add an CanNotDelete Resource Lock.",
"mode": "all",
"metadata": {
"version": "1.1.0",
"category": "Compute"
},
"parameters": {
"effect": {
"type": "String",
"metadata": {
"displayName": "Effect",
"description": "Enable a Delete Lock"
},
"allowedValues": [
"CanNotDelete",
"ReadOnly",
"NotSpecified"
],
"defaultValue": "CanNotDelete"
}
},
"policyRule": {
"if": {
"field": "type",
"equals": "Microsoft.Compute/virtualMachines"
},
"then": {
"effect": "DeployIfNotExists",
"details": {
"type": "Microsoft.Authorization/locks",
"existenceCondition": {
"field": "Microsoft.Authorization/locks/level",
"equals": "[parameters('effect')]"
},
"roleDefinitionIds": [
"/providers/Microsoft.Authorization/roleDefinitions/8e3af657-a8ff-443c-a75c-2fe8c4bcb635"
],
"deployment": {
"properties": {
"mode": "incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json",
"contentVersion": "1.0.0.0",
"parameters": {},
"variables": {
"vmName": "vm-niclas01"
},
"resources": [
{
"type": "Microsoft.Authorization/locks",
"apiVersion": "2020-05-01",
"name": "DenyDelete",
"scope": "[concat('Microsoft.Compute/virtualMachines/', variables('vmName'))]",
"properties": {
"level": "CanNotDelete",
"notes": "Prevents deletion of resource."
}
}
]
}
}
}
}
}
}
}
}
#2 - Deploy lock on multiple VMs, not on RG:
{
"properties": {
"displayName": "Test 2 - All Azure Vm's should be Delete Locked",
"policyType": "Custom",
"mode": "All",
"metadata": {
"version": "1.1.0"
},
"parameters": {
"effect": {
"type": "String",
"metadata": {
"displayName": "Effect",
"description": "Enable a Delete Lock"
},
"allowedValues": [
"CanNotDelete",
"ReadOnly",
"NotSpecified"
],
"defaultValue": "CanNotDelete"
},
"vmName": {
"type": "Array",
"metadata": {
"displayName": "VM Names",
"description": "The list of VM names that should have resource locks"
},
"allowedValues": [
"vm-niclas01",
"vm-niclas02",
"vm-linuxniclas"
]
}
},
"policyRule": {
"if": {
"allOf": [
{
"field": "name",
"in": "[parameters('vmName')]"
},
{
"field": "type",
"equals": "Microsoft.Compute/virtualMachines"
}
]
},
"then": {
"effect": "DeployIfNotExists",
"details": {
"type": "Microsoft.Authorization/locks",
"existenceCondition": {
"field": "Microsoft.Authorization/locks/level",
"equals": "[parameters('effect')]"
},
"roleDefinitionIds": [
"/providers/Microsoft.Authorization/roleDefinitions/8e3af657-a8ff-443c-a75c-2fe8c4bcb635"
],
"deployment": {
"properties": {
"mode": "incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json",
"contentVersion": "1.0.0.0",
"parameters": {
"vmName": {
"type": "Array"
}
},
"variables": {
"vmName1": "[concat('/', parameters('vmName')[0])]",
"vmName2": "[concat('/', parameters('vmName')[1])]"
},
"resources": [
{
"type": "Microsoft.Authorization/locks",
"apiVersion": "2020-05-01",
"name": "DenyDelete",
"scope": "[concat('Microsoft.Compute/virtualMachines', variables('vmName1'))]",
"properties": {
"level": "CanNotDelete",
"notes": "Prevents deletion of resource."
}
},
{
"type": "Microsoft.Authorization/locks",
"apiVersion": "2020-05-01",
"name": "DenyDelete",
"scope": "[concat('Microsoft.Compute/virtualMachines/', variables('vmName2'))]",
"properties": {
"level": "CanNotDelete",
"notes": "Prevents deletion of resource."
}
}
],
"outputs": {}
},
"parameters": {
"vmName": {
"value": "[parameters('vmName')]"
}
}
}
}
}
}
}
}
}
3 VMs in the same RG:
Policy assignment with parameter:
Resource Lock deployed:
Resource Lock not deployed, because it is not part of policy parameter:

Create resource group with azure policy in each subscription

I'm trying to create an Azure policy for creating a RG for every subscription under my tenant.
I created this custom policy like I saw in some example but nothing is being created.
The custom policy:
{
"properties": {
"displayName": "Create resource group if not exists",
"description": "This policy will create resource group if not exists",
"policyType": "Custom",
"mode": "All",
"metadata": {
"version": "1.0.0",
"category": "Resource Management"
},
"parameters": {},
"policyRule": {
"if": {
"allOf": [
{
"field": "type",
"equals": "Microsoft.Resources/subscriptions"
}
]
},
"then": {
"effect": "deployIfNotExists",
"details": {
"type": "Microsoft.Resources/deployments",
"name": "createResourceGroup",
"roleDefinitionIds": [
"/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c"
],
"existenceCondition": {
"field": "name",
"equals": "TestRG"
},
"deployment": {
"properties": {
"mode": "incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "",
"parameters": {},
"variables": {},
"resources": [
{
"type": "Microsoft.Resources/resourceGroups",
"apiVersion": "2018-05-01",
"name": "TestRG",
"location": "eastus",
"tags": {
"Test": "Infra"
},
"properties": {}
}
]
},
"parameters": {}
}
}
}
}
}
}
}
If you have any ideas I would really appreciate that.
Thanks.
The alias "Microsoft.Resources/subscriptions" which you are referring to does not exist within the available aliases, hence the custom policy isn't working as expected. You can verify the list of available aliases using the PowerShell command "Get-AzPolicyAlias".
To raise a new policy alias request, you need to create ticket with Microsoft Support team.

Azure ARM policy Template Deny specific Resources

I am trying to understand how Management group policies works but deploying some policies.
I have this ARM template, which its purpose it to block specific resources from being created. Which, in my case works, but I would like to deny the creation of storage account only if specific sku.name is selected
this is the azure policy.
{
"properties": {
"displayName": "Not allowed resource types",
"policyType": "BuiltIn",
"mode": "All",
"description": "This policy enables you to specify the resource types that your organization cannot deploy.",
"parameters": {
"listOfResourceTypesNotAllowed": {
"type": "Array",
"metadata": {
"description": "The list of resource types that cannot be deployed.",
"displayName": "Not allowed resource types",
"strongType": "resourceTypes"
}
}
},
"policyRule": {
"if": {
"field": "type",
"in": "[parameters('listOfResourceTypesNotAllowed')]"
},
"then": {
"effect": "Deny"
}
}
},
"id": "/providers/Microsoft.Authorization/policyDefinitions/6c112d4e-5bc7-47ae-a041-ea2d9dccd749",
"type": "Microsoft.Authorization/policyDefinitions",
"name": "6c112d4e-5bc7-47ae-a041-ea2d9dccd749"
}
and this my parameters:
{
"listOfResourceTypesNotAllowed": {
"type": "Array",
"metadata": {
"description": "The list of resource types that cannot be deployed.",
"displayName": "Not allowed resource types",
"strongType": "resourceTypes"
},
"allowedValues": [
"Microsoft.DocumentDB/databaseAccounts",
"Microsoft.Storage/storageAccounts"
]
}
}
and my rules:
{
"if": {
"field": "type",
"in": "[parameters('listOfResourceTypesNotAllowed')]"
},
"then": {
"effect": "Deny"
}
}
Can anyone help me to understand how can this be achieved please?
Thank you so much for anyone who can spend some time to help me to understand this type of deployment
You can use the below policy defination for allowing only allowed sku types of storage accounts to be deployed in your subscription:
{
"properties": {
"displayName": "Storage accounts should be limited by allowed SKUs",
"policyType": "BuiltIn",
"mode": "Indexed",
"description": "Restrict the set of storage account SKUs that your organization can deploy.",
"metadata": {
"version": "1.1.0",
"category": "Storage"
},
"parameters": {
"effect": {
"type": "String",
"metadata": {
"displayName": "Effect",
"description": "Enable or disable the execution of the audit policy"
},
"allowedValues": [
"Audit",
"Deny",
"Disabled"
],
"defaultValue": "Deny"
},
"listOfAllowedSKUs": {
"type": "Array",
"metadata": {
"description": "The list of SKUs that can be specified for storage accounts.",
"displayName": "Allowed SKUs",
"strongType": "StorageSKUs"
}
}
},
"policyRule": {
"if": {
"allOf": [
{
"field": "type",
"equals": "Microsoft.Storage/storageAccounts"
},
{
"not": {
"field": "Microsoft.Storage/storageAccounts/sku.name",
"in": "[parameters('listOfAllowedSKUs')]"
}
}
]
},
"then": {
"effect": "[parameters('effect')]"
}
}
},
"id": "/providers/Microsoft.Authorization/policyDefinitions/7433c107-6db4-4ad1-b57a-a76dce0154a1",
"type": "Microsoft.Authorization/policyDefinitions",
"name": "7433c107-6db4-4ad1-b57a-a76dce0154a1"
}
Reference:
List of built-in policy definitions - Azure Policy | Microsoft Docs
Storage accounts should be limited by allowed SKUs- policy

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')]"
}
}
}
}
}
}
}
}
}]
}
POLICY DEFINITION DEPLOYMENT
(Optional) INITIATIVE DEFINTION DEPLOYMENT
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)]"
}
}
]
}

How to add the Azure Active Directory Administrator on a SQL Server to an Azure group once the SQL server deploys

I am trying to create an automated process that adds the Azure Active Directory on a SQL Server to an Azure group once the SQL server deploys. The group I want to add too is a security group. I am thinking about using Azure policy to implement this. What would the policy rule look like? If there is a better Azure service/feature to implement my task what is it?
Here is sample policy definition that has worked for me which evaluates and provides the complaint and non-complaint resources on the existing resources. Also kindly note, during an evaluation cycle, policy definitions with a "DeployIfNotExists" effect that match resources are marked as non-compliant, but no action is taken on that resource. Existing non-compliant resources can be remediated with a remediation task.
{
"mode": "All",
"policyRule": {
"if": {
"allOf": [
{
"field": "type",
"equals": "Microsoft.Sql/servers"
}
]
},
"then": {
"effect": "deployIfNotExists",
"details": {
"type": "Microsoft.Sql/servers/administrators",
"existenceCondition": {
"allOf": [
{
"field": "Microsoft.Sql/servers/administrators/administratorType",
"equals": "ActiveDirectory"
},
{
"field": "Microsoft.Sql/servers/administrators/login",
"equals": "xxxx#xxxxxx.com"
},
{
"field": "Microsoft.Sql/servers/administrators/sid",
"equals": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx"
},
{
"field": "Microsoft.Sql/servers/administrators/tenantId",
"equals": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx"
}
]
},
"deployment": {
"properties": {
"mode": "incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"type": "string"
},
"sqlServerName": {
"type": "string"
}
},
"variables": {},
"resources": [
{
"name": "[parameters('sqlServerName')]",
"type": "Microsoft.Sql/servers",
"apiVersion": "2019-06-01-preview",
"location": "[parameters('location')]",
"resources": [
{
"type": "Microsoft.Sql/servers/administrators",
"apiVersion": "2019-06-01-preview",
"name": "[concat(parameters('sqlServerName'), '/ActiveDirectory')]",
"dependsOn": [
"[resourceId('Microsoft.Sql/servers', parameters('sqlServerName'))]"
],
"properties": {
"administratorType": "ActiveDirectory",
"login": "xxxx#xxxxxx.com",
"sid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx",
"tenantId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx"
}
}
]
}
]
},
"parameters": {
"sqlServerName": {
"value": "[field('Name')]"
},
"location": {
"value": "[field('Location')]"
}
}
}
},
"roleDefinitionIds": [
"/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c",
"/providers/Microsoft.Authorization/roleDefinitions/8e3af657-a8ff-443c-a75c-2fe8c4bcb635"
]
}
}
},
"parameters": {}
}

Resources