Share via


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。

您可以巢狀邏輯運算子。 下列範例顯示作業 notallOf 巢狀的作業。

"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為 、 lessOrEqualsgreatergreaterOrEquals,如果屬性類型不符合條件類型,則會擲回錯誤。 字串比較是使用 InvariantCultureIgnoreCase 進行。

使用 likenotLike 條件時,您會在 值中提供通配符 (*)。 值不應該有一個以上的通配符。

使用 matchnotMatch 條件時,請提供主題標籤 (#) 來比對字母的數字、問號 (?) 和點 (.) 來比對任何字元,以及符合該實際字元的任何其他字元。 雖然 matchnotMatch 會區分大小寫,但評估 stringValue 的所有其他條件都不區分大小寫。 和notMatchInsensitivelymatchInsensitively提供不區分大小寫的替代方法。

欄位

評估資源要求承載中屬性值是否符合特定準則的條件,可以使用表達式來形成 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 來檢查多個巢狀函 equalstrue式的結果。 規則會拒絕沒有至少三個標籤的任何資源。

{
  "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() 如需詳細資訊,請移至 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 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 版本。
  • 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.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 existenceConditionauditIfNotExists適用於和 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 ,並可封鎖傳入要求。 使用複雜的函式撰寫原則時,請留意這些限制,並針對可能超過這些限制的資源測試您的原則。

下一步