Define, assign and test

Define the custom policy at the right scope point. Assign it and test it out to confirm that it works as expected.


We’ll define and assign the custom policy at the subscription scope to test it out.

Define the policy

  1. Determine your subscription scope

    subscriptionId=$(az account show --query id --output tsv)
  2. Create the custom policy definition

    az policy definition create --name jitDenySourceAny \
      --display-name "Deny JIT requests with source Any" \
      --description "Deny Just In Time (JIT) requests with Any as the source address prefix." \
      --metadata version="0.1.0" category="Just In Time" preview=true \
      --mode All \
      --params "@azurepolicy.parameters.json" \
      --rules "@azurepolicy.rules.json" \
      --subscription $subscriptionId

Assign the policy

  1. Assign the custom policy

    az policy assignment create --name jitDenySourceAny \
      --display-name "Deny Just In Time requests with All Configured Ports" \
      --policy jitDenySourceAny \
      --scope "/subscriptions/$subscriptionId"

    I normally recommend bundling custom policies together into a policy initiative and assigning the initiative instead. That approach is better from a lifecycle management perspective.

If you go back into the portal you can see the definition (in the new category) and the assignment.

Test the policy

  1. Remove the original rule

    az network nsg rule delete --name anysourcerule --nsg-name offender --resource-group custom_policy_lab
  2. Add it back in

    az network nsg rule create --name anysourcerule \
      --nsg-name offender \
      --resource-group custom_policy_lab \
      --direction Inbound \
      --priority 100 \
      --destination-address-prefix \
      --destination-port 22

    Example output:

    Resource 'anysourcerule' was disallowed by policy. Policy identifiers: '[{"policyAssignment":{"name":"Deny Just In Time requests with All Configured Ports","id":"/subscriptions/2ca40be1-7e80-4f2b-92f7-06b2123a68cc/providers/Microsoft.Authorization/policyAssignments/jitDenySourceAny"},"policyDefinition":{"name":"Deny JIT requests with source Any","id":"/subscriptions/2ca40be1-7e80-4f2b-92f7-06b2123a68cc/providers/Microsoft.Authorization/policyDefinitions/jitDenySourceAny"}}]'.

    OK, the policy is working as required. Job done!

Finishing up

Thankfully, creating custom policies is an increasingly rare event as the number of built in policies grows each day. There is also a growing amount of community content out there. But if you need to create your own policies then understanding aliases and the policy structure is vital.

If you have created a new custom policy that you couldn’t find anywhere else then perhaps it could be useful to others. You could always contribute to the set of community policies.

Perhaps it would be good to keep your custom policies and initiatives in a GitHub repo and use GitHub Actions to push them into production. Or embed into infrastructure as code such as ARM templates or Terraform configs.


Help us improve

Azure Citadel is a community site built on GitHub, please contribute and send a pull request

 Make a change