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。
您可以巢狀邏輯運算子。 下列範例顯示作業 not
內 allOf
巢狀的作業。
"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
的所有其他條件都不區分大小寫。 和notMatchInsensitively
中matchInsensitively
提供不區分大小寫的替代方法。
欄位
評估資源要求承載中屬性值是否符合特定準則的條件,可以使用表達式來形成 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
的 。 如需詳細資訊,請參閱避免範本錯誤。 使用 enforcementModedoNotEnforce
來防止在測試及驗證新原則定義時,對新或更新的資源進行失敗評估的影響。
Value 範例
此原則規則範例會使用 value
來比較函式的結果 resourceGroup()
和傳 name
回的屬性與 like
的條件 *netrg
。 此規則會拒絕任何資源群組中名稱結尾為 *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()
. 只有當表達式不是另一個count
表達式的子系時value count
,才允許。 傳回與上述相同的值。
如果呼叫傳回的值是物件,即支援屬性存取子。 例如: current('objectArrayMember').property
。
欄位計數使用量
current(<the array alias defined in count.field>)
. 例如:current('Microsoft.Test/resource/enumeratedArray[*]')
。current()
. 只有當表達式不是另一個count
表達式的子系時field 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 DateTime 格式為 'yyyy-MM-ddTHH:mm:ss 的字串。FFFFFFFZ'numberOfDaysToAdd
:[必要] 整數 - 要新增的天數
field(fieldName)
fieldName
:[必要] 字串 - 要擷取的域名- 從 If 條件評估的資源傳回該欄位的值。
field
主要與 和deployIfNotExists
搭配auditIfNotExists
使用,以參考正在評估之資源的欄位。 如需此用法的範例,請參閱 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
:[必要] 字串 - 字串,指定要檢查 targetRange 是否在內的IP位址範圍。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 | existenceCondition auditIfNotExists 適用於和 deployIfNotExists 原則 |
每個原則規則的原則函式 | 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 管理群組來組織資源來檢閱何謂管理群組。
意見反映
https://aka.ms/ContentUserFeedback。
即將推出:我們會在 2024 年淘汰 GitHub 問題,並以全新的意見反應系統取代並作為內容意見反應的渠道。 如需更多資訊,請參閱:提交及檢視以下的意見反映: