Azure 原則定義結構原則規則
原則規則包含 if
和 then
區塊。 在 if
區塊中,您可以定義一個或多個條件,指定何時強制執行原則。 您可以將邏輯運算子套用至這些條件,以精確地定義原則的案例。
如需每個效果、評估順序、屬性和範例的完整詳細資料,請參閱 Azure 原則定義效果基本資料。
在 then
區塊中,您可以定義當 if
條件滿足時發生的效果。
{
"if": {
<condition> | <logical operator>
},
"then": {
"effect": "deny | audit | modify | denyAction | append | auditIfNotExists | deployIfNotExists | disabled"
}
}
如需 policyRule 的詳細資訊,請移至原則定義結構描述。
邏輯運算子
支援的邏輯運算子包括︰
"not": {condition or operator}
"allOf": [{condition or operator},{condition or operator}]
"anyOf": [{condition or operator},{condition or operator}]
not
語法會反轉條件的結果。 allOf
語法 (類似於邏輯 and
作業) 需要所有條件都為 true。 anyOf
語法 (類似於邏輯 or
作業) 需要一或多個條件為 true。
您可以巢狀邏輯運算子。 下列範例顯示 allOf
作業內變成巢狀的 not
作業。
"if": {
"allOf": [
{
"not": {
"field": "tags",
"containsKey": "application"
}
},
{
"field": "type",
"equals": "Microsoft.Storage/storageAccounts"
}
]
},
條件
條件會評估值是否符合特定準則。 支援的條件如下︰
"equals": "stringValue"
"notEquals": "stringValue"
"like": "stringValue"
"notLike": "stringValue"
"match": "stringValue"
"matchInsensitively": "stringValue"
"notMatch": "stringValue"
"notMatchInsensitively": "stringValue"
"contains": "stringValue"
"notContains": "stringValue"
"in": ["stringValue1","stringValue2"]
"notIn": ["stringValue1","stringValue2"]
"containsKey": "keyName"
"notContainsKey": "keyName"
"less": "dateValue"
|"less": "stringValue"
|"less": intValue
"lessOrEquals": "dateValue"
|"lessOrEquals": "stringValue"
|"lessOrEquals": intValue
"greater": "dateValue"
|"greater": "stringValue"
|"greater": intValue
"greaterOrEquals": "dateValue"
|"greaterOrEquals": "stringValue"
|"greaterOrEquals": intValue
"exists": "bool"
對於 less
、lessOrEquals
、greater
和 greaterOrEquals
,如果屬性類型不符合條件類型,則會擲回錯誤。 字串比較是使用 InvariantCultureIgnoreCase
進行。
使用 like
和 notLike
條件時,您會在值中提供萬用字元 (*
)。 此值不應具有多個萬用字元。
使用 match
和 notMatch
條件時,請提供雜湊標記 (#
) 來比對數字、問號 (?
) 表示一個字母和點 (.
) 來比對任何字元,以及任何其他字元來比對該實際字元。 雖然 match
和 notMatch
會區分大小寫,但評估 stringValue
的所有其他條件都不會區分大小寫。 matchInsensitively
和 notMatchInsensitively
中可以使用不區分大小寫的替代方案。
欄位
在資源要求承載中評估屬性值是否符合特定準則的條件,可以使用 field
運算式構成。 支援下列欄位:
name
fullName
- 傳回資源的完整名稱。 資源的完整名稱是資源名稱前面加上任何父系資源名稱 (例如
myServer/myDatabase
)。
- 傳回資源的完整名稱。 資源的完整名稱是資源名稱前面加上任何父系資源名稱 (例如
kind
type
location
- 為支援各種格式,位置欄位會標準化。 例如,
East US 2
視為等於eastus2
。 - 針對不受特定位置限制的資源,請使用 global。
- 為支援各種格式,位置欄位會標準化。 例如,
id
- 傳回目前評估資源的資源識別碼。
- 範例:
/subscriptions/11111111-1111-1111-1111-111111111111/resourceGroups/myRG/providers/Microsoft.KeyVault/vaults/myVault
identity.type
- 傳回資源上所啟用受控識別的類型。
tags
tags['<tagName>']
- 此括號語法支援具有連字號、句號或空格等標點符號的標籤名稱。
- 其中
tagName
是進行條件驗證的標籤名稱。 - 範例:
tags['Acct.CostCenter']
,其中Acct.CostCenter
是標籤的名稱。
tags['''<tagName>''']
- 此括號語法能透過以雙引號進行逸出,來支援具有單引號的標籤名稱。
- 其中
tagName
是進行條件驗證的標籤名稱。 - 範例:
tags['''My.Apostrophe.Tag''']
,其中'My.Apostrophe.Tag'
是標籤的名稱。
注意
tags.<tagName>
、tags[tagName]
和tags[tag.with.dots]
都仍是可接受的宣告標籤欄位方式。 不過,建議的運算式為上面所列的運算式。屬性別名 - 如需清單,請參閱別名。
注意
在參考陣列別名
[*]
的field
運算式中,陣列中的每個元素都會透過在元素之間的邏輯and
進行個別評估。 如需詳細資訊,請參閱參考陣列資源屬性。
使用 field
運算式的條件可以取代舊版原則定義語法 "source": "action"
,而舊版原則定義語法原本是用於寫入作業。 例如,已不再支援此專案:
{
"source": "action",
"like": "Microsoft.Network/publicIPAddresses/*"
}
但可以使用 field
邏輯來達成所需的行為:
{
"field": "type",
"equals": "Microsoft.Network/publicIPAddresses"
}
搭配參數使用標籤
可以將參數值傳遞到標籤欄位。 將參數傳遞到標籤欄位能在原則指派期間提升原則定義的彈性。
在下列範例中,concat
用來為名稱為 tagName
參數值的標籤建立標籤欄位查詢。 如果該標籤不存在,modify
效果是用來透過使用 resourcegroup()
函式查詢來新增標籤,此標籤會使用已稽核資源父資源群組上相同具名標籤集的值。
{
"if": {
"field": "[concat('tags[', parameters('tagName'), ']')]",
"exists": "false"
},
"then": {
"effect": "modify",
"details": {
"operations": [
{
"operation": "add",
"field": "[concat('tags[', parameters('tagName'), ']')]",
"value": "[resourcegroup().tags[parameters('tagName')]]"
}
],
"roleDefinitionIds": [
"/providers/microsoft.authorization/roleDefinitions/4a9ae827-6dc8-4573-8ac7-8239d42aa03f"
]
}
}
}
值
評估值是否符合特定準則的條件可以使用 value
運算式構成。 值可以是常值、參數的值,或任何支援的範本函式傳回的值。
警告
如果「範本函式」的結果為錯誤,則原則評估會失敗。 失敗的評估是隱含的 deny
。 如需詳細資訊,請參閱避免範本錯誤。 使用 doNotEnforce
的 enforcementMode,以防止在測試和驗證新的原則定義時,由於新的或更新的資源評估失敗而受到影響。
Value 範例
此原則規則範例使用 value
,將 resourceGroup()
函式的結果和傳回的 name
屬性與 *netrg
的 like
條件進行比較。 在名稱結尾為 *netrg
的任何資源群組中,規則會拒絕不屬於 Microsoft.Network/*
type
的任何資源。
{
"if": {
"allOf": [
{
"value": "[resourceGroup().name]",
"like": "*netrg"
},
{
"field": "type",
"notLike": "Microsoft.Network/*"
}
]
},
"then": {
"effect": "deny"
}
}
此原則規則範例使用 value
,檢查多個巢狀函式的結果是否 equals
true
。 規則會拒絕沒有至少三個標籤的任何資源。
{
"mode": "indexed",
"policyRule": {
"if": {
"value": "[less(length(field('tags')), 3)]",
"equals": "true"
},
"then": {
"effect": "deny"
}
}
}
避免範本失敗
在 value
中使用「範本函式」允許很多複雜的巢狀函式。 如果「範本函式」的結果為錯誤,則原則評估會失敗。 失敗的評估是隱含的 deny
。 在特定情況下失敗的 value
範例:
{
"policyRule": {
"if": {
"value": "[substring(field('name'), 0, 3)]",
"equals": "abc"
},
"then": {
"effect": "audit"
}
}
}
上述範例原則規則使用 substring(),將 name
的前三個字元與 abc
進行比較。 如果 name
短於三個字元,substring()
函式會導致錯誤發生。 此錯誤會導致原則變成 deny
效果。
請改用 if() 函式來檢查 name
的前三個字元是否等於 abc
,不允許 name
短於三個個字元,這會導致錯誤發生:
{
"policyRule": {
"if": {
"value": "[if(greaterOrEquals(length(field('name')), 3), substring(field('name'), 0, 3), 'not starting with abc')]",
"equals": "abc"
},
"then": {
"effect": "audit"
}
}
}
透過已修訂的原則規則,if()
會先檢查 name
的長度,然後嘗試在少於三個字元的值上取得 substring()
。 如果 name
太短,則會改為傳回「不是以 abc 開頭」一值,並與 abc
進行比較。 簡短名稱開頭不是 abc
的資源仍會使原則規則失敗,但在評估期間不再導致錯誤發生。
計數
計算多少陣列成員符合特定準則的條件可以使用 count
運算式構成。 常見的案例是檢查「至少一個」、「只有一個」、「全部」或「沒有一個」陣列成員符合條件。 count
會評估條件運算式的每個陣列成員,並加總 true 結果,然後與運算式運算子進行比較。
欄位計數
計數要求承載中有多少陣列的成員符合條件運算式。 field count
運算式的結構為:
{
"count": {
"field": "<[*] alias>",
"where": {
/* condition expression */
}
},
"<condition>": "<compare the count of true condition expression array members to this value>"
}
下列屬性會與 field count
搭配使用:
count.field
(必要):包含陣列的路徑,而且必須是陣列別名。count.where
(選用):要針對count.field
的每個陣列別名陣列成員進行個別評估的條件運算式。 如果未提供這個屬性,「欄位」路徑的所有陣列成員都會評估為 true。 任何條件都可以在此屬性內使用。 邏輯運算子可以在此屬性內使用,以建立複雜的評估需求。condition
(必要):此值會與符合count.where
條件運算式的項目數進行比較。 應該使用數值條件。
如需如何在 Azure 原則中使用陣列屬性的詳細資料,包括如何評估 field count
運算式的詳細說明,請參閱參考陣列資源屬性。
值計數
計算陣列符合條件的成員數目。 陣列可以是常值陣列或陣列參數的參考。 value count
運算式的結構為:
{
"count": {
"value": "<literal array | array parameter reference>",
"name": "<index name>",
"where": {
/* condition expression */
}
},
"<condition>": "<compare the count of true condition expression array members to this value>"
}
下列屬性會與 value count
搭配使用:
count.value
(必要):要評估的陣列。count.name
(必要):索引名稱,由英文字母和數字組成。 定義目前反覆運算中評估的陣列成員值的名稱。 名稱用來參考count.where
條件中目前的值。 當count
運算式不在另一個count
運算式的子項目中時,即為選用。 未提供時,索引名稱會隱含地設為"default"
。count.where
(選用):要針對count.value
的每個陣列成員進行個別評估的條件運算式。 如果未提供此屬性,所有陣列成員都會評估為 true。 任何條件都可以在此屬性內使用。 邏輯運算子可以在此屬性內使用,以建立複雜的評估需求。 呼叫目前的函式,即可存取目前列舉的陣列成員值。condition
(必要):此值會與符合count.where
條件運算式的項目數進行比較。 應該使用數值條件。
目前的函式
current()
函式只能在 count.where
條件中使用。 其會傳回 count
運算式評估目前列舉的陣列成員值。
值計數使用量
current(<index name defined in count.name>)
. 例如:current('arrayMember')
。current()
. 僅在value count
運算式不是另一個count
運算式的子項目時才允許。 傳回與上述相同的值。
如果呼叫傳回的值是物件,即支援屬性存取子。 例如: current('objectArrayMember').property
。
欄位計數使用量
current(<the array alias defined in count.field>)
. 例如:current('Microsoft.Test/resource/enumeratedArray[*]')
。current()
. 僅在field count
運算式不是另一個count
運算式的子項目時才允許。 傳回與上述相同的值。current(<alias of a property of the array member>)
. 例如:current('Microsoft.Test/resource/enumeratedArray[*].property')
。
欄位計數範例
範例 1: 檢查陣列是否為空白
{
"count": {
"field": "Microsoft.Network/networkSecurityGroups/securityRules[*]"
},
"equals": 0
}
範例 2: 檢查是否只有一個陣列成員符合條件運算式
{
"count": {
"field": "Microsoft.Network/networkSecurityGroups/securityRules[*]",
"where": {
"field": "Microsoft.Network/networkSecurityGroups/securityRules[*].description",
"equals": "My unique description"
}
},
"equals": 1
}
範例 3: 檢查是否至少有一個陣列成員符合條件運算式
{
"count": {
"field": "Microsoft.Network/networkSecurityGroups/securityRules[*]",
"where": {
"field": "Microsoft.Network/networkSecurityGroups/securityRules[*].description",
"equals": "My common description"
}
},
"greaterOrEquals": 1
}
範例 4: 檢查是否所有物件陣列成員都符合條件運算式
{
"count": {
"field": "Microsoft.Network/networkSecurityGroups/securityRules[*]",
"where": {
"field": "Microsoft.Network/networkSecurityGroups/securityRules[*].description",
"equals": "description"
}
},
"equals": "[length(field('Microsoft.Network/networkSecurityGroups/securityRules[*]'))]"
}
範例 5:檢查至少有一個陣列成員符合條件運算式中的多個屬性
{
"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[*].destinationPortRange",
"equals": "3389"
}
]
}
},
"greater": 0
}
範例 6:在 where
條件中使用 current()
函式,存取範本函式中目前列舉的陣列成員值。 此條件會檢查虛擬網路是否包含不在 10.0.0.0/24 CIDR 範圍的位址首碼。
{
"count": {
"field": "Microsoft.Network/virtualNetworks/addressSpace.addressPrefixes[*]",
"where": {
"value": "[ipRangeContains('10.0.0.0/24', current('Microsoft.Network/virtualNetworks/addressSpace.addressPrefixes[*]'))]",
"equals": false
}
},
"greater": 0
}
範例 7:在 where
條件中使用 field()
函式,存取目前列舉的陣列成員值。 此條件會檢查虛擬網路是否包含不在 10.0.0.0/24 CIDR 範圍的位址首碼。
{
"count": {
"field": "Microsoft.Network/virtualNetworks/addressSpace.addressPrefixes[*]",
"where": {
"value": "[ipRangeContains('10.0.0.0/24', first(field(('Microsoft.Network/virtualNetworks/addressSpace.addressPrefixes[*]')))]",
"equals": false
}
},
"greater": 0
}
值計數範例
範例 1:檢查資源名稱是否符合任何指定的名稱模式。
{
"count": {
"value": [
"prefix1_*",
"prefix2_*"
],
"name": "pattern",
"where": {
"field": "name",
"like": "[current('pattern')]"
}
},
"greater": 0
}
範例 2:檢查資源名稱是否符合任何指定的名稱模式。 current()
函式不會指定索引名稱。 結果與上述範例相同。
{
"count": {
"value": [
"prefix1_*",
"prefix2_*"
],
"where": {
"field": "name",
"like": "[current()]"
}
},
"greater": 0
}
範例 3:檢查資源名稱是否符合陣列參數提供的任何指定名稱模式。
{
"count": {
"value": "[parameters('namePatterns')]",
"name": "pattern",
"where": {
"field": "name",
"like": "[current('pattern')]"
}
},
"greater": 0
}
範例 4:檢查是否有任何虛擬網路位址首碼,不在核准的首碼清單中。
{
"count": {
"field": "Microsoft.Network/virtualNetworks/addressSpace.addressPrefixes[*]",
"where": {
"count": {
"value": "[parameters('approvedPrefixes')]",
"name": "approvedPrefix",
"where": {
"value": "[ipRangeContains(current('approvedPrefix'), current('Microsoft.Network/virtualNetworks/addressSpace.addressPrefixes[*]'))]",
"equals": true
},
},
"equals": 0
}
},
"greater": 0
}
範例 5:檢查 NSG 中是否已定義所有保留的 NSG 規則。 包含物件的陣列參數會定義保留的 NSG 規則屬性。
參數值:
[
{
"priority": 101,
"access": "deny",
"direction": "inbound",
"destinationPortRange": 22
},
{
"priority": 102,
"access": "deny",
"direction": "inbound",
"destinationPortRange": 3389
}
]
原則:
{
"count": {
"value": "[parameters('reservedNsgRules')]",
"name": "reservedNsgRule",
"where": {
"count": {
"field": "Microsoft.Network/networkSecurityGroups/securityRules[*]",
"where": {
"allOf": [
{
"field": "Microsoft.Network/networkSecurityGroups/securityRules[*].priority",
"equals": "[current('reservedNsgRule').priority]"
},
{
"field": "Microsoft.Network/networkSecurityGroups/securityRules[*].access",
"equals": "[current('reservedNsgRule').access]"
},
{
"field": "Microsoft.Network/networkSecurityGroups/securityRules[*].direction",
"equals": "[current('reservedNsgRule').direction]"
},
{
"field": "Microsoft.Network/networkSecurityGroups/securityRules[*].destinationPortRange",
"equals": "[current('reservedNsgRule').destinationPortRange]"
}
]
}
},
"equals": 1
}
},
"equals": "[length(parameters('reservedNsgRules'))]"
}
原則函式
函式可用來引入其他邏輯至原則規則。 其會在原則定義的原則規則內,以及在專案中指派給原則定義的參數值內進行解析。
除了下列函式和使用者定義函式,所有的 Resource Manager 範本函式都可在原則規則內使用:
copyIndex()
dateTimeAdd()
dateTimeFromEpoch
dateTimeToEpoch
deployment()
environment()
extensionResourceId()
lambda()
如需詳細資訊,請移至 lambdalistAccountSas()
listKeys()
listSecrets()
list*
managementGroup()
newGuid()
pickZones()
providers()
reference()
resourceId()
subscriptionResourceId()
tenantResourceId()
tenant()
variables()
注意
在 deployIfNotExists
原則定義中,仍可在其範本部署的 details.deployment.properties.template
部分內使用這些函式。
下列函式可在原則規則中使用,但與 Azure Resource Manager 範本 (ARM 範本) 中的用法不同:
utcNow()
- 不同於 ARM 範本,此屬性可以在 defaultValue 外使用。- 以通用 ISO 8601 日期時間格式
yyyy-MM-ddTHH:mm:ss.fffffffZ
傳回設為目前日期和時間的字串。
- 以通用 ISO 8601 日期時間格式
下列函式僅適用於原則規則:
addDays(dateTime, numberOfDaysToAdd)
dateTime
:[必要] 字串 - 採用通用 ISO 8601 日期時間格式 'yyyy-MM-ddTHH:mm:ss.FFFFFFFZ' 的字串numberOfDaysToAdd
:[必要] 整數 - 要新增的天數
field(fieldName)
fieldName
:[必要] 字串 - 要擷取的欄位名稱- 從 If 條件評估的資源傳回該欄位的值。
field
主要是與auditIfNotExists
和deployIfNotExists
搭配使用,以參考所評估資源上的欄位。 如需此用法的範例,請參閱 DeployIfNotExists 範例。
requestContext().apiVersion
- 傳回已觸發原則評估的要求 API 版本 (範例:
2021-09-01
)。 此值是 API 版本,即資源建立/更新評估的 PUT/PATCH 要求使用的版本。 在對現有資源進行合規性評估時,一律使用最新的 API 版本。
- 傳回已觸發原則評估的要求 API 版本 (範例:
policy()
傳回評估原則相關的下列資訊。 您可以從傳回的物件存取屬性 (例如,
[policy().assignmentId]
)。{ "assignmentId": "/subscriptions/11111111-1111-1111-1111-111111111111/providers/Microsoft.Authorization/policyAssignments/myAssignment", "definitionId": "/providers/Microsoft.Authorization/policyDefinitions/34c877ad-507e-4c82-993e-3452a6e0ad3c", "setDefinitionId": "/providers/Microsoft.Authorization/policySetDefinitions/42a694ed-f65e-42b2-aa9e-8052e9740a92", "definitionReferenceId": "StorageAccountNetworkACLs" }
ipRangeContains(range, targetRange)
range
:[必要] 字串 - 此字串會指定 IP 位址範圍,以檢查是否包含 targetRange。targetRange
:[必要] 字串 - 此字串會指定 IP 位址範圍,以驗證是否包含在「範圍」內。- 傳回布林值,指出 range IP 位址範圍是否包含 targetRange IP 位址範圍。 不允許空白範圍或 IP 系列間混合,並導致評估失敗。
支援的格式:
- 單一 IP 位址 (例如,
10.0.0.0
、2001:0DB8::3:FFFE
) - CIDR 範圍 (例如,
10.0.0.0/24
、2001:0DB8::/110
) - 起始和結束 IP 位址定義的範圍 (例如,
192.168.0.1-192.168.0.9
、2001:0DB8::-2001:0DB8::3:FFFF
)
current(indexName)
- 只在 計數運算式中使用的特殊函式。
原則函式範例
此原則規則範例會使用 resourceGroup
資源函式來取得 name
屬性,與 concat
陣列和物件函式結合來建置 like
條件,強制資源名稱以資源群組名稱開頭。
{
"if": {
"not": {
"field": "name",
"like": "[concat(resourceGroup().name,'*')]"
}
},
"then": {
"effect": "deny"
}
}
原則規則限制
製作期間強制執行的限制
原則的製作或指派期間會強制執行原則規則結構的限制。 嘗試建立或指派超過這些限制的原則定義會失敗。
限制 | 值 | 其他詳細資料 |
---|---|---|
if 條件中的條件運算式 |
4096 | |
then 區塊中的條件運算式 |
128 | 適用於 auditIfNotExists 和 deployIfNotExists 原則的 existenceCondition |
每個原則規則的原則函式 | 2048 | |
參數的原則函式數目 | 128 | 範例: [function('parameter1', 'parameter2', ...)] |
巢狀原則函式深度 | 64 | 範例: [function(nested1(nested2(...)))] |
原則函式運算式字串長度 | 81920 | 例如,"[function(....)]" 的長度 |
每個陣列的 Field count 運算式 |
5 | |
每個原則規則的 Value count 運算式 |
10 | |
Value count 運算式反覆運算計數 |
100 | 對於巢狀 Value count 運算式,這也會包含父運算式的反覆運算計數 |
評估期間強制執行的限制
原則評估期間由原則函式處理的物件大小限制。 這些限制需取決於評估的內容,所以製作期間不一定會強制執行。 例如:
{
"field": "name",
"equals": "[concat(field('stringPropertyA'), field('stringPropertyB'))]"
}
concat()
函式建立的字串長度會取決於評估資源中的屬性值。
限制 | 值 | 範例 |
---|---|---|
函式傳回的字串長度 | 131072 | [concat(field('longString1'), field('longString2'))] |
作為參數提供函式,或函式傳回的複雜物件深度 | 128 | [union(field('largeObject1'), field('largeObject2'))] |
作為參數提供函式,或函式傳回的複雜物件節點數目 | 32768 | [concat(field('largeArray1'), field('largeArray2'))] |
警告
評估期間超過上述限制的原則會有效地成為 deny
原則,並可封鎖傳入的要求。
使用複雜的函式撰寫原則時,請留意這些限制,並針對可能超過這些限制的資源測試您的原則。
下一步
- 如需原則定義結構的詳細資訊,請移至基本資料、參數和別名。
- 針對專案,請移至專案定義結構。
- 在 Azure 原則範例檢閱範例。
- 檢閱了解原則效果。
- 了解如何以程式設計方式建立原則。
- 了解如何取得合規性資料。
- 了解如何補救不符合規範的資源。
- 透過使用 Azure 管理群組來組織資源來檢閱何謂管理群組。