Структура определения службы "Политика Azure"

Политика Azure устанавливает соглашения о ресурсах. Определения политик описывают соответствие ресурсов условия и последствия выполнения условий. Условие сравнивает поле или значение свойства ресурса с требуемым значением. Доступ к полям свойств ресурсов осуществляется с помощью псевдонимов. Если поле свойства ресурса является массивом, для выбора значений из всех элементов массива и применения условия к каждому из них можно использовать специальный псевдоним массива. Дополнительные сведения об условиях.

Это соглашения помогут вам контролировать расходы и управлять ресурсами. Например, можно указать, что разрешены только определенные типы виртуальных машин. Кроме того, можно требовать наличие определенного тега для ресурсов. Назначения политик наследуются дочерними ресурсами. Назначение политики, применяемое к группе ресурсов, применяется также ко всем ресурсам в этой группе.

Схема определения политики policyRule представлена здесь: https://schema.management.azure.com/schemas/2020-10-01/policyDefinition.json

Для создания определения политики используется JSON. Определение политики содержит следующие элементы:

  • display name
  • description
  • mode
  • метаданные
  • parameters
  • policy rule
    • logical evaluation
    • effect

В следующем примере JSON показана политика, которая налагает ограничения на расположения для развертывания ресурсов.

{
    "properties": {
        "displayName": "Allowed locations",
        "description": "This policy enables you to restrict the locations your organization can specify when deploying resources.",
        "mode": "Indexed",
        "metadata": {
            "version": "1.0.0",
            "category": "Locations"
        },
        "parameters": {
            "allowedLocations": {
                "type": "array",
                "metadata": {
                    "description": "The list of locations that can be specified when deploying resources",
                    "strongType": "location",
                    "displayName": "Allowed locations"
                },
                "defaultValue": [ "westus2" ]
            }
        },
        "policyRule": {
            "if": {
                "not": {
                    "field": "location",
                    "in": "[parameters('allowedLocations')]"
                }
            },
            "then": {
                "effect": "deny"
            }
        }
    }
}

Встроенные компоненты и шаблоны Политики Azure приведены в примерах Политики Azure.

Отображаемое имя и описание

Параметры displayName и description позволяют идентифицировать определение политики и описать контекст для ее использования. Максимальная длина displayName составляет 128 символов, а description — 512 символов.

Примечание

Во время создания или обновления определения политики идентификатор, тип и имя определяются свойствами, которые являются внешними по отношению к JSON и не обязательны в JSON-файле. Выборка определения политики с помощью пакета SDK возвращает идентификатор, тип и имя свойства как часть JSON, но все они являются сведениями только для чтения, относящимися к определению политики.

Тип

Хотя свойство type невозможно задать, есть три значения, возвращаемых пакетом SDK и видимых на портале:

  • Builtin: эти определения политик предоставляются и обслуживаются корпорацией Майкрософт.
  • Custom: это значение задается для всех определений политик, созданных клиентами.
  • Static: указывает определение политики соответствия нормативным требованиям, которой владеет Майкрософт. Результаты проверки соответствия для этих определений политик являются результатами сторонних аудитов в инфраструктуре Майкрософт. На портале Azure это значение иногда отображается как управляемое корпорацией Майкрософт. Дополнительные сведения см. в статье Общая ответственность в облаке.

Режим

Режим настраивается в зависимости от того, нацелена ли политика на свойство Azure Resource Manager или на свойство поставщика ресурсов.

Режимы Resource Manager

Свойство mode определяет, какие типы ресурсов оцениваются определением политики. Ниже приведены поддерживаемые режимы.

  • all: оцениваются группы ресурсов, подписки и все типы ресурсов.
  • indexed: оцениваются только типы ресурсов, которые поддерживают теги и расположение.

Например, ресурс Microsoft.Network/routeTables поддерживает теги и расположение и оценивается в обоих режимах. Однако ресурс Microsoft.Network/routeTables/routes нельзя помечать тегами и он не оценивается в режиме Indexed.

В большинстве случаев рекомендуется задать для параметра mode значение all. Во всех определениях политик, создаваемых на портале, используется режим all. Если используется PowerShell или Azure CLI, необходимо указать параметр mode вручную. Если определение политики не включает значение mode, в Azure PowerShell используется значение по умолчанию all, а в Azure CLI — null. Режим null аналогичен использованию indexed для поддержки обратной совместимости.

