Files
regorus/tests/azure_policy/cases/versioned_normalization.yaml
Anand Krishnamoorthi 7f42115b63 test(azure_policy): add foundation test cases (#698)
YAML-driven test cases for the core Azure Policy compiler. These cover
alias resolution, field conditions, logical operators, type coercion,
count expressions, template functions, effect compilation, and policy
definition parsing. 24 files, each a self-contained scenario exercised
by the test runner in the companion code PR.

Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-28 11:03:39 -05:00

2130 lines
61 KiB
YAML

# Versioned alias normalization tests.
#
# Each test verifies that the normalizer picks the correct ARM path based on
# the api_version. Resources contain DIFFERENT values at each possible path
# so that if the wrong path is selected, the "equals" check fails and the
# test fails with an unexpected undefined / wrong effect.
#
# Aliases file: versioned_aliases.json (Microsoft.Test/versionedResources)
#
# Alias | Old API (2015) | New API (2020) | Default (no match)
# ----------------------|----------------------------------------|----------------------------------|-------------------
# accountType | properties.accountType | sku.name | properties.accountType
# config.threshold | properties.config.properties.threshold | properties.config.threshold | properties.config.threshold
# tier | properties.pricingTier | sku.tier | sku.tier
# operationMode | properties.legacyMode | properties.mode | properties.mode
# | (2015-01-01 only) | (2020-01-01 only) |
# | properties.settings.mode (2017-06-01) | |
aliases: versioned_aliases.json
cases:
# =========================================================================
# 1. simpleProp — no versioning, baseline sanity check
# =========================================================================
- note: simple_prop_baseline
policy_rule: |
{
"if": {
"field": "Microsoft.Test/versionedResources/simpleProp",
"equals": "hello"
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/versionedResources
name: testResource
properties:
simpleProp: "hello"
want_effect: "Deny"
# =========================================================================
# 2. accountType — properties.accountType (old) vs sku.name (new)
# Resource has DIFFERENT values at each path.
# =========================================================================
# Old API → should read properties.accountType = "Premium_LRS"
- note: accountType_old_api
policy_rule: |
{
"if": {
"field": "Microsoft.Test/versionedResources/accountType",
"equals": "Premium_LRS"
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/versionedResources
name: testResource
sku:
name: "Standard_LRS"
properties:
accountType: "Premium_LRS"
api_version: "2015-06-15"
want_effect: "Deny"
# Old API — verify wrong value is NOT matched
- note: accountType_old_api_wrong_value
policy_rule: |
{
"if": {
"field": "Microsoft.Test/versionedResources/accountType",
"equals": "Standard_LRS"
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/versionedResources
name: testResource
sku:
name: "Standard_LRS"
properties:
accountType: "Premium_LRS"
api_version: "2015-06-15"
want_undefined: true
# New API → should read sku.name = "Standard_LRS"
- note: accountType_new_api
policy_rule: |
{
"if": {
"field": "Microsoft.Test/versionedResources/accountType",
"equals": "Standard_LRS"
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/versionedResources
name: testResource
sku:
name: "Standard_LRS"
properties:
accountType: "Premium_LRS"
api_version: "2020-01-01"
want_effect: "Deny"
# New API — verify wrong value is NOT matched
- note: accountType_new_api_wrong_value
policy_rule: |
{
"if": {
"field": "Microsoft.Test/versionedResources/accountType",
"equals": "Premium_LRS"
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/versionedResources
name: testResource
sku:
name: "Standard_LRS"
properties:
accountType: "Premium_LRS"
api_version: "2020-01-01"
want_undefined: true
# No API version → default path = properties.accountType
- note: accountType_no_api_version
policy_rule: |
{
"if": {
"field": "Microsoft.Test/versionedResources/accountType",
"equals": "Premium_LRS"
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/versionedResources
name: testResource
sku:
name: "Standard_LRS"
properties:
accountType: "Premium_LRS"
want_effect: "Deny"
# Unknown API version → falls back to default = properties.accountType
- note: accountType_unknown_api_version
policy_rule: |
{
"if": {
"field": "Microsoft.Test/versionedResources/accountType",
"equals": "Premium_LRS"
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/versionedResources
name: testResource
sku:
name: "Standard_LRS"
properties:
accountType: "Premium_LRS"
api_version: "2099-01-01"
want_effect: "Deny"
# =========================================================================
# 3. accountType with fully-qualified alias name in policy
# Tests both compiler FQ→short resolution AND normalizer versioned path.
# =========================================================================
- note: fq_accountType_old_api
policy_rule: |
{
"if": {
"field": "Microsoft.Test/versionedResources/accountType",
"equals": "Premium_LRS"
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/versionedResources
name: testResource
sku:
name: "Standard_LRS"
properties:
accountType: "Premium_LRS"
api_version: "2015-06-15"
want_effect: "Deny"
- note: fq_accountType_new_api
policy_rule: |
{
"if": {
"field": "Microsoft.Test/versionedResources/accountType",
"equals": "Standard_LRS"
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/versionedResources
name: testResource
sku:
name: "Standard_LRS"
properties:
accountType: "Premium_LRS"
api_version: "2020-01-01"
want_effect: "Deny"
# =========================================================================
# 4. config.threshold — extra properties nesting in old API
# Old: properties.config.properties.threshold = 200
# New: properties.config.threshold = 100
# =========================================================================
- note: config_threshold_old_api
policy_rule: |
{
"if": {
"field": "Microsoft.Test/versionedResources/config.threshold",
"equals": 200
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/versionedResources
name: testResource
properties:
config:
threshold: 100
properties:
threshold: 200
api_version: "2015-06-15"
want_effect: "Deny"
- note: config_threshold_old_api_wrong
policy_rule: |
{
"if": {
"field": "Microsoft.Test/versionedResources/config.threshold",
"equals": 100
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/versionedResources
name: testResource
properties:
config:
threshold: 100
properties:
threshold: 200
api_version: "2015-06-15"
want_undefined: true
- note: config_threshold_new_api
policy_rule: |
{
"if": {
"field": "Microsoft.Test/versionedResources/config.threshold",
"equals": 100
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/versionedResources
name: testResource
properties:
config:
threshold: 100
properties:
threshold: 200
api_version: "2020-01-01"
want_effect: "Deny"
- note: config_threshold_new_api_wrong
policy_rule: |
{
"if": {
"field": "Microsoft.Test/versionedResources/config.threshold",
"equals": 200
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/versionedResources
name: testResource
properties:
config:
threshold: 100
properties:
threshold: 200
api_version: "2020-01-01"
want_undefined: true
# =========================================================================
# 5. tier — properties.pricingTier (old) vs sku.tier (new)
# =========================================================================
- note: tier_old_api
policy_rule: |
{
"if": {
"field": "Microsoft.Test/versionedResources/tier",
"equals": "Premium"
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/versionedResources
name: testResource
sku:
tier: "Standard"
properties:
pricingTier: "Premium"
api_version: "2015-06-15"
want_effect: "Deny"
- note: tier_old_api_wrong
policy_rule: |
{
"if": {
"field": "Microsoft.Test/versionedResources/tier",
"equals": "Standard"
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/versionedResources
name: testResource
sku:
tier: "Standard"
properties:
pricingTier: "Premium"
api_version: "2015-06-15"
want_undefined: true
- note: tier_new_api
policy_rule: |
{
"if": {
"field": "Microsoft.Test/versionedResources/tier",
"equals": "Standard"
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/versionedResources
name: testResource
sku:
tier: "Standard"
properties:
pricingTier: "Premium"
api_version: "2020-01-01"
want_effect: "Deny"
- note: tier_new_api_wrong
policy_rule: |
{
"if": {
"field": "Microsoft.Test/versionedResources/tier",
"equals": "Premium"
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/versionedResources
name: testResource
sku:
tier: "Standard"
properties:
pricingTier: "Premium"
api_version: "2020-01-01"
want_undefined: true
# =========================================================================
# 6. operationMode — three distinct paths across versions
# 2015-01-01: properties.legacyMode = "compat"
# 2017-06-01: properties.settings.mode = "advanced"
# 2020-01-01: properties.mode = "standard"
# default: properties.mode = "standard"
# =========================================================================
- note: operationMode_oldest_api
policy_rule: |
{
"if": {
"field": "Microsoft.Test/versionedResources/operationMode",
"equals": "compat"
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/versionedResources
name: testResource
properties:
legacyMode: "compat"
mode: "standard"
settings:
mode: "advanced"
api_version: "2015-01-01"
want_effect: "Deny"
- note: operationMode_oldest_api_wrong
policy_rule: |
{
"if": {
"field": "Microsoft.Test/versionedResources/operationMode",
"equals": "standard"
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/versionedResources
name: testResource
properties:
legacyMode: "compat"
mode: "standard"
settings:
mode: "advanced"
api_version: "2015-01-01"
want_undefined: true
- note: operationMode_middle_api
policy_rule: |
{
"if": {
"field": "Microsoft.Test/versionedResources/operationMode",
"equals": "advanced"
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/versionedResources
name: testResource
properties:
legacyMode: "compat"
mode: "standard"
settings:
mode: "advanced"
api_version: "2017-06-01"
want_effect: "Deny"
- note: operationMode_middle_api_wrong
policy_rule: |
{
"if": {
"field": "Microsoft.Test/versionedResources/operationMode",
"equals": "compat"
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/versionedResources
name: testResource
properties:
legacyMode: "compat"
mode: "standard"
settings:
mode: "advanced"
api_version: "2017-06-01"
want_undefined: true
- note: operationMode_newest_api
policy_rule: |
{
"if": {
"field": "Microsoft.Test/versionedResources/operationMode",
"equals": "standard"
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/versionedResources
name: testResource
properties:
legacyMode: "compat"
mode: "standard"
settings:
mode: "advanced"
api_version: "2020-01-01"
want_effect: "Deny"
- note: operationMode_default_no_api
policy_rule: |
{
"if": {
"field": "Microsoft.Test/versionedResources/operationMode",
"equals": "standard"
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/versionedResources
name: testResource
properties:
legacyMode: "compat"
mode: "standard"
settings:
mode: "advanced"
want_effect: "Deny"
# =========================================================================
# 7. FQ alias with operationMode (mixed-case short name + versioned paths)
# =========================================================================
- note: fq_operationMode_middle_api
policy_rule: |
{
"if": {
"field": "Microsoft.Test/versionedResources/operationMode",
"equals": "advanced"
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/versionedResources
name: testResource
properties:
legacyMode: "compat"
mode: "standard"
settings:
mode: "advanced"
api_version: "2017-06-01"
want_effect: "Deny"
# =========================================================================
# PART 2 — Complex resource type: Microsoft.Test/complexResources
#
# Alias catalog for this type includes:
# - Sub-resource array: rules[*] (with properties flattening)
# - Nested sub-resource array: rules[*].filters[*] (2-level flattening)
# - Primitive array: allowedIPs[*] (strings, no properties wrapper)
# - Sub-resource element fields: rules[*].action, rules[*].protocol, etc.
# - Versioned sub-resource field: rules[*].priority (old vs new path)
# - Nested object alias: config.retryCount (versioned), config.timeout
# - Deeply nested alias: settings.encryption.enabled (versioned)
# - Primitive array inside sub-resource: rules[*].targets[*]
# =========================================================================
# -----------------------------------------------------------------------
# 8. Scalar baseline — enabled field
# -----------------------------------------------------------------------
- note: complex_enabled_baseline
policy_rule: |
{
"if": {
"field": "Microsoft.Test/complexResources/enabled",
"equals": true
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
enabled: true
want_effect: "Deny"
- note: complex_enabled_false
policy_rule: |
{
"if": {
"field": "Microsoft.Test/complexResources/enabled",
"equals": true
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
enabled: false
want_undefined: true
# -----------------------------------------------------------------------
# 9. Sub-resource array: count rules[*]
# -----------------------------------------------------------------------
- note: count_rules_basic
policy_rule: |
{
"if": {
"count": {
"field": "Microsoft.Test/complexResources/rules[*]"
},
"greater": 2
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
rules:
- name: r1
properties:
action: "Allow"
- name: r2
properties:
action: "Deny"
- name: r3
properties:
action: "Allow"
want_effect: "Deny"
- note: count_rules_not_enough
policy_rule: |
{
"if": {
"count": {
"field": "Microsoft.Test/complexResources/rules[*]"
},
"greater": 5
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
rules:
- name: r1
properties:
action: "Allow"
- name: r2
properties:
action: "Deny"
want_undefined: true
# -----------------------------------------------------------------------
# 10. Sub-resource with where — access flattened properties
# rules[*].action lives under properties wrapper in ARM.
# After normalization, it should be at rules[*].action directly.
# -----------------------------------------------------------------------
- note: count_rules_where_action
policy_rule: |
{
"if": {
"count": {
"field": "Microsoft.Test/complexResources/rules[*]",
"where": {
"field": "Microsoft.Test/complexResources/rules[*].action",
"equals": "Allow"
}
},
"equals": 2
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
rules:
- name: r1
properties:
action: "Allow"
- name: r2
properties:
action: "Deny"
- name: r3
properties:
action: "Allow"
want_effect: "Deny"
- note: count_rules_where_action_zero
policy_rule: |
{
"if": {
"count": {
"field": "Microsoft.Test/complexResources/rules[*]",
"where": {
"field": "Microsoft.Test/complexResources/rules[*].action",
"equals": "Block"
}
},
"equals": 0
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
rules:
- name: r1
properties:
action: "Allow"
- name: r2
properties:
action: "Deny"
want_effect: "Deny"
# -----------------------------------------------------------------------
# 11. Sub-resource where with allOf — multiple flattened fields
# -----------------------------------------------------------------------
- note: count_rules_where_allOf
policy_rule: |
{
"if": {
"count": {
"field": "Microsoft.Test/complexResources/rules[*]",
"where": {
"allOf": [
{ "field": "Microsoft.Test/complexResources/rules[*].action", "equals": "Allow" },
{ "field": "Microsoft.Test/complexResources/rules[*].direction", "equals": "Inbound" },
{ "field": "Microsoft.Test/complexResources/rules[*].protocol", "equals": "Tcp" }
]
}
},
"greaterOrEquals": 1
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
rules:
- name: r1
properties:
action: "Allow"
direction: "Inbound"
protocol: "Tcp"
- name: r2
properties:
action: "Allow"
direction: "Outbound"
protocol: "Tcp"
- name: r3
properties:
action: "Deny"
direction: "Inbound"
protocol: "Tcp"
want_effect: "Deny"
- note: count_rules_where_allOf_no_match
policy_rule: |
{
"if": {
"count": {
"field": "Microsoft.Test/complexResources/rules[*]",
"where": {
"allOf": [
{ "field": "Microsoft.Test/complexResources/rules[*].action", "equals": "Allow" },
{ "field": "Microsoft.Test/complexResources/rules[*].direction", "equals": "Inbound" },
{ "field": "Microsoft.Test/complexResources/rules[*].protocol", "equals": "Udp" }
]
}
},
"greaterOrEquals": 1
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
rules:
- name: r1
properties:
action: "Allow"
direction: "Inbound"
protocol: "Tcp"
want_undefined: true
# -----------------------------------------------------------------------
# 12. Sub-resource where with anyOf
# -----------------------------------------------------------------------
- note: count_rules_where_anyOf_destPort
policy_rule: |
{
"if": {
"count": {
"field": "Microsoft.Test/complexResources/rules[*]",
"where": {
"anyOf": [
{ "field": "Microsoft.Test/complexResources/rules[*].destPort", "equals": "22" },
{ "field": "Microsoft.Test/complexResources/rules[*].destPort", "equals": "3389" }
]
}
},
"notEquals": 0
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
rules:
- name: r1
properties:
destPort: "443"
- name: r2
properties:
destPort: "22"
want_effect: "Deny"
# -----------------------------------------------------------------------
# 13. Sub-resource where with not
# -----------------------------------------------------------------------
- note: count_rules_where_not
policy_rule: |
{
"if": {
"count": {
"field": "Microsoft.Test/complexResources/rules[*]",
"where": {
"not": {
"field": "Microsoft.Test/complexResources/rules[*].action",
"equals": "Deny"
}
}
},
"greater": 0
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
rules:
- name: r1
properties:
action: "Allow"
- name: r2
properties:
action: "Deny"
want_effect: "Deny"
# -----------------------------------------------------------------------
# 14. Primitive array: count allowedIPs[*]
# Unlike rules[*], allowedIPs is a plain string array — no properties
# flattening.
# -----------------------------------------------------------------------
- note: count_allowedIPs_basic
policy_rule: |
{
"if": {
"count": {
"field": "Microsoft.Test/complexResources/allowedIPs[*]",
"where": {
"field": "Microsoft.Test/complexResources/allowedIPs[*]",
"like": "10.*"
}
},
"equals": 2
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
allowedIPs:
- "10.0.0.1"
- "192.168.1.1"
- "10.0.0.2"
want_effect: "Deny"
- note: count_allowedIPs_empty
policy_rule: |
{
"if": {
"count": {
"field": "Microsoft.Test/complexResources/allowedIPs[*]"
},
"equals": 0
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
allowedIPs: []
want_effect: "Deny"
# -----------------------------------------------------------------------
# 15. Primitive array inside sub-resource: rules[*].targets[*]
# -----------------------------------------------------------------------
- note: count_rules_targets_nested
policy_rule: |
{
"if": {
"count": {
"field": "Microsoft.Test/complexResources/rules[*]",
"where": {
"count": {
"field": "Microsoft.Test/complexResources/rules[*].targets[*]",
"where": {
"field": "Microsoft.Test/complexResources/rules[*].targets[*]",
"like": "*.prod.*"
}
},
"greater": 0
}
},
"greater": 0
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
rules:
- name: r1
properties:
action: "Allow"
targets:
- "app.prod.east"
- "app.dev.east"
- name: r2
properties:
action: "Allow"
targets:
- "api.dev.west"
want_effect: "Deny"
- note: count_rules_targets_nested_no_prod
policy_rule: |
{
"if": {
"count": {
"field": "Microsoft.Test/complexResources/rules[*]",
"where": {
"count": {
"field": "Microsoft.Test/complexResources/rules[*].targets[*]",
"where": {
"field": "Microsoft.Test/complexResources/rules[*].targets[*]",
"like": "*.prod.*"
}
},
"greater": 0
}
},
"greater": 0
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
rules:
- name: r1
properties:
action: "Allow"
targets:
- "app.dev.east"
- name: r2
properties:
action: "Allow"
targets:
- "api.staging.west"
want_undefined: true
# -----------------------------------------------------------------------
# 16. Nested sub-resource arrays: rules[*].filters[*]
# filters[*] is a sub-resource (has properties wrapper) nested inside
# rules[*] — two-level properties flattening.
# -----------------------------------------------------------------------
- note: nested_sub_resource_count
policy_rule: |
{
"if": {
"count": {
"field": "Microsoft.Test/complexResources/rules[*]",
"where": {
"count": {
"field": "Microsoft.Test/complexResources/rules[*].filters[*]",
"where": {
"field": "Microsoft.Test/complexResources/rules[*].filters[*].name",
"equals": "source-ip"
}
},
"greater": 0
}
},
"greater": 0
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
rules:
- name: r1
properties:
action: "Allow"
filters:
- properties:
name: "source-ip"
value: "10.0.0.0/8"
- properties:
name: "protocol"
value: "tcp"
- name: r2
properties:
action: "Deny"
filters:
- properties:
name: "dest-port"
value: "22"
want_effect: "Deny"
- note: nested_sub_resource_count_no_match
policy_rule: |
{
"if": {
"count": {
"field": "Microsoft.Test/complexResources/rules[*]",
"where": {
"count": {
"field": "Microsoft.Test/complexResources/rules[*].filters[*]",
"where": {
"field": "Microsoft.Test/complexResources/rules[*].filters[*].name",
"equals": "geo-location"
}
},
"greater": 0
}
},
"greater": 0
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
rules:
- name: r1
properties:
action: "Allow"
filters:
- properties:
name: "source-ip"
value: "10.0.0.0/8"
want_undefined: true
- note: nested_sub_resource_filter_value
policy_rule: |
{
"if": {
"count": {
"field": "Microsoft.Test/complexResources/rules[*]",
"where": {
"count": {
"field": "Microsoft.Test/complexResources/rules[*].filters[*]",
"where": {
"allOf": [
{ "field": "Microsoft.Test/complexResources/rules[*].filters[*].name", "equals": "protocol" },
{ "field": "Microsoft.Test/complexResources/rules[*].filters[*].value", "equals": "tcp" }
]
}
},
"greater": 0
}
},
"equals": 1
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
rules:
- name: r1
properties:
action: "Allow"
filters:
- properties:
name: "protocol"
value: "tcp"
- name: r2
properties:
action: "Deny"
filters:
- properties:
name: "protocol"
value: "udp"
want_effect: "Deny"
# -----------------------------------------------------------------------
# 17. Count in allOf: type check + sub-resource count
# -----------------------------------------------------------------------
- note: count_in_allOf_with_type_check
policy_rule: |
{
"if": {
"allOf": [
{ "field": "type", "equals": "Microsoft.Test/complexResources" },
{
"count": {
"field": "Microsoft.Test/complexResources/rules[*]",
"where": {
"allOf": [
{ "field": "Microsoft.Test/complexResources/rules[*].action", "equals": "Allow" },
{ "field": "Microsoft.Test/complexResources/rules[*].direction", "equals": "Inbound" }
]
}
},
"greater": 0
}
]
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
rules:
- name: r1
properties:
action: "Allow"
direction: "Inbound"
- name: r2
properties:
action: "Deny"
direction: "Outbound"
want_effect: "Deny"
- note: count_in_allOf_wrong_type
policy_rule: |
{
"if": {
"allOf": [
{ "field": "type", "equals": "Microsoft.Other/resources" },
{
"count": {
"field": "Microsoft.Test/complexResources/rules[*]",
"where": {
"field": "Microsoft.Test/complexResources/rules[*].action",
"equals": "Allow"
}
},
"greater": 0
}
]
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
rules:
- name: r1
properties:
action: "Allow"
want_undefined: true
# -----------------------------------------------------------------------
# 18. Nested object: config.retryCount — versioned
# Old API: properties.config.properties.retryCount
# New API: properties.config.retryCount
# -----------------------------------------------------------------------
- note: config_retryCount_old_api
policy_rule: |
{
"if": {
"field": "Microsoft.Test/complexResources/config.retryCount",
"greater": 3
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
config:
retryCount: 2
properties:
retryCount: 5
api_version: "2015-01-01"
want_effect: "Deny"
- note: config_retryCount_old_api_wrong
policy_rule: |
{
"if": {
"field": "Microsoft.Test/complexResources/config.retryCount",
"greater": 3
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
config:
retryCount: 2
properties:
retryCount: 1
api_version: "2015-01-01"
want_undefined: true
- note: config_retryCount_new_api
policy_rule: |
{
"if": {
"field": "Microsoft.Test/complexResources/config.retryCount",
"greater": 3
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
config:
retryCount: 5
properties:
retryCount: 1
api_version: "2020-01-01"
want_effect: "Deny"
- note: config_retryCount_new_api_wrong
policy_rule: |
{
"if": {
"field": "Microsoft.Test/complexResources/config.retryCount",
"greater": 3
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
config:
retryCount: 2
properties:
retryCount: 99
api_version: "2020-01-01"
want_undefined: true
# -----------------------------------------------------------------------
# 19. Non-versioned nested object: config.timeout
# -----------------------------------------------------------------------
- note: config_timeout_baseline
policy_rule: |
{
"if": {
"field": "Microsoft.Test/complexResources/config.timeout",
"greater": 30
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
config:
timeout: 60
want_effect: "Deny"
# -----------------------------------------------------------------------
# 20. Deep nested alias: settings.encryption.enabled — versioned
# Old API (2015): properties.encryptionEnabled (flat)
# New API (2020): properties.settings.encryption.enabled (deep)
# -----------------------------------------------------------------------
- note: encryption_enabled_old_api
policy_rule: |
{
"if": {
"field": "Microsoft.Test/complexResources/settings.encryption.enabled",
"equals": true
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
encryptionEnabled: true
settings:
encryption:
enabled: false
api_version: "2015-01-01"
want_effect: "Deny"
- note: encryption_enabled_old_api_wrong
policy_rule: |
{
"if": {
"field": "Microsoft.Test/complexResources/settings.encryption.enabled",
"equals": true
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
encryptionEnabled: false
settings:
encryption:
enabled: true
api_version: "2015-01-01"
want_undefined: true
- note: encryption_enabled_new_api
policy_rule: |
{
"if": {
"field": "Microsoft.Test/complexResources/settings.encryption.enabled",
"equals": true
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
encryptionEnabled: false
settings:
encryption:
enabled: true
api_version: "2020-01-01"
want_effect: "Deny"
- note: encryption_enabled_new_api_wrong
policy_rule: |
{
"if": {
"field": "Microsoft.Test/complexResources/settings.encryption.enabled",
"equals": true
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
encryptionEnabled: true
settings:
encryption:
enabled: false
api_version: "2020-01-01"
want_undefined: true
- note: encryption_enabled_no_api_default
policy_rule: |
{
"if": {
"field": "Microsoft.Test/complexResources/settings.encryption.enabled",
"equals": true
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
encryptionEnabled: false
settings:
encryption:
enabled: true
want_effect: "Deny"
# -----------------------------------------------------------------------
# 21. FQ alias: fully-qualified with complex resource
# -----------------------------------------------------------------------
- note: fq_config_retryCount_old_api
policy_rule: |
{
"if": {
"field": "Microsoft.Test/complexResources/config.retryCount",
"greater": 3
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
config:
retryCount: 2
properties:
retryCount: 5
api_version: "2015-01-01"
want_effect: "Deny"
- note: fq_encryption_enabled_new_api
policy_rule: |
{
"if": {
"field": "Microsoft.Test/complexResources/settings.encryption.enabled",
"equals": true
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
encryptionEnabled: false
settings:
encryption:
enabled: true
api_version: "2020-01-01"
want_effect: "Deny"
# -----------------------------------------------------------------------
# 22. Complex NSG-like: type + count + where(allOf) + anyOf inside where
# -----------------------------------------------------------------------
- note: complex_nsg_like_deny_ssh
policy_rule: |
{
"if": {
"allOf": [
{ "field": "type", "equals": "Microsoft.Test/complexResources" },
{
"count": {
"field": "Microsoft.Test/complexResources/rules[*]",
"where": {
"allOf": [
{ "field": "Microsoft.Test/complexResources/rules[*].action", "equals": "Allow" },
{ "field": "Microsoft.Test/complexResources/rules[*].direction", "equals": "Inbound" },
{
"anyOf": [
{ "field": "Microsoft.Test/complexResources/rules[*].destPort", "equals": "22" },
{ "field": "Microsoft.Test/complexResources/rules[*].destPort", "equals": "*" }
]
},
{
"anyOf": [
{ "field": "Microsoft.Test/complexResources/rules[*].sourcePort", "equals": "*" },
{ "field": "Microsoft.Test/complexResources/rules[*].sourcePort", "equals": "0" }
]
}
]
}
},
"greater": 0
}
]
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
rules:
- name: allowHTTPS
properties:
action: "Allow"
direction: "Inbound"
protocol: "Tcp"
destPort: "443"
sourcePort: "*"
- name: allowSSH
properties:
action: "Allow"
direction: "Inbound"
protocol: "Tcp"
destPort: "22"
sourcePort: "*"
want_effect: "Deny"
- note: complex_nsg_like_no_ssh
policy_rule: |
{
"if": {
"allOf": [
{ "field": "type", "equals": "Microsoft.Test/complexResources" },
{
"count": {
"field": "Microsoft.Test/complexResources/rules[*]",
"where": {
"allOf": [
{ "field": "Microsoft.Test/complexResources/rules[*].action", "equals": "Allow" },
{ "field": "Microsoft.Test/complexResources/rules[*].direction", "equals": "Inbound" },
{
"anyOf": [
{ "field": "Microsoft.Test/complexResources/rules[*].destPort", "equals": "22" },
{ "field": "Microsoft.Test/complexResources/rules[*].destPort", "equals": "*" }
]
}
]
}
},
"greater": 0
}
]
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
rules:
- name: allowHTTPS
properties:
action: "Allow"
direction: "Inbound"
protocol: "Tcp"
destPort: "443"
sourcePort: "*"
- name: denySSH
properties:
action: "Deny"
direction: "Inbound"
protocol: "Tcp"
destPort: "22"
sourcePort: "*"
want_undefined: true
# -----------------------------------------------------------------------
# 23. Value count with nested field count across sub-resources
# "For each required port, at least one Allow rule must exist"
# -----------------------------------------------------------------------
- note: value_count_nested_field_count_rules
policy_rule: |
{
"if": {
"count": {
"value": "[parameters('requiredPorts')]",
"name": "port",
"where": {
"count": {
"field": "Microsoft.Test/complexResources/rules[*]",
"where": {
"allOf": [
{ "field": "Microsoft.Test/complexResources/rules[*].destPort", "equals": "[current('port')]" },
{ "field": "Microsoft.Test/complexResources/rules[*].action", "equals": "Allow" }
]
}
},
"greater": 0
}
},
"equals": "[length(parameters('requiredPorts'))]"
},
"then": { "effect": "Deny" }
}
parameters:
requiredPorts:
- "443"
- "80"
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
rules:
- name: allowHTTPS
properties:
action: "Allow"
destPort: "443"
- name: allowHTTP
properties:
action: "Allow"
destPort: "80"
- name: denySSH
properties:
action: "Deny"
destPort: "22"
want_effect: "Deny"
- note: value_count_nested_field_count_rules_missing
policy_rule: |
{
"if": {
"count": {
"value": "[parameters('requiredPorts')]",
"name": "port",
"where": {
"count": {
"field": "Microsoft.Test/complexResources/rules[*]",
"where": {
"allOf": [
{ "field": "Microsoft.Test/complexResources/rules[*].destPort", "equals": "[current('port')]" },
{ "field": "Microsoft.Test/complexResources/rules[*].action", "equals": "Allow" }
]
}
},
"greater": 0
}
},
"equals": "[length(parameters('requiredPorts'))]"
},
"then": { "effect": "Deny" }
}
parameters:
requiredPorts:
- "443"
- "80"
- "8080"
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
rules:
- name: allowHTTPS
properties:
action: "Allow"
destPort: "443"
- name: allowHTTP
properties:
action: "Allow"
destPort: "80"
want_undefined: true
# -----------------------------------------------------------------------
# 24. Empty sub-resource array — count = 0
# -----------------------------------------------------------------------
- note: count_rules_empty_array
policy_rule: |
{
"if": {
"count": {
"field": "Microsoft.Test/complexResources/rules[*]"
},
"equals": 0
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
rules: []
want_effect: "Deny"
# -----------------------------------------------------------------------
# 25. Missing sub-resource array — count = 0
# -----------------------------------------------------------------------
- note: count_rules_missing_array
policy_rule: |
{
"if": {
"count": {
"field": "Microsoft.Test/complexResources/rules[*]"
},
"equals": 0
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
enabled: true
want_effect: "Deny"
# -----------------------------------------------------------------------
# 26. Sub-resource where accessing root-level field (name on element)
# The "name" field lives at the element root, not under properties.
# -----------------------------------------------------------------------
- note: count_rules_where_name_field
policy_rule: |
{
"if": {
"count": {
"field": "Microsoft.Test/complexResources/rules[*]",
"where": {
"field": "Microsoft.Test/complexResources/rules[*].name",
"like": "allow*"
}
},
"equals": 2
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
rules:
- name: allowHTTPS
properties:
action: "Allow"
- name: allowHTTP
properties:
action: "Allow"
- name: denySSH
properties:
action: "Deny"
want_effect: "Deny"
# -----------------------------------------------------------------------
# 27. Mixed: scalar alias AND count in allOf
# -----------------------------------------------------------------------
- note: enabled_and_rule_count_allOf
policy_rule: |
{
"if": {
"allOf": [
{ "field": "Microsoft.Test/complexResources/enabled", "equals": true },
{
"count": {
"field": "Microsoft.Test/complexResources/rules[*]",
"where": {
"field": "Microsoft.Test/complexResources/rules[*].action",
"equals": "Allow"
}
},
"greater": 3
}
]
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
enabled: true
rules:
- name: r1
properties: { action: "Allow" }
- name: r2
properties: { action: "Allow" }
- name: r3
properties: { action: "Allow" }
- name: r4
properties: { action: "Allow" }
want_effect: "Deny"
- note: enabled_false_short_circuits
policy_rule: |
{
"if": {
"allOf": [
{ "field": "Microsoft.Test/complexResources/enabled", "equals": true },
{
"count": {
"field": "Microsoft.Test/complexResources/rules[*]",
"where": {
"field": "Microsoft.Test/complexResources/rules[*].action",
"equals": "Allow"
}
},
"greater": 0
}
]
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
enabled: false
rules:
- name: r1
properties: { action: "Allow" }
want_undefined: true
# -----------------------------------------------------------------------
# 28. Count in not — negated sub-resource count
# -----------------------------------------------------------------------
- note: not_count_rules
policy_rule: |
{
"if": {
"not": {
"count": {
"field": "Microsoft.Test/complexResources/rules[*]"
},
"lessOrEquals": 2
}
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
rules:
- name: r1
properties: { action: "Allow" }
- name: r2
properties: { action: "Allow" }
- name: r3
properties: { action: "Deny" }
want_effect: "Deny"
# -----------------------------------------------------------------------
# 29. Sub-resource element without properties wrapper
# Some elements may just have top-level fields, no properties.
# The normalizer should handle this gracefully.
# -----------------------------------------------------------------------
- note: sub_resource_no_properties_wrapper
policy_rule: |
{
"if": {
"count": {
"field": "Microsoft.Test/complexResources/rules[*]",
"where": {
"field": "Microsoft.Test/complexResources/rules[*].name",
"equals": "direct"
}
},
"greater": 0
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
rules:
- name: "direct"
action: "Allow"
want_effect: "Deny"
# -----------------------------------------------------------------------
# 30. Deep nesting: allOf > anyOf > not > count
# -----------------------------------------------------------------------
- note: deep_logical_with_count
policy_rule: |
{
"if": {
"allOf": [
{ "field": "type", "equals": "Microsoft.Test/complexResources" },
{
"anyOf": [
{
"not": {
"count": {
"field": "Microsoft.Test/complexResources/rules[*]",
"where": {
"field": "Microsoft.Test/complexResources/rules[*].action",
"equals": "Deny"
}
},
"greaterOrEquals": 1
}
}
]
}
]
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
rules:
- name: r1
properties:
action: "Allow"
- name: r2
properties:
action: "Allow"
want_effect: "Deny"
- note: deep_logical_with_count_has_deny
policy_rule: |
{
"if": {
"allOf": [
{ "field": "type", "equals": "Microsoft.Test/complexResources" },
{
"anyOf": [
{
"not": {
"count": {
"field": "Microsoft.Test/complexResources/rules[*]",
"where": {
"field": "Microsoft.Test/complexResources/rules[*].action",
"equals": "Deny"
}
},
"greaterOrEquals": 1
}
}
]
}
]
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
rules:
- name: r1
properties:
action: "Allow"
- name: r2
properties:
action: "Deny"
want_undefined: true
# -----------------------------------------------------------------------
# 31. Missing field in sub-resource element — exists false
# -----------------------------------------------------------------------
- note: exists_false_in_sub_resource
policy_rule: |
{
"if": {
"count": {
"field": "Microsoft.Test/complexResources/rules[*]",
"where": {
"field": "Microsoft.Test/complexResources/rules[*].protocol",
"exists": false
}
},
"greater": 0
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
rules:
- name: r1
properties:
action: "Allow"
protocol: "Tcp"
- name: r2
properties:
action: "Deny"
want_effect: "Deny"
- note: exists_true_in_sub_resource_all_present
policy_rule: |
{
"if": {
"count": {
"field": "Microsoft.Test/complexResources/rules[*]",
"where": {
"field": "Microsoft.Test/complexResources/rules[*].protocol",
"exists": false
}
},
"equals": 0
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
rules:
- name: r1
properties:
action: "Allow"
protocol: "Tcp"
- name: r2
properties:
action: "Deny"
protocol: "Udp"
want_effect: "Deny"
# -----------------------------------------------------------------------
# 32. Versioned sub-resource field: rules[*].priority
# Old API (2015): properties.rules[*].properties.priority
# New API (2020): properties.rules[*].properties.prio
# The "priority" alias always maps to a field under the element's
# properties wrapper — the difference is the field NAME changes
# across versions.
#
# NOTE: Versioned paths for sub-resource element fields are handled
# at the structural level (the alias defines the full ARM path).
# After normalization, the alias short name "priority" should resolve
# correctly. We place DIFFERENT values at "priority" vs "prio" in the
# elements to test path selection.
# -----------------------------------------------------------------------
# Versioned sub-resource element fields use per-element alias resolution
# during normalization. After structural flattening, the normalizer remaps
# element-level field names when the selected API path differs from the
# alias short name (e.g., "prio" → "priority" for new API versions).
- note: rules_priority_old_api
policy_rule: |
{
"if": {
"count": {
"field": "Microsoft.Test/complexResources/rules[*]",
"where": {
"field": "Microsoft.Test/complexResources/rules[*].priority",
"greater": 100
}
},
"greater": 0
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
rules:
- name: r1
properties:
priority: 200
prio: 50
api_version: "2015-01-01"
want_effect: "Deny"
- note: rules_priority_new_api
policy_rule: |
{
"if": {
"count": {
"field": "Microsoft.Test/complexResources/rules[*]",
"where": {
"field": "Microsoft.Test/complexResources/rules[*].priority",
"greater": 100
}
},
"greater": 0
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
rules:
- name: r1
properties:
priority: 50
prio: 200
api_version: "2020-01-01"
want_effect: "Deny"
# -----------------------------------------------------------------------
# 33. Three-level nesting: allOf > count(rules) > where > count(filters)
# > where > allOf (filter name + value)
# -----------------------------------------------------------------------
- note: three_level_nesting_count_in_allof
policy_rule: |
{
"if": {
"allOf": [
{ "field": "type", "equals": "Microsoft.Test/complexResources" },
{ "field": "Microsoft.Test/complexResources/enabled", "equals": true },
{
"count": {
"field": "Microsoft.Test/complexResources/rules[*]",
"where": {
"allOf": [
{ "field": "Microsoft.Test/complexResources/rules[*].action", "equals": "Allow" },
{
"count": {
"field": "Microsoft.Test/complexResources/rules[*].filters[*]",
"where": {
"allOf": [
{ "field": "Microsoft.Test/complexResources/rules[*].filters[*].name", "equals": "protocol" },
{ "field": "Microsoft.Test/complexResources/rules[*].filters[*].value", "equals": "tcp" }
]
}
},
"greater": 0
}
]
}
},
"greater": 0
}
]
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
enabled: true
rules:
- name: r1
properties:
action: "Allow"
filters:
- properties:
name: "protocol"
value: "tcp"
- properties:
name: "source-ip"
value: "10.0.0.0/8"
- name: r2
properties:
action: "Deny"
filters:
- properties:
name: "protocol"
value: "udp"
want_effect: "Deny"
- note: three_level_nesting_enabled_false
policy_rule: |
{
"if": {
"allOf": [
{ "field": "type", "equals": "Microsoft.Test/complexResources" },
{ "field": "Microsoft.Test/complexResources/enabled", "equals": true },
{
"count": {
"field": "Microsoft.Test/complexResources/rules[*]",
"where": {
"count": {
"field": "Microsoft.Test/complexResources/rules[*].filters[*]"
},
"greater": 0
}
},
"greater": 0
}
]
},
"then": { "effect": "Deny" }
}
resource:
type: Microsoft.Test/complexResources
name: myResource
properties:
enabled: false
rules:
- name: r1
properties:
action: "Allow"
filters:
- properties: { name: "x", value: "y" }
want_undefined: true