Azure Policy for Naming - json

I'm doing something incorrectly here regarding an Azure Policy I'm creating. Trying to create a naming policy that blocks creation of a resource (in this case a resource group) that doesn't match.
{
"properties": {
"mode": "All",
"displayName": "Company Naming Convention - Resource Groups",
"description": "This policy governs the naming standard for resource groups and should be assigned at the resource group scope. The naming scheme is rg-region-workload name-environment-optional instance number'.",
"metadata": {
"category": "Governance"
},
"policyRule": {
"if": {
"allOf": [
{
"field": "type",
"equals": "Microsoft.Resources/resourceGroups"
},
{
"allOf": [
{
"field": "name",
"notLike": "rg-useast-*"
},
{
"field": "name",
"notLike": "rg-useast2-*"
},
{
"field": "name",
"notLike": "rg-uscentral-*"
},
{
"field": "name",
"notLike": "rg-uksouth-*"
}
]
},
{
"allOf": [
{
"field": "name",
"notLike": "*-production.###"
},
{
"field": "name",
"notLike": "*-development.###"
},
{
"field": "name",
"notLike": "*-qualityassurance.###"
},
{
"field": "name",
"notLike": "*-testing.###"
}
]
}
]
},
"then": {
"effect": "deny"
}
}
}
}
I'd ALSO like to create a policy to audit existing resources that don't match this name, but I can address that later. Anyone have a suggestion what I'm doing wrong or a better way to go about this?

Ok... so the original policy works great... if I actually looked at the right resource. Should be "Microsoft.Resources/subscriptions/resourceGroups" not "Microsoft.Resources/resourceGroups". Dang do I feel like an idiot...

You are using incorrect syntax in your Azure Policy Definition. The allOf syntax requires all conditions to be true and you can keep all the conditions in single allOf Operator.
Modified version of Policy for reference :
{
"properties": {
"mode": "All",
"displayName": "Company Naming Convention - Resource Groups",
"description": "This policy governs the naming standard for resource groups and should be assigned at the resource group scope. The naming scheme is rg-region-workload name-environment-optional instance number'.",
"metadata": {
"category": "Governance"
},
"policyRule": {
"if": {
"allOf": [
{
"field": "type",
"equals": "Microsoft.Resources/subscriptions/resourceGroups"
},
{
"field": "name",
"notLike": "rg-useast-*"
},
{
"field": "name",
"notLike": "rg-useast2-*"
},
{
"field": "name",
"notLike": "rg-uscentral-*"
},
{
"field": "name",
"notLike": "rg-uksouth-*"
},
{
"field": "name",
"notLike": "*-production.###"
},
{
"field": "name",
"notLike": "*-development.###"
},
{
"field": "name",
"notLike": "*-qualityassurance.###"
},
{
"field": "name",
"notLike": "*-testing.###"
}
]
},
"then": {
"effect": "deny"
}
}
}
}
Also note, it takes around 30 minutes for the assignment to be applied to the defined scope. For more information on evaluation cycle of Azure Policy, refer this document.
For on-demand evaluation , use az cli command : az policy state trigger-scan

Related

Azure Policy Not Denying Route Creation