indexed следует использовать при создании политик, которые будут принудительно применять теги или расположения. Это не обязательно, но помешает отображению ресурсов, которые не поддерживают теги и расположения, в качестве несоответствующих в результатах проверки соответствия. Исключением являются группы ресурсов и подписки. В определениях политик, которые принудительно применяют расположение или теги к группе ресурсов или подписке, следует задать для параметра mode значение all и явно указать целевой тип Microsoft.Resources/subscriptions/resourceGroups или Microsoft.Resources/subscriptions. Пример см. в разделе Шаблон. Теги — пример#1. Список ресурсов, поддерживающих теги, см. в разделе Поддержка тегов для ресурсов Azure.

Режимы поставщика ресурсов

Ниже перечислены полностью поддерживаемые режимы поставщика ресурсов:

  • Microsoft.Kubernetes.Dataдля управления кластерами Kubernetes в Azure или вне их, а также для Политика Azure компонентов, предназначенных для кластеров Kubernetes с поддержкой Azure Arc, таких как pod, контейнеры и входящий трафик. В определениях, использующих этот режим поставщика ресурсов, применяются действия audit, denyи disabled.
  • Microsoft.KeyVault.Data для управления хранилищами и сертификатами в Azure Key Vault. Дополнительные сведения об этих определениях политик см. в статье Интеграция Azure Key Vault с Политикой Azure.

Сейчас в предварительной версии поддерживаются следующие режимы поставщика ресурсов:

Примечание

Если не указано явно, режимы поставщика ресурсов поддерживают только встроенные определения политик, а исключения не поддерживаются на уровне компонента.

Метаданные

В необязательном свойстве metadata хранится информация об определении политики. Клиенты могут определять любые свойства и значения, полезные для организации, в свойстве metadata. Однако существуют некоторые общие свойства, используемые Политикой Azure и встроенными компонентами. Длина значения каждого свойства metadata ограничена 1024 символами.

Общие свойства метаданных

  • version (строка): отслеживает сведения о версии содержимого определения политики.
  • category (строка): определяет, в какой категории на портале Azure отображается определение политики.
  • preview (логическое): флаг true или false, указывающий, было ли определение политики создано в предварительной версии.
  • deprecated (логическое): флаг true или false, указывающий, было ли определение политики отмечено как нерекомендуемое.
  • portalReview (строка): определяет, следует ли проверять параметры на портале независимо от требуемых входных данных.

Примечание

Служба Политика Azure использует свойства version, preview и deprecated для передачи уровня изменений встроенному определению политики или инициативе и состоянию. Формат version{Major}.{Minor}.{Patch}. Конкретные состояния, такие как устаревший или предварительная версия, добавляются к свойству version или в другом свойстве как логическое значение. Дополнительные сведения о способах встраивания версий Политики Azure см. в разделе Встроенное управление версиями. Дополнительные сведения о том, что означает, что политика является устаревшей или доступна в виде предварительной версии, см. в разделе Предварительные версии политик и устаревшие политики.

Параметры

Параметры помогают упростить управление политиками за счет сокращения числа определений политик. Параметры можно рассматривать как поля в форме: name, address, city, state. Эти параметры никогда не меняются, однако их значения изменяются в зависимости от того, как пользователь заполняет форму. Точно так же параметры работают при создании политик. Добавив параметры в определение политики, вы сможете повторно использовать ее в различных сценариях, указывая разные значения.

Примечание

Параметры могут быть добавлены к имеющемуся и назначенному определению. Новый параметр должен включать в себя свойство defaultValue. Это предотвращает косвенное использование существующих назначений политики или инициативы.

Свойства параметра

Параметр имеет следующие свойства, которые используются в определении политики:

  • name: имя параметра. Используется функцией развертывания parameters в правиле политики. Дополнительные сведения см. в разделе об использовании значения параметра.
  • type: Определяет, является ли параметр строкой, массивом, объектом, логическим значением, целым числом, числом с плавающей запятой или значением даты/времени.
  • metadata: Определяет вложенное свойство, которое в основном используется для отображения понятной пользователям информации на портале Azure:
    • description: Объясняет назначение параметра. Можно использовать для примеров допустимых значений.
    • displayName: Понятное имя параметра, которое отображается на портале.
    • strongType: (Необязательно.) Используется при назначении определения политики через портал. Предоставляет список с учетом контекста. См. дополнительные сведения о вложенном свойстве strongType.
    • assignPermissions: (Необязательно.) Установите на true, чтобы портал Azure создавал назначения ролей во время назначения политики. Это свойство полезно, если вы хотите назначить разрешения за пределами области назначения. Каждому определению роли в политике (или во всех политиках инициативы) соответствует одно назначение роли. Значение параметра должно быть допустимым ресурсом или областью.
  • defaultValue: (Необязательно.) Устанавливает значение параметра в назначении, если значение не указано. Это свойство необходимо при обновлении существующего назначенного определения политики. Значение параметра объектного типа должно соответствовать определенной схеме.
  • allowedValues: (Необязательно.) Предоставляет массив значений, которые параметр принимает во время назначения. При сравнении допустимых значений учитывается регистр. Значения параметров объектного типа должны соответствовать определенной схеме.
  • schema: (необязательно) обеспечивает проверку входных данных параметров во время назначения с использованием самоопределяющейся схемы JSON. Это свойство поддерживается только для параметров объектного типа и соответствует реализации Json.NET Schema 2019-09. Вы можете просмотреть дополнительные сведения об использовании схем на сайте https://json-schema.org/ и протестировать черновые версии схем на сайте https://www.jsonschemavalidator.net/.

Примеры параметров

Пример 1

Например, можно создать определение политики, чтобы ограничить расположения, в которых могут развертываться ресурсы. Для такого определения политики можно использовать параметр allowedLocations. Этот параметр будет использоваться каждым назначением определения политики для ограничения допустимых значений. Использование вложенного свойства strongType делает назначение через портал более удобным:

"parameters": {
    "allowedLocations": {
        "type": "array",
        "metadata": {
            "description": "The list of allowed locations for resources.",
            "displayName": "Allowed locations",
            "strongType": "location"
        },
        "defaultValue": [ "westus2" ],
        "allowedValues": [
            "eastus2",
            "westus2",
            "westus"
        ]
    }
}

Пример входных данных для этого параметра массивового типа (без strongType) при назначении: ["westus", "eastus2"].

Пример 2

В более сложном сценарии можно определить политику, которая требует, чтобы модули pod кластера Kubernetes использовали указанные метки. Параметром для этого определения политики может быть labelSelector, который будет использоваться в каждом назначении определения политики для указания нужных ресурсов Kubernetes на основе ключей и значений меток:

"parameters": {
    "labelSelector": {
        "type": "Object",
        "metadata": {
            "displayName": "Kubernetes label selector",
            "description": "Label query to select Kubernetes resources for policy evaluation. An empty label selector matches all Kubernetes resources."
        },
        "defaultValue": {},
        "schema": {
            "description": "A label selector is a label query over a set of resources. The result of matchLabels and matchExpressions are ANDed. An empty label selector matches all resources.",
            "type": "object",
            "properties": {
                "matchLabels": {
                    "description": "matchLabels is a map of {key,value} pairs.",
                    "type": "object",
                    "additionalProperties": {
                        "type": "string"
                    },
                    "minProperties": 1
                },
                "matchExpressions": {
                    "description": "matchExpressions is a list of values, a key, and an operator.",
                    "type": "array",
                    "items": {
                        "type": "object",
                        "properties": {
                            "key": {
                                "description": "key is the label key that the selector applies to.",
                                "type": "string"
                            },
                            "operator": {
                                "description": "operator represents a key's relationship to a set of values.",
                                "type": "string",
                                "enum": [
                                    "In",
                                    "NotIn",
                                    "Exists",
                                    "DoesNotExist"
                                ]
                            },
                            "values": {
                                "description": "values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty.",
                                "type": "array",
                                "items": {
                                    "type": "string"
                                }
                            }
                        },
                        "required": [
                            "key",
                            "operator"
                        ],
                        "additionalProperties": false
                    },
                    "minItems": 1
                }
            },
            "additionalProperties": false
        }
    },
}

Пример входных данных для этого параметра объектного типа при назначении будет представлен в формате JSON, который проверяется указанной схемой, и может иметь следующий вид:

