Create the custom policy
OK, we know the aliases to use and the logic we need to apply. Time to construct the JSON for the custom policy.
Create a custom policy
OK, you now have all of the building blocks and info to create the policy, plus a selection of links. The lab will start you off with a template and then you can work through the sections to start fleshing it out. It will be more painful than just copying and pasting code blocks, but no-one learns much that way.
If you do get stuck then scroll to the example azurepolicy.json.
Policy template
-
Press
CTRL
+SHIFT
+E
to open the Explorer -
Create a new file called azurepolicy.json
-
Copy in the template below:
{ "properties": { "displayName": "<displayName>", "description": "<description>", "mode": "<mode>", "metadata": { "version": "0.1.0", "category": "categoryName", "preview": true }, "parameters": { <parameters> }, "policyRule": { "if": { <rule> }, "then": { "effect": "<effect>" } } } }
Core properties
Customise the core properties
- Update displayName to “Deny JIT requests with source Any”
- Update description to “Deny Just In Time (JIT) requests with Any as the source address prefix.”
- Set mode to “All”
Indexed mode should only be used when dealing with resources that have tags and locations.
Metadata
The metadata block is optional but can be very useful. The version, category and preview keys are known ad common properties and control where and how the policy is displayed in the portal.
-
Set the category to “Just In Time”
You can specify a pre-existing category that is already used by the inbuilt policies, or create a new category.
You can also create your own key value pairs within the metadata block to add information that is useful to you. For instance, you could add a creator name, link back to a source repo or refer back to a change request record.
Parameters
Using parameters makes your policies more flexible and can reduce the number of custom policies you have to create. Make use of the strongTypes where possible.
- Add a parameter called ports
- Add a suitable displayname and description
- Default the parameter to the standard set of Just In Time ports
Policy Rule
Modify the policyRule section to deny JIT security rules that have the source address prefix set to Any.
- Ensure the if handles either the networkSecurityGroups or securityRules resourceTypes
- Use the ports parameter
- If the condition is evaluated as true then the effect should be Deny
Example azurepolicy.json
If you want to see how your finished template compares to the one I created - or you’ve just got a bit stuck - then here is the full version.
{
"properties": {
"displayName": "Deny JIT requests with source Any",
"description": "Deny Just In Time (JIT) requests with Any as the source address prefix.",
"mode": "All",
"metadata": {
"version": "0.1.0",
"category": "Just In Time",
"preview": true
},
"parameters": {
"ports": {
"type": "array",
"metadata": {
"description": "The list of destination ports to check. Defaults to the standard Just In Time set.",
"displayName": "Array of ports to check for."
},
"defaultValue": [
"22",
"3389",
"5985",
"5986"
]
}
},
"policyRule": {
"if": {
"anyOf": [
{
"allOf": [
{
"field": "type",
"equals": "Microsoft.Network/networkSecurityGroups/securityRules"
},
{
"field": "Microsoft.Network/networkSecurityGroups/securityRules/direction",
"equals": "Inbound"
},
{
"field": "Microsoft.Network/networkSecurityGroups/securityRules/access",
"equals": "Allow"
},
{
"field": "Microsoft.Network/networkSecurityGroups/securityRules/sourceAddressPrefix",
"equals": "*"
},
{
"field": "Microsoft.Network/networkSecurityGroups/securityRules/destinationPortRange",
"in": "[parameters('ports')]"
}
]
},
{
"allOf": [
{
"field": "type",
"equals": "Microsoft.Network/networkSecurityGroups"
},
{
"count": {
"field": "Microsoft.Network/networkSecurityGroups/securityRules[*]",
"where": {
"allOf": [
{
"field": "Microsoft.Network/networkSecurityGroups/securityRules[*].direction",
"equals": "Inbound"
},
{
"field": "Microsoft.Network/networkSecurityGroups/securityRules[*].access",
"equals": "Allow"
},
{
"field": "Microsoft.Network/networkSecurityGroups/securityRules[*].sourceAddressPrefix",
"equals": "*"
},
{
"field": "Microsoft.Network/networkSecurityGroups/securityRules[*].destinationPortRange",
"in": "[parameters('ports')]"
}
]
}
},
"greater": 0
}
]
}
]
},
"then": {
"effect": "deny"
}
}
}
}
Create the additional files
The convention is to create a set of three files as different commands use either the full azuredeploy.json, or the azurepolicy.parameter.json and azurepolicy.rules.json.
- Create the additional files using jq
jq .properties.parameters < azurepolicy.json > azurepolicy.parameters.json
jq .properties.policyRule < azurepolicy.json > azurepolicy.rules.json
Next steps
OK, we have our set of files. Let’s define the policy and assign it for testing.
Help us improve
Azure Citadel is a community site built on GitHub, please contribute and send a pull request
Make a change