Programmatically create policies

This article walks you through programmatically creating and managing policies. Azure Policy definitions enforce different rules and effects over your resources. Enforcement makes sure that resources stay compliant with your corporate standards and service-level agreements.

For information about compliance, see getting compliance data.

Prerequisites

Before you begin, make sure that the following prerequisites are met:

  1. If you haven't already, install the ARMClient. It's a tool that sends HTTP requests to Azure Resource Manager-based APIs.

  2. Update your Azure PowerShell module to the latest version. See Install Azure PowerShell module for detailed information. For more information about the latest version, see Azure PowerShell.

  3. Register the Azure Policy Insights resource provider using Azure PowerShell to validate that your subscription works with the resource provider. To register a resource provider, you must have permission to run the register action operation for the resource provider. This operation is included in the Contributor and Owner roles. Run the following command to register the resource provider:

    Register-AzResourceProvider -ProviderNamespace 'Microsoft.PolicyInsights'
    

    For more information about registering and viewing resource providers, see Resource Providers and Types.

  4. If you haven't already, install Azure CLI. You can get the latest version at Install Azure CLI on Windows.

Create and assign a policy definition

The first step toward better visibility of your resources is to create and assign policies over your resources. The next step is to learn how to programmatically create and assign a policy. The example policy audits storage accounts that are open to all public networks using PowerShell, Azure CLI, and HTTP requests.

Create and assign a policy definition with PowerShell

  1. Use the following JSON snippet to create a JSON file with the name AuditStorageAccounts.json.

    {
        "if": {
            "allOf": [{
                    "field": "type",
                    "equals": "Microsoft.Storage/storageAccounts"
                },
                {
                    "field": "Microsoft.Storage/storageAccounts/networkAcls.defaultAction",
                    "equals": "Allow"
                }
            ]
        },
        "then": {
            "effect": "audit"
        }
    }
    

    For more information about authoring a policy definition, see Azure Policy Definition Structure.

  2. Run the following command to create a policy definition using the AuditStorageAccounts.json file.

    New-AzPolicyDefinition -Name 'AuditStorageAccounts' -DisplayName 'Audit Storage Accounts Open to Public Networks' -Policy 'AuditStorageAccounts.json'
    

    The command creates a policy definition named Audit Storage Accounts Open to Public Networks. For more information about other parameters that you can use, see New-AzPolicyDefinition.

    When called without location parameters, New-AzPolicyDefinition defaults to saving the policy definition in the selected subscription of the sessions context. To save the definition to a different location, use the following parameters:

    • SubscriptionId - Save to a different subscription. Requires a GUID value.
    • ManagementGroupName - Save to a management group. Requires a string value.
  3. After you create your policy definition, you can create a policy assignment by running the following commands:

    $rg = Get-AzResourceGroup -Name 'ContosoRG'
    $Policy = Get-AzPolicyDefinition -Name 'AuditStorageAccounts'
    New-AzPolicyAssignment -Name 'AuditStorageAccounts' -PolicyDefinition $Policy -Scope $rg.ResourceId
    

    Replace ContosoRG with the name of your intended resource group.

    The Scope parameter on New-AzPolicyAssignment works with management group, subscription, resource group, or a single resource. The parameter uses a full resource path, which the ResourceId property on Get-AzResourceGroup returns. The pattern for Scope for each container is as follows. Replace {rName}, {rgName}, {subId}, and {mgName} with your resource name, resource group name, subscription ID, and management group name, respectively. {rType} would be replaced with the resource type of the resource, such as Microsoft.Compute/virtualMachines for a VM.

    • Resource - /subscriptions/{subID}/resourceGroups/{rgName}/providers/{rType}/{rName}
    • Resource group - /subscriptions/{subId}/resourceGroups/{rgName}
    • Subscription - /subscriptions/{subId}
    • Management group - /providers/Microsoft.Management/managementGroups/{mgName}

For more information about managing resource policies using the Resource Manager PowerShell module, see Az.Resources.

Create and assign a policy definition using ARMClient