I want to make an Azure policy that denies anyone trying to create a route to certain prefixes that don't use the next hop virtual appliance parameter and IP that I specify. I have this working with just a single prefix (0.0.0.0/0 internet route) but as soon as I try to define other routes (10.0.0.0/8) it doesn't work. Here is what I have so far:
{
"mode": "All",
"policyRule": {
"if": {
"anyOf": [
{
"allOf": [
{
"field": "type",
"equals": "Microsoft.Network/routeTables"
},
{
"count": {
"field": "Microsoft.Network/routeTables/routes[*]",
"where": {
"anyOf": [
{
"field": "Microsoft.Network/routeTables/routes[*].addressPrefix",
"equals": "0.0.0.0/0"
},
{
"anyOf": [
{
"field": "Microsoft.Network/routeTables/routes[*].nextHopType",
"notEquals": "VirtualAppliance"
},
{
"field": "Microsoft.Network/routeTables/routes[*].nextHopIpAddress",
"notEquals": "[parameters('routeTableSettings')[field('location')].virtualApplianceIpAddress]"
}
]
},
{
"field": "Microsoft.Network/routeTables/routes[*].addressPrefix",
"equals": "10.0.0.0/8"
},
{
"anyOf": [
{
"field": "Microsoft.Network/routeTables/routes[*].nextHopType",
"notEquals": "VirtualAppliance"
},
{
"field": "Microsoft.Network/routeTables/routes[*].nextHopIpAddress",
"notEquals": "[parameters('routeTableSettings')[field('location')].virtualApplianceIpAddress]"
}
]
}
]
}
},
"greater": 0
}
]
},
{
"anyOf": [
{
"field": "type",
"equals": "Microsoft.Network/routeTables/routes"
},
{
"field": "Microsoft.Network/routeTables/routes[*].addressPrefix",
"equals": "0.0.0.0/0"
},
{
"anyOf": [
{
"field": "Microsoft.Network/routeTables/routes/nextHopType",
"notEquals": "VirtualAppliance"
},
{
"field": "Microsoft.Network/routeTables/routes/nextHopIpAddress",
"notEquals": "[parameters('routeTableSettings')[field('location')].virtualApplianceIpAddress]"
}
]
},
{
"field": "type",
"equals": "Microsoft.Network/routeTables/routes"
},
{
"field": "Microsoft.Network/routeTables/routes[*].addressPrefix",
"equals": "10.0.0.0/8"
},
{
"anyOf": [
{
"field": "Microsoft.Network/routeTables/routes/nextHopType",
"notEquals": "VirtualAppliance"
},
{
"field": "Microsoft.Network/routeTables/routes/nextHopIpAddress",
"notEquals": "[parameters('routeTableSettings')[field('location')].virtualApplianceIpAddress]"
}
]
}
]
}
]
},
"then": {
"effect": "deny"
}
},
"parameters": {
"routeTableSettings": {
"type": "Object",
"metadata": {
"displayName": "Route Table Settings",
"description": "Location-specific settings for route tables."
}
}
}
}
Parameters
{
"eastus2": {
"virtualApplianceIpAddress": "10.1.1.1"
},
"disabled": {
"virtualApplianceIpAddress": ""
}
}
To achieve the above requirement we need to use IN clause in our azure policy to deny/not allow the resource type to create .
As suggested by #harshavmb in comment which is correct. Posting it as an answer to help other community members to find fix their issue for the same.
The MS DOC has an example how to use the in with policy rule:
{
"properties": {
"displayName": "Allowed locations",
"description": "This policy enables you to restrict the locations your organization can specify when deploying resources.",
"mode": "Indexed",
"metadata": {
"version": "1.0.0",
"category": "Locations"
},
"parameters": {
"allowedLocations": {
"type": "array",
"metadata": {
"description": "The list of locations that can be specified when deploying resources",
"strongType": "location",
"displayName": "Allowed locations"
},
"defaultValue": [ "westus2" ]
}
},
"policyRule": {
"if": {
"not": {
"field": "location",
"in": "[parameters('allowedLocations')]"
}
},
"then": {
"effect": "deny"
}
}
}
}
Also from Azure portal>Policy> Not allowed resource we can find the json with in clause .
As shown below:
For more information please refer the below links:-
MICROSOFT DOCUMENTATION:- Not_allowed_resource_types
BLOG:- AZURE POLICY TO DENY CREATION OF ALL RESOURCES

Audit for specific Azure DNS in a specific region (Azure Policy)

I'd like to have an Azure Policy that audits for specific Azure DNS's in the targeted Region. Both should be available in an array so the policy can be scoped multiple times.
So far I've got this, which does not work since it puts the state in compliance by having the right DNS set, but completely ignores the region specified in the array. My goal is to have the policy compliance check for both.
{
"mode": "All",
"policyRule": {
"if": {
"allOf": [
{
"field": "type",
"equals": "Microsoft.Network/virtualNetworks"
},
{
"anyOf": [
{
"value": "[if(empty(field('Microsoft.Network/virtualNetworks/dhcpOptions.dnsServers')), bool('false'), equals(length(intersection(parameters('dnsSettings'), field('Microsoft.Network/virtualNetworks/dhcpOptions.dnsServers'))), length(parameters('dnsSettings'))))]",
"equals": false
},
{
"value": "[if(empty(field('Microsoft.Network/virtualNetworks/dhcpOptions.dnsServers')), bool('false'), equals(length(field('Microsoft.Network/virtualNetworks/dhcpOptions.dnsServers')),length(parameters('dnsSettings'))))]",
"equals": false
}
]
},
{
"not": {
"allOf": [
{
"field": "location",
"in": "[parameters('location')]"
}
]
}
}
]
},
"then": {
"effect": "[parameters('effect')]"
}
},
"parameters": {
"dnsSettings": {
"type": "Array",
"metadata": {
"displayName": "dnsSettings",
"description": "Audit for specific DNS settings."
}
},
"location": {
"type": "Array",
"metadata": {
"displayName": "Location",
"description": "Choose specific location",
"strongType": "location"
}
},
"effect": {
"type": "String",
"metadata": {
"displayName": "Effects",
"description": "Enable or disable the execution of the Policy."
},
"allowedValues": [
"Audit",
"Disabled"
],
"defaultValue": "Audit"
}
}
}
We can use auditIfNotExists with few logic operations so that this will allow only after the success code, below sample is to understand about .
{
"if": {
"field": "type",
"equals": "Microsoft.Compute/virtualMachines"
},
"then": {
"effect": "auditIfNotExists",
"details": {
"type": "Microsoft.Compute/virtualMachines/extensions",
"existenceCondition": {
"allOf": [{
"field": "Microsoft.Compute/virtualMachines/extensions/publisher",
"equals": "Microsoft.Azure.Security"
},
{
"field": "Microsoft.Compute/virtualMachines/extensions/type",
"equals": "IaaSAntimalware"
}
]
}
}
}
}
Below is the way we can specify the dns, Sample for adding dns:
{
"mode": "All",
"name": "Deny changing VNet DNS settings from pre-defined value",
"description": "This Policy will prevent users from changing DNS settings on a VNet",
"policyRule": {
"if": {
"allOf": [
{
"field": "type",
"equals": "Microsoft.Network/virtualNetworks"
},
{
"anyOf": [
{
"value": "[if(empty(field('Microsoft.Network/virtualNetworks/dhcpOptions.dnsServers')), bool('false'), equals(length(intersection(parameters('dnsSettings'), field('Microsoft.Network/virtualNetworks/dhcpOptions.dnsServers'))), length(parameters('dnsSettings'))))]",
"equals": false
},
{
"value": "[if(empty(field('Microsoft.Network/virtualNetworks/dhcpOptions.dnsServers')), bool('false'), equals(length(field('Microsoft.Network/virtualNetworks/dhcpOptions.dnsServers')),length(parameters('dnsSettings'))))]",
"equals": false
}
]
}
]
},
"then": {
"effect": "auditIfNotExists"
}
},
"parameters": {
"dnsSettings": {
"type": "array",
"metadata": {
"displayname": "Enforced DNS Settings",
"description": "Users will be unable to change the DNS settings on a VNet from the values defined in this array."
}
}
}
}
Check AzurePolicy.json and AzurePolicy.rules.json to understand about allowing standard dns within application rules. Include location settings in it.