{
    "matchLabels": {
        "poolID": "abc123",
        "nodeGroup": "Group1",
        "region": "southcentralus"
    },
    "matchExpressions": [
        {
            "key": "name",
            "operator": "In",
            "values": ["payroll", "web"]
        },
        {
            "key": "environment",
            "operator": "NotIn",
            "values": ["dev"]
        }
    ]
}

Использование значения параметра

В правилах политики полученные параметры используются со следующим синтаксисом функции parameters.

{
    "field": "location",
    "in": "[parameters('allowedLocations')]"
}

В этом примере используется параметр allowedLocations, который рассматривался в разделе о свойствах параметра.

strongType

В свойстве metadata можно использовать вложенное свойство strongType, чтобы предоставить список для выбора параметров на портале Azure. strongType может быть поддерживаемым типом ресурса или допустимым значением. Чтобы определить, можно ли использовать strongType для того или иного типа ресурса, используйте командлет Get-AzResourceProvider. Значение strongType для типа ресурса представлено в следующем формате: <Resource Provider>/<Resource Type>. Например, Microsoft.Network/virtualNetworks/subnets.

Некоторые поддерживаемые типы ресурсовGet-AzResourceProvider не возвращает. Эти типы перечислены ниже.

  • Microsoft.RecoveryServices/vaults/backupPolicies

Допустимыми значениями, помимо типов ресурсов для strongType, являются следующие.

  • location
  • resourceTypes
  • storageSkus
  • vmSKUs
  • existingResourceGroups

Расположение определения

При создании инициативы или политики необходимо указывать расположение определения. Расположение определения должно быть задано как группа управления или подписка. Расположение указывает область, которой можно назначить инициативу или политику. Ресурсы должны быть непосредственными членами или дочерними элементами в иерархии расположения определения для назначения.

Если расположение определения является

  • подпиской: определение политики можно назначить только ресурсам в этой подписке;
  • группой управления: определение политики можно назначить только ресурсам из дочерних групп управления и дочерних подписок. Если вы планируете применить определение политики к нескольким подпискам, расположение должно быть группой управления, содержащей каждую подписку.

Дополнительные сведения см. в статье Общие сведения об области в Политике Azure.

Правило политики

Правило политики состоит из блоков If и Then. В блоке If указываются одно или несколько условий. Они определяют, когда применяется эта политика. В этих условиях можно использовать логические операторы, чтобы точно определить сценарии для использования политики.

В блоке Then описываются результаты, которые вступают в силу при соблюдении условий из блока If.

{
    "if": {
        <condition> | <logical operator>
    },
    "then": {
        "effect": "deny | audit | modify | append | auditIfNotExists | deployIfNotExists | disabled"
    }
}

Логические операторы

Ниже перечислены поддерживаемые логические операторы.

  • "not": {condition or operator}
  • "allOf": [{condition or operator},{condition or operator}]
  • "anyOf": [{condition or operator},{condition or operator}]

Оператор not инвертирует результат условия. Оператор allOf действует как логическая операция And, то есть требует соблюдения всех входящих в него условий. Оператор anyOf действует как логическая операция Or, то есть проверяет соблюдение хотя бы одного из входящих в него условий.

Допускается вложение логических операторов. В следующем примере представлена операция 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, он не учитывается. Другие варианты без учета регистра доступны для условий matchInsensitively и notMatchInsensitively.

Поля

Условия, определяющие, отвечают ли значения свойств в полезных данных запроса ресурса определенным критериям, можно составлять с помощью выражения field. Поддерживаются следующие поля.

  • name
  • fullName
    • Возвращает полное имя ресурса. Полное имя ресурса — это имя ресурса, к которому добавлены любые имена родительских ресурсов (например, myServer/myDatabase).
  • kind
  • type
  • location
    • Поля расположений нормализуются для поддержки различных форматов. Например, значение East US 2 считается эквивалентным значению eastus2.
    • Используйте global для ресурсов, которые зависят от расположения.
  • id
    • Возвращает ИД оцениваемого ресурса.
    • Например, /subscriptions/06be863d-0996-4d56-be22-384767287aa2/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, ссылающихся на псевдоним [*], каждый элемент массива оценивается отдельно, и между элементами ставится логический оператор И. Дополнительные сведения см. в статье Ссылки на свойства ресурсов массива.

Использование тегов с параметрами

Значение параметра передается полю тега. Передача параметра полю тега повышает гибкость определения политики во время ее назначения.

