(* Azure Policy grammar. * * All key matching is case-insensitive. JSON object keys are unordered, * so the ordering shown below is for readability only. *) (* ================================================================ * Policy rule & then block * NOTE: Keys may appear in any order; extra keys may appear between * the recognized ones. The ordering below is illustrative. * ================================================================ *) policy-rule ::= '{' '"if"' ':' constraint ',' '"then"' ':' then-block (',' STRING ':' json-value)* '}' then-block ::= '{' '"effect"' ':' STRING (',' '"details"' ':' json-value)? '}' (* ================================================================ * Constraints * ================================================================ *) constraint ::= allOf | anyOf | not | condition allOf ::= '{' '"allOf"' ':' '[' (constraint (',' constraint)*)? ']' '}' anyOf ::= '{' '"anyOf"' ':' '[' (constraint (',' constraint)*)? ']' '}' not ::= '{' '"not"' ':' constraint '}' (* Keys within a condition are unordered; exactly one lhs-entry and one * op-entry are required. *) condition ::= '{' lhs-entry ',' op-entry '}' lhs-entry ::= field | value-lhs | count field ::= '"field"' ':' string-value value-lhs ::= '"value"' ':' json-value op-entry ::= operator ':' json-value operator ::= '"contains"' | '"containsKey"' | '"equals"' | '"notEquals"' | '"greater"' | '"greaterOrEquals"' | '"less"' | '"lessOrEquals"' | '"exists"' | '"in"' | '"notIn"' | '"like"' | '"notLike"' | '"match"' | '"matchInsensitively"' | '"notMatch"' | '"notMatchInsensitively"' | '"notContains"' | '"notContainsKey"' (* ================================================================ * Count expressions * ================================================================ *) count ::= '"count"' ':' count-inner count-inner ::= count-field | count-value count-field ::= '{' field (',' where)? '}' count-value ::= '{' value-lhs (',' '"name"' ':' STRING)? (',' where)? '}' where ::= '"where"' ':' constraint (* ================================================================ * JSON values & template expressions * ================================================================ *) string-value ::= STRING | '"[' string-expr ']"' json-value ::= STRING | NUMBER | BOOL | NULL | array | object | '"[' string-expr ']"' array ::= '[' (json-value (',' json-value)*)? ']' object ::= '{' (STRING ':' json-value (',' STRING ':' json-value)*)? '}' (* ================================================================ * ARM template expression sub-grammar * ================================================================ *) string-expr ::= NUMBER | STRING | '-' string-expr | complex-expr complex-expr ::= IDENT | complex-expr '.' IDENT | complex-expr '(' (string-expr (',' string-expr)*)? ')' | complex-expr '[' string-expr ']'