I want to create a policy where i audit/deny PostgreSQL Databases which do not have firewall rules configured. This is a policy which is workin but the compliance state shows every single rule in it...
{
"mode": "All",
"policyRule": {
"if": {
"allOf": [
{
"field": "type",
"equals": "Microsoft.DBforPostgreSQL/servers/firewallRules"
},
{
"field": "Microsoft.DBforPostgreSQL/servers/firewallRules/startIpAddress",
"exists": "false"
},
{
"field": "Microsoft.DBforPostgreSQL/servers/firewallRules/endIpAddress",
"exists": "false"
}
]
},
"then": {
"effect": "[parameters('effect')]"
}
},
"parameters": {
"effect": {
"type": "String",
"metadata": {
"displayName": "Effect",
"description": "The effect determines what happens when the policy rule is evaluated to match"
},
"allowedValues": [
"Audit",
"Deny",
"Disabled"
],
"defaultValue": "Audit"
}
}
}
As soon as I change Microsoft.DBforPostgreSQL/servers/firewallRules to Microsoft.DBforPostgreSQL/servers it cannot create the policy with error:
The policy definition '6bab4b2f-30b3-4f07-a92e-496b6309d14d' targets multiple resource types, but the policy rule is authored in a way that makes the policy not applicable to the target resource types 'Microsoft.DBforPostgreSQL/servers,Microsoft.DBforPostgreSQL/servers/firewallRules'. This is because the policy rule has a condition that can never be satisfied by the target resource types. If an alias is used, please make sure that the alias gets evaluated against only the resource type it belongs to by adding a type condition before it, or split the policy into multiple ones to avoid targeting multiple resource types.
Does anyone have an idea how to fix that?
Related
I am looking to configure policy to audit resource groups that contains resources, whether have the particular tag or not. If the resource group does not have any resources, then there is no need to audit. My requirement is only to perform audit for tags, if the resource group contains resources. Is it a possible scenario for creating policy?
Assuming it is fair to say that your requirement is to audit for resources and not the resource groups, you can achieve this by using the built-in policy definition "Require a tag on resources" and set it to "audit" instead of "deny".
EDIT:
Considering your clarification, you can perform the reverse check - meaning a check on resources, inspecting their resource groups:
"parameters": {
"tagName": {
"type": "String",
"metadata": {
"displayName": "Tag Name",
"description": "Name of the tag, such as 'environment'"
}
}
},
"policyRule": {
"if": {
"allOf": [
{
"field": "type",
"notEquals": "Microsoft.Resources/subscriptions/resourceGroups"
},
{
"not": {
"field": "[resourceGroup().tags[parameters('tagName')]]",
"exists": "false"
}
}
]
},
"then": {
"effect": "audit"
}
}
Here we are checking that we are not looking at a resource group directly. Then, we check if the parent resource group does not have the specified tag (notExists).
/MMT
Below is my policy definition and is correctly working (policy is responsible to assign tags from resource group to resources):
{
"properties": {
"displayName": "inheritTags",
"policyType": "Custom",
"mode": "Indexed",
"metadata": {
"createdBy": "3332dc03-2402-46e3-9098-c7350b0bc8dd",
"createdOn": "2019-11-25T14:49:57.8136557Z",
"updatedBy": "3332dc03-2402-46e3-9098-c7350b0bc8dd",
"updatedOn": "2019-11-26T19:43:48.752452Z"
},
"parameters": {},
"policyRule": {
"if": {
"allOf": [
{
"value": "[resourceGroup().tags]",
"exists": "true"
},
{
"value": "[resourceGroup().tags]",
"notEquals": ""
}
]
},
"then": {
"effect": "modify",
"details": {
"operations": [
{
"operation": "addOrReplace",
"field": "tags",
"value": "[resourceGroup().tags]"
}
],
"roleDefinitionIds": [
"/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c"
]
}
}
}
},
"id": "/subscriptions/78afced4-1c58-4e66-8242-c042890d34c3/providers/Microsoft.Authorization/policyDefinitions/9f2a0e94-5ada-47b0-8125-42464f93cf37",
"type": "Microsoft.Authorization/policyDefinitions",
"name": "9f2a0e94-5ada-47b0-8125-42464f93cf37"
}
Nevertheless in Overview tab on Policy page I have information that assigned policy definition is in Non-compliant state:
Reason for that? Different values due to comparing previous state to expected state and I know that source of "issues" are keywords like exists, notEquals and so on: https://learn.microsoft.com/en-us/azure/governance/policy/how-to/determine-non-compliance#compliance-reasons
How to ignore those compliance messages and get resource compliance, you know tags are correctly assigned so what is the problem? or maybe I have wrong understanding of azure policies?
The resources that are coming up as non-compliant is because they do not have the same tags as the RG. For some resources, modify won't because they don't support tags or don't support updating/adding tags. I can't tell what type of resource it is so I can't say forsure that is the issues. If this is the case that those resources don't support tags, then you can just excluded that resource from the assignment to see the compliance percentage not including those. (Edit the assignment and add an exclusion)
I'm currently trying to understand the Azure policies. I think I've got my head around the aliases, but I'm having trouble understanding where to find the correct values for ExistenceCondition equals field
How does it different from the PolicyRule we applied?
Should i keep ExistanceCondition almost same as PolicyRule?
Policy rule i applied :
"if":{
"allOf":[
{
"field":"type",
"equals":"Microsoft.Insights/metricalerts"
},
{
"field":"Microsoft.Insights/metricalerts/enabled",
"equals":"true"
},
{
"field":"Microsoft.Insights/metricalerts/actions[*]",
"less":"1"
}
]
}
ExistenceCondition is the opposite of policyRule in terms of control direction.
In policy rule you proceed only if the condition is true. in ExistenceCondition you proceed only if the condition is false. In the example below in policyRule you filter only the storageAccount then proceed. The deploy happens only if the condition is false (deleteRetentionPolicy.enabled ==false) so it proceeds and deploy. So once deploy is done, it will be deleteRetentionPolicy.enabled ==true
"policyRule": {
"if": {
"allOf": [
{
"field": "type",
"equals": "Microsoft.Storage/storageAccounts"
},
{
"field": "kind",
"in": [
"Storage",
"StorageV2",
"BlobStorage",
"BlockBlobStorage"
]
}
]
},
"then": {
"effect": "DeployIfNotExists",
"details": {
"type": "Microsoft.Storage/storageAccounts/blobServices",
"existenceCondition": {
"field": "Microsoft.Storage/storageAccounts/blobServices/default.deleteRetentionPolicy.enabled",
"equals": true
},
See this example:
https://learn.microsoft.com/en-us/azure/governance/policy/samples/pattern-effect-details#sample-2-explanation
"details": {
"type": "Microsoft.Compute/virtualMachines/extensions",
"existenceCondition": {
"allOf": [{
"field": "Microsoft.Compute/virtualMachines/extensions/publisher",
"equals": "[parameters('publisher')]"
},
{
"field": "Microsoft.Compute/virtualMachines/extensions/type",
"equals": "[parameters('type')]"
}
]
}
}
The existenceCondition uses policy language elements, such as logical
operators, to determine if a matching related resource exists. In this
example, the values checked against each alias are defined in
parameters.
ExistenceCondition apply only to policy with effect AuditIfNotExists and DeployIfNotExists.
In case of AuditIfNotExists
"If any matching related resource evaluates to true, the effect is
satisfied and doesn't trigger the audit."
In case of DeployIfNotExists
"If any matching related resource evaluates to true, the effect is
satisfied and doesn't trigger the deployment."
Existing resource which does not match ExistenceCondition will be marked as non-complaint. Resources filtered out by PolicyRule will not be marked as non-complaint.
I'm struggling to create a parameterized version of the Azure Policy example which copies Tags applied to a Resource Group to any resources within it. This is the example I'm using as inspiration: https://github.com/Azure/azure-policy/tree/master/samples/ResourceGroup/copy-resourcegroup-tag, which is:
{
"if": {
"field": "tags.example",
"exists": "false"
},
"then": {
"effect": "append",
"details": [
{
"field": "tags.example",
"value": "[resourceGroup().tags.example]"
}
]
}
}
We have a number of tags added to Resource Groups, and for billing purposes I need to ensure these are applied to all resources within. I am looking to create an Initiative which contains the same policy several times, each time using a different parameterized tag name. My parameterized version of the example policy looks like this:
"parameters": {
"tagName": {
"type": "String",
"metadata": {
"displayName": "Tag name",
"description": "The tag to copy to child resources"
}
}
},
"policyRule": {
"if": {
"field": "[concat('tags.', parameters('tagName'))]",
"exists": "false"
},
"then": {
"effect": "append",
"details": [
{
"field": "[concat('tags.', parameters('tagName'))]",
"value": "[concat('resourceGroup().tags.', parameters('tagName'))]"
}
]
}
}
When the policy applies I get a result of non-compliant. Viewing the compliance details shows:
Reason for non-compliance
Current value must exist.
Field
tags.ApplicationName
Current value
--
There is a tag called ApplicationName with a value on the Resource Group. The documentation says the reason for "Current value must exist" is the exists condition. This seems counter-intuitive to the way I am expecting this to work - I know it doesn't exist which is why I want to set the value.
Is there any way to debug these beyond assigning the policy and waiting several hours for a result?
Thanks for your help!
I've figured this out, my syntax was wrong, I need to refer to the Tags using keys rather than as attributes, i.e. tags['ApplicationName'] rather than tags.ApplicationName. The policyRule property needs to be:
"policyRule": {
"if": {
"field": "[concat('tags[', parameters('tagName'), ']')]",
"exists": "false"
},
"then": {
"effect": "append",
"details": [
{
"field": "[concat('tags[', parameters('tagName'), ']')]",
"value": "[resourceGroup().tags[parameters('tagName')]]"
}
]
}
}
I also misunderstood how this feature works, it seems that policies with an Append effect can only append at the point of resource creation, not retrospectively on an existing resource. The above policy adds the Tags for new resources but results in a "non-compliant" report for existing resource.
This behavior is as documented here:
"When a policy definition using the append effect is run as part of an evaluation cycle, it doesn't make changes to resources that already exist. Instead, it marks any resource that meets the if condition as non-compliant."
In the Azure Policy "allowed resource type" you can supply an array of resource types. When I want to allow SQL Elastic pool I need also to include all the subtypes of SQL Elastic pool.
I would like to use:
'Microsoft.Sql/servers/elasticpools/*'
'Microsoft.Sql/servers/elasticPools/advisors/*'
'Microsoft.Sql/servers/elasticpools/elasticpool/advisors/*'
'microsoft.web/serverfarms/*
'microsoft.web/sites/*
But this doesn't work.
We now use:
'Microsoft.Sql/servers/elasticpools'
'Microsoft.Sql/servers/elasticPools/advisors'
'Microsoft.Sql/servers/elasticpools/advisors/createindex'
'Microsoft.Sql/servers/elasticpools/advisors/dbparameterization'
'Microsoft.Sql/servers/elasticpools/advisors/defragmentindex'
'Microsoft.Sql/servers/elasticpools/advisors/dropindex'
'Microsoft.Sql/servers/elasticpools/advisors/forcelastgoodplan'
'Microsoft.Sql/servers/elasticpools/elasticpool/advisors/createindex'
'Microsoft.Sql/servers/elasticpools/elasticpool/advisors/dbparameterization'
'Microsoft.Sql/servers/elasticpools/elasticpool/advisors/defragmentindex'
'Microsoft.Sql/servers/elasticpools/elasticpool/advisors/dropindex'
'Microsoft.Sql/servers/elasticpools/elasticpool/advisors/forcelastgoodplan'
'Microsoft.Web/sites/config'
'Microsoft.Web/sites/...'
Policy we use is:
{
"if": {
"not": {
"field": "type",
"in": "[parameters('listOfResourceTypesAllowed')]"
}
},
"then": {
"effect": "[parameters('Effect')]"
}
}
Policy parameter:
{
"listOfResourceTypesAllowed": {
"type": "array",
"metadata": {
"displayName": "Allowed resource types",
"description": "The list of resource types that can be deployed.",
"strongType": "resourceTypes"
}
},
"Effect": {
"type": "string",
"metadata": {
"description": "The effect of the policy."
}
}
}
Question is it possible to use wildcards or something like that?