How to enforce Tag value pattern in Azure policy?

I'd like to enforce tag value pattern "RJGVM-###" for a Tag which will be required for resource groups.
I manage to make it required, but whenever I put in any value it still passes.
{
"mode": "All",
"policyRule": {
"if": {
"allOf": [
{
"field": "type",
"equals": "Microsoft.Resources/subscriptions/resourceGroups"
},
{
"not": {
"field": "[concat('tags[',parameters('tagName'), ']')]",
"exists": "true"
}
},
{
"value": "[resourceGroup().tags[parameters('tagName')]]",
"notMatch": "RJGVM-###"
}
]
},
"then": {
"effect": "deny"
}
},
"parameters": {
"tagName": {
"type": "String",
"metadata": {
"displayName": "Tag Name",
"description": "Name of the tag, such as 'environment'"
}
}
}
}
Please refer this example mentioned in the below link to ensure match pattern on tag value :
https://github.com/Azure/azure-policy/tree/master/samples/TextPatterns/enforce-tag-match-pattern

Does Azure Policies using JSON let you check for a VM extension by it's name?

I'm currently using the following exsistance condition:
"existenceCondition": {
"allOf": [
{
"field": "Microsoft.Compute/virtualMachines/extensions/instanceView.name",
"equals": "customextensionname"
},
{
"field": "Microsoft.Compute/virtualMachines/extensions/publisher",
"equals": "Microsoft.Compute"
},
{
"field": "Microsoft.Compute/virtualMachines/extensions/provisioningState",
"equals": "Succeeded"
}
]
I tried using extension/name and I get an error that it's not available. My policy checks for all windows VMs, but I'm not sure how to check the name of the extension. It's there, but it reports non compliant and that there is no value for instanceView.name..
i think it should be something like this:
{
"field": "type",
"equals": "Microsoft.Compute/VirtualMachines/extensions"
},
{
"not": {
"field": "name",
"equals": "customextensionname"
}
}
You don't need an alias for name. It's a supported top level field. Within the existence condition it will refer to the related resource - the extension in your case - not the evaluated resource.
Your existence condition will work like this:
"existenceCondition": {
"allOf": [
{
"field": "name",
"equals": "customextensionname"
},
{
"field": "Microsoft.Compute/virtualMachines/extensions/publisher",
"equals": "Microsoft.Compute"
},
{
"field": "Microsoft.Compute/virtualMachines/extensions/provisioningState",
"equals": "Succeeded"
}
]

How to force Name pattern for Hostnames in Azure policies?

Microsoft provides a JSON-Template for an Azure policy:
{
"properties": {
"displayName": "Hostname pattern with match condition.",
"description": "Enforce a naming pattern on Hostnames with the match condition.",
"mode": "All",
"parameters": {
"namePattern": {
"type": "String",
"metadata": {
"description": "Pattern to use for Hostnames. Can include ? for letters and # for numbers."
}
}
},
"policyRule": {
"if": {
"not": {
"field": "name",
"match": "[parameters('namePattern')]"
}
},
"then": {
"effect": "deny"
}
}
}
}
But this JSON checks for ALL resources in Azure (NICs, Disks, etc). I want only a Policy for Hostnames.
I think I have somewhere to inject the qualifier for /Microsoft.Compute/virtualMachines/ - but where? Every try ends up in an invalid JSON-File. Thanks for helping!
You can restrict the types of resources by specifying a check on the type field. We need to add "allOf" because we need all the conditions to be satisfied for a deny.
I think below change to your policy rule should work.
"policyRule": {
"if": {
"allof":[
{
"field": "type",
"equals": "Microsoft.Compute/VirtualMachines"
},
{
"not": {
"field": "name",
"match": "[parameters('namePattern')]"
}
}
]
},
"then": {
"effect": "deny"
}
}