Use the following procedure to create a policy definition.

  1. Copy the following JSON snippet to create a JSON file. You'll call the file in the next step.

    "properties": {
        "displayName": "Audit Storage Accounts Open to Public Networks",
        "policyType": "Custom",
        "mode": "Indexed",
        "description": "This policy ensures that storage accounts with exposure to Public Networks are audited.",
        "parameters": {},
        "policyRule": {
            "if": {
                "allOf": [{
                        "field": "type",
                        "equals": "Microsoft.Storage/storageAccounts"
                    },
                    {
                        "field": "Microsoft.Storage/storageAccounts/networkAcls.defaultAction",
                        "equals": "Allow"
                    }
                ]
            },
            "then": {
                "effect": "audit"
            }
        }
    }
    
  2. Create the policy definition using one of the following calls:

    # For defining a policy in a subscription
    armclient PUT "/subscriptions/{subscriptionId}/providers/Microsoft.Authorization/policyDefinitions/AuditStorageAccounts?api-version=2021-09-01" @<path to policy definition JSON file>
    
    # For defining a policy in a management group
    armclient PUT "/providers/Microsoft.Management/managementgroups/{managementGroupId}/providers/Microsoft.Authorization/policyDefinitions/AuditStorageAccounts?api-version=2021-09-01" @<path to policy definition JSON file>
    

    Replace the preceding {subscriptionId} with the ID of your subscription or {managementGroupId} with the ID of your management group.

    For more information about the structure of the query, see Azure Policy Definitions - Create or Update and Policy Definitions - Create or Update At Management Group.

Use the following procedure to create a policy assignment and assign the policy definition at the resource group level.

  1. Copy the following JSON snippet to create a JSON policy assignment file. Replace example information in <> symbols with your own values.

    {
        "properties": {
            "description": "This policy assignment makes sure that storage accounts with exposure to Public Networks are audited.",
            "displayName": "Audit Storage Accounts Open to Public Networks Assignment",
            "parameters": {},
            "policyDefinitionId": "/subscriptions/<subscriptionId>/providers/Microsoft.Authorization/policyDefinitions/Audit Storage Accounts Open to Public Networks",
            "scope": "/subscriptions/<subscriptionId>/resourceGroups/<resourceGroupName>"
        }
    }
    
  2. Create the policy assignment using the following call:

    armclient PUT "/subscriptions/<subscriptionID>/resourceGroups/<resourceGroupName>/providers/Microsoft.Authorization/policyAssignments/Audit Storage Accounts Open to Public Networks?api-version=2021-09-01" @<path to Assignment JSON file>
    

    Replace example information in <> symbols with your own values.

    For more information about making HTTP calls to the REST API, see Azure REST API Resources.

Create and assign a policy definition with Azure CLI

To create a policy definition, use the following procedure:

  1. Copy the following JSON snippet to create a JSON policy assignment file.

    {
        "if": {
            "allOf": [{
                    "field": "type",
                    "equals": "Microsoft.Storage/storageAccounts"
                },
                {
                    "field": "Microsoft.Storage/storageAccounts/networkAcls.defaultAction",
                    "equals": "Allow"
                }
            ]
        },
        "then": {
            "effect": "audit"
        }
    }
    

    For more information about authoring a policy definition, see Azure Policy Definition Structure.

  2. Run the following command to create a policy definition:

    az policy definition create --name 'audit-storage-accounts-open-to-public-networks' --display-name 'Audit Storage Accounts Open to Public Networks' --description 'This policy ensures that storage accounts with exposures to public networks are audited.' --rules '<path to json file>' --mode All
    

    The command creates a policy definition named Audit Storage Accounts Open to Public Networks. For more information about other parameters that you can use, see az policy definition create.

    When called without location parameters, az policy definition creation defaults to saving the policy definition in the selected subscription of the sessions context. To save the definition to a different location, use the following parameters:

    • subscription - Save to a different subscription. Requires a GUID value for the subscription ID or a string value for the subscription name.
    • management-group - Save to a management group. Requires a string value.
  3. Use the following command to create a policy assignment. Replace example information in <> symbols with your own values.

    az policy assignment create --name '<name>' --scope '<scope>' --policy '<policy definition ID>'
    

    The scope parameter on az policy assignment create works with management group, subscription, resource group, or a single resource. The parameter uses a full resource path. The pattern for scope for each container is as follows. Replace {rName}, {rgName}, {subId}, and {mgName} with your resource name, resource group name, subscription ID, and management group name, respectively. {rType} would be replaced with the resource type of the resource, such as Microsoft.Compute/virtualMachines for a VM.

    • Resource - /subscriptions/{subID}/resourceGroups/{rgName}/providers/{rType}/{rName}
    • Resource group - /subscriptions/{subID}/resourceGroups/{rgName}
    • Subscription - /subscriptions/{subID}
    • Management group - /providers/Microsoft.Management/managementGroups/{mgName}

You can get the Azure Policy Definition ID by using PowerShell with the following command:

az policy definition show --name 'Audit Storage Accounts with Open Public Networks'

The policy definition ID for the policy definition that you created should resemble the following example:

"/subscription/<subscriptionId>/providers/Microsoft.Authorization/policyDefinitions/Audit Storage Accounts Open to Public Networks"

For more information about how you can manage resource policies with Azure CLI, see Azure CLI Resource Policies.

Next steps

Review the following articles for more information about the commands and queries in this article.