В указанном ниже примере 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. Значения могут быть литералами, значениями параметров или возвращаемыми значениями любых поддерживаемых функций шаблонов.

Предупреждение

Если результатом функции шаблона является ошибка, оценка политики завершится сбоем. Завершившаяся сбоем оценка — это неявный запрет. Дополнительные сведения см. в разделе Аvoiding template failures (Предотвращение сбоев шаблонов). Используйте enforcementModeDoNotEnforce, чтобы исключить влияние неудачной оценки на новые или обновленные ресурсы при тестировании и проверке нового определения политики.

Примеры значений

В этом примере правила политики используют value для сравнения результата функции resourceGroup() и возвращенного свойства name с условием like для *netrg. Это правило запрещает любой ресурс, с типом, отличающимся от Microsoft.Network/*, в любой группе ресурсов, имя которой заканчивается на *netrg.

{
    "if": {
        "allOf": [{
                "value": "[resourceGroup().name]",
                "like": "*netrg"
            },
            {
                "field": "type",
                "notLike": "Microsoft.Network/*"
            }
        ]
    },
    "then": {
        "effect": "deny"
    }
}

В этом примере правила политики используют value для проверки того, равен ли результат нескольких вложенных функций true. Это правило запрещает любой ресурс, в котором нет хотя бы трех тегов.

{
    "mode": "indexed",
    "policyRule": {
        "if": {
            "value": "[less(length(field('tags')), 3)]",
            "equals": "true"
        },
        "then": {
            "effect": "deny"
        }
    }
}

Предотвращение сбоев шаблонов

Использование функций шаблона в value позволяет выполнять многие сложные вложенные функции. Если результатом функции шаблона является ошибка, оценка политики завершится сбоем. Завершившаяся сбоем оценка — это неявный запрет. Пример value, которое приводит к сбою в некоторых сценариях.

{
    "policyRule": {
        "if": {
            "value": "[substring(field('name'), 0, 3)]",
            "equals": "abc"
        },
        "then": {
            "effect": "audit"
        }
    }
}

В примере правила политики выше используется substring() для сравнения первых трех символов имени с abc. Если имя короче трех символов, то функция substring() приводит к ошибке. Эта ошибка приводит к тому, что политика становится действием deny.

Вместо этого используйте функцию if(), чтобы проверить, совпадают ли первые три символа имени с abc, не давая имени короче трех символов вызывать ошибку.

{
    "policyRule": {
        "if": {
            "value": "[if(greaterOrEquals(length(field('name')), 3), substring(field('name'), 0, 3), 'not starting with abc')]",
            "equals": "abc"
        },
        "then": {
            "effect": "audit"
        }
    }
}

С измененным правилом политики if() проверяет длину имени перед попыткой получить substring() для значения с менее чем тремя символами. Если имя слишком коротко, то возвращается значение «не начинается с abc», которое затем сравнивается с abc. Ресурс с коротким именем, которое не начинается с abc, по-прежнему не выполняет правило политики, но больше не вызывает ошибку во время оценки.

Count

Условия, которые подсчитывают количество элементов массива, отвечающих определенным критериям, можно составлять с помощью выражения count. К распространенным сценариям относится проверка соответствия условию “по крайней мере один из”, “только один из”, “все” или “ни одного” для элементов массива. Count оценивает каждый элемент массива по выражению условия и складывает результаты true, а затем сравнивает полученное значение с оператором выражения.

Field count

Подсчитывает, сколько элементов массива в полезных данных запроса соответствуют выражению условия. Структура выражения 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. Если это свойство не указано, то все элементы массива с путем field оцениваются как true. В этом свойстве можно использовать любое condition (условие). Внутри этого свойства можно использовать логические операторы для создания сложных требований к оценке.
  • <condition> (обязательное): значение сравнивается с числом элементов, которые соответствуют выражению условия count.where. Следует использовать числовое condition.

Дополнительные сведения о том, как работать со свойствами, представляющими собой массивы, в Политике Azure, в том числе подробное описание того, как оценивается выражение field count, см. в статье Ссылки на свойства ресурса массива.

Value 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 (условие). Внутри этого свойства можно использовать логические операторы для создания сложных требований к оценке. Значение перечисляемого в данный момент элемента массива можно получить, вызвав функцию current.
  • <condition> (обязательное): значение сравнивается с числом элементов, которые соответствуют выражению условия count.where. Следует использовать числовое condition.

Функция current

Функция current() доступна только в условии count.where. Она возвращает значение элемента массива, перечисляемого в данный момент при оценке выражения count.

Использование выражения value count

  • current(<index name defined in count.name>). Например, так: current('arrayMember').
  • current(). Допускается только в том случае, если выражение value count не является дочерним для другого выражения count. Возвращает то же значение, что и приведенное выше выражение.

Если значение, возвращаемое вызовом, представляет собой объект, поддерживаются методы доступа к свойствам. Например, так: current('objectArrayMember').property.

Использование выражения field count

  • 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').

Примеры использования выражения field count

Пример 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. Использование функции current() внутри условий where для доступа к значению перечисляемого в данный момент элемента массива в функции шаблона. Это условие проверяет, есть ли в виртуальной сети префикс адреса, не входящий в диапазон CIDR 10.0.0.0/24.

{
    "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. Использование функции field() внутри условий where для доступа к значению перечисляемого в данный момент элемента массива. Это условие проверяет, есть ли в виртуальной сети префикс адреса, не входящий в диапазон CIDR 10.0.0.0/24.

{
    "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
}

Примеры использования выражения value count

Пример 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. Проверка того, определены ли все зарезервированные правила в группе безопасности сети. Свойства зарезервированных правил группы безопасности сети определяются в параметре массива, содержащем объекты.

Значение параметра:

[
    {
        "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'))]"
}

Действие

Политика Azure поддерживает следующие типы действий:

  • Append добавляет в запрос некоторый набор полей;
  • Audit записывает предупреждение в журнал действий, но не отвергает запрос;
  • AuditIfNotExists: создает событие предупреждения в журнале действий, если связанный ресурс не существует;
  • Deny записывает событие в журнал действий и отвергает запрос;
  • DeployIfNotExists: развертывает связанный ресурс, если он еще не существует;
  • Disabled не оценивает ресурсы на соответствие правилу политики.
  • Изменение: добавляет, обновляет или удаляет определенный набор полей в запросе.
  • EnforceOPAConstraint (нерекомендуемый): настраивает контроллер допуска агента открытой политики с помощью Gatekeeper 3-й версии для самоуправляемых кластеров Kubernetes в Azure
  • EnforceRegoPolicy (нерекомендуемый): настраивает контроллер допуска агента открытой политики с помощью Gatekeeper 2-й версии в службе Azure Kubernetes

Подробные сведения о каждом эффекте, порядке оценки и свойствах, а также примеры см. в статье Действия политик Azure.

Функции политики

Функции можно использовать для привнесения дополнительной логики в правило политики. Они разрешаются в рамках правила политики определения политики и в рамках значений параметров, назначенных определениям политик в инициативе.

В рамках правила политики можно использовать все функции шаблона Resource Manager, кроме функций, определяемых пользователем и следующих.

  • copyIndex()
  • dateTimeAdd()
  • deployment()
  • environment()
  • extensionResourceId()
  • listAccountSas()
  • listKeys()
  • listSecrets()
  • list*
  • managementGroup()
  • newGuid()
  • pickZones()
  • providers()
  • reference()
  • resourceId()
  • subscriptionResourceId()
  • tenantResourceId()
  • tenant()
  • utcNow(format)
  • variables()

Примечание

Эти функции по-прежнему доступны в части details.deployment.properties.template развертывания шаблона, в определении политики deployIfNotExists.

Следующая функция доступна для использования в правиле политики, но такое применение отличается от использования в шаблоне 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 предназначена главным образом для использования с AuditIfNotExists и DeployIfNotExists, чтобы ссылаться на поля в ресурсе, который оценивается. Это можно увидеть на примере DeployIfNotExists.
  • requestContext().apiVersion

    • Возвращает версию API запроса, который активировал оценку политики (пример: 2021-09-01). Это значение указывает версию API, которая использовалась в запросе PUT/PATCH для оценки при создании или обновлении ресурсов. Последняя версия API всегда используется во время оценки соответствия для существующих ресурсов.
  • policy()

    • Возвращает перечисленные ниже сведения об оцениваемой политике. Доступ к свойствам можно получить из возвращенного объекта (пример: [policy().assignmentId]).

      {
        "assignmentId": "/subscriptions/ad404ddd-36a5-4ea8-b3e3-681e77487a63/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 в диапазоне range. Пустые диапазоны и сочетания семейств 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)

    • специальная функция, которую можно использовать только в выражениях count.

Пример функции политики

В этом примере правила политики функция ресурса 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'))]
Глубина cоставных объектов, предоставляемых функции в качестве параметра или возвращаемых ею 128 [union(field('largeObject1'), field('largeObject2'))]
Количество узлов cоставных объектов, предоставляемых функции в качестве параметра или возвращаемых ею 32768 [concat(field('largeArray1'), field('largeArray2'))]

Предупреждение

Политика, превышающая указанные выше ограничения во время оценки, фактически становится политикой запрета и может блокировать входящие запросы. При написании политик со сложными функциями следует учитывать эти ограничения и протестировать политики для тех ресурсов, которые могут их превышать.

Aliases

Псевдонимы свойств позволяют обращаться к определенным свойствам для типа ресурса. Псевдонимы позволяют ограничить значения или условия, разрешенные для свойства ресурса. Каждый псевдоним сопоставляется с путями в разных версиях API для заданного типа ресурса. Во время оценки политики модуль политики получает путь свойства для этой версии API.

Список псевдонимов постоянно пополняется. Чтобы узнать, какие псевдонимы в настоящее время поддерживаются службой "Политика Azure", используйте один из следующих методов:

  • Расширение Политики Azure для Visual Studio Code (рекомендуется)

    Используйте расширение Политики Azure для Visual Studio Code, чтобы просматривать и находить псевдонимы для свойств ресурсов.

    Снимок экрана: расширение Политики Azure для Visual Studio Code с указателем, наведенным на свойство для отображения псевдонимов.

  • Azure PowerShell

    # Login first with Connect-AzAccount if not using Cloud Shell
    
    # Use Get-AzPolicyAlias to list available providers
    Get-AzPolicyAlias -ListAvailable
    
    # Use Get-AzPolicyAlias to list aliases for a Namespace (such as Azure Compute -- Microsoft.Compute)
    (Get-AzPolicyAlias -NamespaceMatch 'compute').Aliases
    

    Примечание

    Чтобы найти псевдонимы, которые можно использовать с действием modify, используйте следующую команду в Azure PowerShell 4.6.0 или более поздней версии:

    Get-AzPolicyAlias | Select-Object -ExpandProperty 'Aliases' | Where-Object { $_.DefaultMetadata.Attributes -eq 'Modifiable' }
    
  • Azure CLI

    # Login first with az login if not using Cloud Shell
    
    # List namespaces
    az provider list --query [*].namespace
    
    # Get Azure Policy aliases for a specific Namespace (such as Azure Compute -- Microsoft.Compute)
    az provider show --namespace Microsoft.Compute --expand "resourceTypes/aliases" --query "resourceTypes[].aliases[].name"
    
  • REST API или ARMClient

    GET https://management.azure.com/providers/?api-version=2019-10-01&$expand=resourceTypes/aliases
    

Общие сведения о псевдониме [*]

Некоторые доступные псевдонимы имеют версию с отображаемым "обычным" именем, а другие — с присоединенным [*]. Пример:

  • Microsoft.Storage/storageAccounts/networkAcls.ipRules
  • Microsoft.Storage/storageAccounts/networkAcls.ipRules[*]

«Обычный» псевдоним представляет поле как одно значение. Это поле предназначено для сценариев сравнения точного соответствия, если весь набор значений должен в точности соответствовать определению, не больше и не меньше.

Псевдоним [*] представляет коллекцию значений, выбранных из элементов массива в свойстве ресурса. Пример:

Псевдоним Выбранные значения
Microsoft.Storage/storageAccounts/networkAcls.ipRules[*] Элементы массива ipRules.
Microsoft.Storage/storageAccounts/networkAcls.ipRules[*].action Значения свойства action каждого элемента массива ipRules.

При использовании в условии field псевдонимы массивов дают возможность сравнить каждый элемент массива с целевым значением. При использовании в выражении count можно:

  • проверить размер массива;
  • проверить соответствие всех, любого или ни одного из элементов массива сложному условию;
  • проверить соответствие ровно n элементов массива сложному условию.

Дополнительные сведения и примеры представлены в разделе Ссылки на свойства ресурсов, являющиеся массивами.

Дальнейшие действия