共用方式為


Azure 原則定義結構原則規則

原則規則包含 ifthen 區塊。 在 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"

對於 lesslessOrEqualsgreatergreaterOrEquals,如果屬性類型不符合條件類型,則會擲回錯誤。 字串比較是使用 InvariantCultureIgnoreCase 進行。

使用 likenotLike 條件時,您會在值中提供萬用字元 (*)。 此值不應具有多個萬用字元。

使用 matchnotMatch 條件時,請提供雜湊標記 (#) 來比對數字、問號 (?) 表示一個字母和點 (.) 來比對任何字元,以及任何其他字元來比對該實際字元。 雖然 matchnotMatch 會區分大小寫,但評估 stringValue 的所有其他條件都不會區分大小寫。 matchInsensitivelynotMatchInsensitively 中可以使用不區分大小寫的替代方案。

欄位

在資源要求承載中評估屬性值是否符合特定準則的條件,可以使用 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。 如需詳細資訊,請參閱避免範本錯誤。 使用 doNotEnforceenforcementMode,以防止在測試和驗證新的原則定義時,由於新的或更新的資源評估失敗而受到影響。

Value 範例

此原則規則範例使用 value,將 resourceGroup() 函式的結果和傳回的 name 屬性與 *netrglike 條件進行比較。 在名稱結尾為 *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() 如需詳細資訊,請移至 lambda
  • listAccountSas()
  • 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 傳回設為目前日期和時間的字串。

下列函式僅適用於原則規則:

  • addDays(dateTime, numberOfDaysToAdd)

    • dateTime:[必要] 字串 - 採用通用 ISO 8601 日期時間格式 'yyyy-MM-ddTHH:mm:ss.FFFFFFFZ' 的字串
    • numberOfDaysToAdd:[必要] 整數 - 要新增的天數
  • field(fieldName)

    • fieldName:[必要] 字串 - 要擷取的欄位名稱
    • 從 If 條件評估的資源傳回該欄位的值。
    • field 主要是與 auditIfNotExistsdeployIfNotExists 搭配使用,以參考所評估資源上的欄位。 如需此用法的範例,請參閱 DeployIfNotExists 範例
  • requestContext().apiVersion

    • 傳回已觸發原則評估的要求 API 版本 (範例:2021-09-01)。 此值是 API 版本,即資源建立/更新評估的 PUT/PATCH 要求使用的版本。 在對現有資源進行合規性評估時,一律使用最新的 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.02001:0DB8::3:FFFE)
    • CIDR 範圍 (例如,10.0.0.0/242001:0DB8::/110)
    • 起始和結束 IP 位址定義的範圍 (例如,192.168.0.1-192.168.0.92001: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 適用於 auditIfNotExistsdeployIfNotExists 原則的 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 原則,並可封鎖傳入的要求。 使用複雜的函式撰寫原則時,請留意這些限制,並針對可能超過這些限制的資源測試您的原則。

下一步