Files
regorus/tests/azure_policy/cases/count.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

618 lines
16 KiB
YAML

# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
# Count Expressions Test Suite
# Tests field count and value count with optional where clauses and name bindings.
cases:
# =========================================================================
# Field count — direct path (core subset, no alias resolution)
# =========================================================================
- note: field_count_direct_path_core
policy_rule: |
{
"if": {
"count": {
"field": "securityRules[*]"
},
"greater": 2
},
"then": { "effect": "deny" }
}
resource:
securityRules:
- { "name": "r1" }
- { "name": "r2" }
- { "name": "r3" }
want_effect: "deny"
- note: field_count_direct_path_where_core
policy_rule: |
{
"if": {
"count": {
"field": "securityRules[*]",
"where": {
"field": "securityRules[*].access",
"equals": "Allow"
}
},
"equals": 2
},
"then": { "effect": "audit" }
}
resource:
securityRules:
- { "access": "Allow" }
- { "access": "Deny" }
- { "access": "Allow" }
want_effect: "audit"
# =========================================================================
# Field count — basic
# =========================================================================
- note: field_count_basic
policy_rule: |
{
"if": {
"count": {
"field": "securityRules[*]"
},
"greater": 10
},
"then": { "effect": "deny" }
}
resource:
type: "Microsoft.Network/networkSecurityGroups"
securityRules:
- { "name": "r1" }
- { "name": "r2" }
- { "name": "r3" }
- { "name": "r4" }
- { "name": "r5" }
- { "name": "r6" }
- { "name": "r7" }
- { "name": "r8" }
- { "name": "r9" }
- { "name": "r10" }
- { "name": "r11" }
want_effect: "deny"
- note: field_count_equals_zero
policy_rule: |
{
"if": {
"count": {
"field": "storageProfile.dataDisks[*]"
},
"equals": 0
},
"then": { "effect": "audit" }
}
resource:
type: "Microsoft.Compute/virtualMachines"
want_effect: "audit"
# =========================================================================
# Field count — with where clause
# =========================================================================
- note: field_count_with_where
policy_rule: |
{
"if": {
"count": {
"field": "securityRules[*]",
"where": {
"field": "securityRules[*].access",
"equals": "Allow"
}
},
"greater": 5
},
"then": { "effect": "deny" }
}
resource:
type: "Microsoft.Network/networkSecurityGroups"
securityRules:
- { "access": "Allow" }
- { "access": "Allow" }
- { "access": "Allow" }
- { "access": "Allow" }
- { "access": "Allow" }
- { "access": "Allow" }
want_effect: "deny"
- note: field_count_where_allOf
policy_rule: |
{
"if": {
"count": {
"field": "securityRules[*]",
"where": {
"allOf": [
{
"field": "securityRules[*].access",
"equals": "Allow"
},
{
"field": "securityRules[*].direction",
"equals": "Inbound"
}
]
}
},
"greaterOrEquals": 1
},
"then": { "effect": "deny" }
}
resource:
type: "Microsoft.Network/networkSecurityGroups"
securityRules:
- { "access": "Allow", "direction": "Inbound" }
- { "access": "Deny", "direction": "Outbound" }
want_effect: "deny"
- note: field_count_where_anyOf
policy_rule: |
{
"if": {
"count": {
"field": "securityRules[*]",
"where": {
"anyOf": [
{
"field": "securityRules[*].destinationPortRange",
"equals": "22"
},
{
"field": "securityRules[*].destinationPortRange",
"equals": "3389"
}
]
}
},
"notEquals": 0
},
"then": { "effect": "deny" }
}
resource:
type: "Microsoft.Network/networkSecurityGroups"
securityRules:
- { "destinationPortRange": "22" }
- { "destinationPortRange": "443" }
want_effect: "deny"
- note: field_count_where_not
policy_rule: |
{
"if": {
"count": {
"field": "securityRules[*]",
"where": {
"not": {
"field": "securityRules[*].access",
"equals": "Deny"
}
}
},
"greater": 0
},
"then": { "effect": "audit" }
}
resource:
type: "Microsoft.Network/networkSecurityGroups"
securityRules:
- { "access": "Allow" }
- { "access": "Deny" }
want_effect: "audit"
# =========================================================================
# Value count
# =========================================================================
- note: value_count_basic
policy_rule: |
{
"if": {
"count": {
"value": ["eastus", "westus", "centralus"]
},
"equals": 3
},
"then": { "effect": "audit" }
}
resource:
type: "any"
want_effect: "audit"
- note: value_count_with_name
policy_rule: |
{
"if": {
"count": {
"value": ["eastus", "westus", "centralus"],
"name": "location"
},
"greater": 0
},
"then": { "effect": "audit" }
}
resource:
type: "any"
want_effect: "audit"
- note: value_count_with_name_and_where
policy_rule: |
{
"if": {
"count": {
"value": ["eastus", "westus", "centralus", "northeurope"],
"name": "loc",
"where": {
"value": "[current('loc')]",
"like": "*us"
}
},
"equals": 3
},
"then": { "effect": "audit" }
}
resource:
type: "any"
want_effect: "audit"
- note: value_count_expression
policy_rule: |
{
"if": {
"count": {
"value": "[parameters('allowedLocations')]",
"name": "loc"
},
"greater": 0
},
"then": { "effect": "audit" }
}
parameters:
allowedLocations:
- "eastus"
- "westus"
resource:
type: "any"
want_effect: "audit"
# =========================================================================
# Count in allOf/anyOf
# =========================================================================
- note: count_in_allOf
policy_rule: |
{
"if": {
"allOf": [
{ "field": "type", "equals": "Microsoft.Network/networkSecurityGroups" },
{
"count": {
"field": "securityRules[*]",
"where": {
"field": "securityRules[*].access",
"equals": "Allow"
}
},
"greater": 10
}
]
},
"then": { "effect": "deny" }
}
resource:
type: "Microsoft.Network/networkSecurityGroups"
securityRules:
- { "access": "Allow" }
- { "access": "Allow" }
- { "access": "Allow" }
- { "access": "Allow" }
- { "access": "Allow" }
- { "access": "Allow" }
- { "access": "Allow" }
- { "access": "Allow" }
- { "access": "Allow" }
- { "access": "Allow" }
- { "access": "Allow" }
want_effect: "deny"
- note: count_in_not
policy_rule: |
{
"if": {
"not": {
"count": {
"field": "storageProfile.dataDisks[*]"
},
"lessOrEquals": 4
}
},
"then": { "effect": "deny" }
}
resource:
type: "Microsoft.Compute/virtualMachines"
storageProfile:
dataDisks:
- { "name": "d1" }
- { "name": "d2" }
- { "name": "d3" }
- { "name": "d4" }
- { "name": "d5" }
want_effect: "deny"
# =========================================================================
# Count with nested where containing count
# =========================================================================
- note: value_count_nested_where
policy_rule: |
{
"if": {
"count": {
"value": "[parameters('requiredTags')]",
"name": "tag",
"where": {
"field": "[concat('tags[', current('tag'), ']')]",
"exists": true
}
},
"notEquals": "[length(parameters('requiredTags'))]"
},
"then": { "effect": "deny" }
}
parameters:
requiredTags:
- "environment"
- "costCenter"
resource:
type: "Microsoft.Compute/virtualMachines"
tags:
environment: "prod"
want_effect: "deny"
# =========================================================================
# Alias field refs inside count resolve to current loop element
# =========================================================================
- note: field_count_multiple_alias_refs_same_element
policy_rule: |
{
"if": {
"count": {
"field": "securityRules[*]",
"where": {
"allOf": [
{ "field": "securityRules[*].access", "equals": "Allow" },
{ "field": "securityRules[*].direction", "equals": "Inbound" },
{ "field": "securityRules[*].protocol", "equals": "Tcp" }
]
}
},
"equals": 1
},
"then": { "effect": "audit" }
}
resource:
securityRules:
- { "access": "Allow", "direction": "Inbound", "protocol": "Tcp" }
- { "access": "Allow", "direction": "Outbound", "protocol": "Tcp" }
- { "access": "Deny", "direction": "Inbound", "protocol": "Tcp" }
want_effect: "audit"
- note: field_count_nested_field_access
policy_rule: |
{
"if": {
"count": {
"field": "storageProfile.dataDisks[*]",
"where": {
"field": "storageProfile.dataDisks[*].managedDisk.storageAccountType",
"notEquals": "Premium_LRS"
}
},
"greater": 0
},
"then": { "effect": "deny" }
}
resource:
storageProfile:
dataDisks:
- { "name": "d1", "managedDisk": { "storageAccountType": "Premium_LRS" } }
- { "name": "d2", "managedDisk": { "storageAccountType": "Standard_LRS" } }
want_effect: "deny"
- note: field_count_where_zero_matches
policy_rule: |
{
"if": {
"count": {
"field": "items[*]",
"where": {
"field": "items[*].status",
"equals": "failed"
}
},
"equals": 0
},
"then": { "effect": "audit" }
}
resource:
items:
- { "status": "ok" }
- { "status": "ok" }
- { "status": "ok" }
want_effect: "audit"
# =========================================================================
# Nested count: count inside another count's where clause
# =========================================================================
- note: nested_field_and_value_count
policy_rule: |
{
"if": {
"count": {
"value": "[parameters('requiredPorts')]",
"name": "port",
"where": {
"count": {
"field": "securityRules[*]",
"where": {
"allOf": [
{ "field": "securityRules[*].destinationPortRange", "equals": "[current('port')]" },
{ "field": "securityRules[*].access", "equals": "Allow" }
]
}
},
"greater": 0
}
},
"equals": "[length(parameters('requiredPorts'))]"
},
"then": { "effect": "audit" }
}
parameters:
requiredPorts:
- "443"
- "80"
resource:
securityRules:
- { "destinationPortRange": "443", "access": "Allow" }
- { "destinationPortRange": "80", "access": "Allow" }
- { "destinationPortRange": "22", "access": "Deny" }
want_effect: "audit"
- note: nested_field_and_value_count_fail
policy_rule: |
{
"if": {
"count": {
"value": "[parameters('requiredPorts')]",
"name": "port",
"where": {
"count": {
"field": "securityRules[*]",
"where": {
"allOf": [
{ "field": "securityRules[*].destinationPortRange", "equals": "[current('port')]" },
{ "field": "securityRules[*].access", "equals": "Allow" }
]
}
},
"greater": 0
}
},
"equals": "[length(parameters('requiredPorts'))]"
},
"then": { "effect": "deny" }
}
parameters:
requiredPorts:
- "443"
- "80"
- "8080"
resource:
securityRules:
- { "destinationPortRange": "443", "access": "Allow" }
- { "destinationPortRange": "80", "access": "Allow" }
- { "destinationPortRange": "22", "access": "Deny" }
want_effect: ~
# =========================================================================
# current() — zero-arg form (innermost count element)
# =========================================================================
- note: current_zero_arg_value_count
policy_rule: |
{
"if": {
"count": {
"value": ["Allow", "Allow", "Deny"],
"name": "access",
"where": {
"value": "[current()]",
"equals": "Allow"
}
},
"equals": 2
},
"then": { "effect": "deny" }
}
resource:
type: "any"
want_effect: "deny"
- note: current_zero_arg_field_count
policy_rule: |
{
"if": {
"count": {
"field": "items[*]",
"where": {
"value": "[current()]",
"equals": "yes"
}
},
"equals": 2
},
"then": { "effect": "deny" }
}
resource:
items: ["yes", "no", "yes"]
want_effect: "deny"
- note: current_zero_arg_with_function
policy_rule: |
{
"if": {
"count": {
"value": ["HELLO", "WORLD"],
"name": "word",
"where": {
"value": "[startsWith(current(), 'HE')]",
"equals": true
}
},
"equals": 1
},
"then": { "effect": "deny" }
}
resource:
type: "any"
want_effect: "deny"
- note: current_zero_arg_nested_innermost
policy_rule: |
{
"if": {
"count": {
"value": ["a", "b"],
"name": "outer",
"where": {
"count": {
"value": ["x", "y"],
"name": "inner",
"where": {
"value": "[current()]",
"equals": "x"
}
},
"greater": 0
}
},
"greater": 0
},
"then": { "effect": "deny" }
}
resource:
type: "any"
want_effect: "deny"