您现在访问的是微软AZURE全球版技术文档网站,若需要访问由世纪互联运营的MICROSOFT AZURE中国区技术文档网站,请访问 https://docs.azure.cn.

教程:创建自定义策略定义Tutorial: Create a custom policy definition

客户可以通过自定义策略定义来定义自己的 Azure 使用规则。A custom policy definition allows customers to define their own rules for using Azure. 这些规则通常强制实施:These rules often enforce:

  • 安全做法Security practices
  • 成本管理Cost management
  • 组织特定的规则(例如命名或位置)Organization-specific rules (like naming or locations)

无论创建自定义策略的业务推动因素是什么,定义新自定义策略的步骤都是相同的。Whatever the business driver for creating a custom policy, the steps are the same for defining the new custom policy.

创建自定义策略之前,请查看策略示例,以确定是否存在符合需求的策略。Before creating a custom policy, check the policy samples to see if a policy that matches your needs already exists.

遵循以下步骤创建自定义策略:The approach to creating a custom policy follows these steps:

  • 确定业务要求Identify your business requirements
  • 将每个要求映射到 Azure 资源属性Map each requirement to an Azure resource property
  • 将属性映射到别名Map the property to an alias
  • 确定要使用的效果Determine which effect to use
  • 撰写策略定义Compose the policy definition

如果没有 Azure 订阅,请在开始之前创建一个免费帐户If you don't have an Azure subscription, create a free account before you begin.

确定要求Identify requirements

在创建策略定义之前,必须了解策略的意图。Before creating the policy definition, it's important to understand the intent of the policy. 本教程将使用常见的企业安全要求作为目标来演示相关步骤:For this tutorial, we'll use a common enterprise security requirement as the goal to illustrate the steps involved:

  • 必须在每个存储帐户中启用 HTTPSEach storage account must be enabled for HTTPS
  • 必须在每个存储帐户中启用 HTTPEach storage account must be disabled for HTTP

要求中应该明确规定“正常”和“不正常”资源状态。Your requirements should clearly identify both the "to be" and the "not to be" resource states.

尽管我们已定义资源的预期状态,但尚未定义如何处理不合规的资源。While we've defined the expected state of the resource, we've not yet defined what we want done with non-compliant resources. Azure Policy 支持多种效果Azure Policy supports a number of effects. 本教程将业务要求定义为阻止创建不符合业务规则的资源。For this tutorial, we'll define the business requirement as preventing the creation of resources if they aren't compliant with the business rules. 为了满足此目标,我们将使用“拒绝”效果。To meet this goal, we'll use the Deny effect. 我们还需要使用相应的选项来暂停特定分配的策略。We also want the option to suspend the policy for specific assignments. 因此,我们将使用“已禁用”效果,并将其设为策略定义中的参数As such, we'll use the Disabled effect and make the effect a parameter in the policy definition.

确定资源属性Determine resource properties

根据业务要求,要使用 Azure Policy 审核的 Azure 资源为存储帐户。Based on the business requirement, the Azure resource to audit with Azure Policy is a storage account. 但是,我们不知道要在策略定义中使用的属性。However, we don't know the properties to use in the policy definition. Azure Policy 将会评估资源的 JSON 表示形式,因此,需要了解可在该资源中使用的属性。Azure Policy evaluates against the JSON representation of the resource, so we'll need to understand the properties available on that resource.

可通过多种方式确定 Azure 资源的属性。There are many ways to determine the properties for an Azure resource. 本教程将介绍其中的每种方式:We'll look at each for this tutorial:

  • 资源管理器模板Resource Manager templates
    • 导出现有资源Export existing resource
    • 创建体验Creation experience
    • 快速入门模板 (GitHub)Quickstart templates (GitHub)
    • 模板参考文档Template reference docs
  • Azure 资源浏览器Azure Resource Explorer

资源管理器模板Resource Manager templates

可通过多种方式查找包含所要管理的属性的资源管理器模板There are several ways to look at a Resource Manager template that includes the property you're looking to manage.

门户中的现有资源Existing resource in the portal

查找属性的最简单方法是查找相同类型的现有资源。The simplest way to find properties is to look at an existing resource of the same type. 已使用所要强制实施的设置配置的资源也会提供用于比较的值。Resources already configured with the setting you want to enforce also provide the value to compare against. 在 Azure 门户中,找到该特定资源的“导出模板”页(在“设置”下) 。Look at the Export template page (under Settings) in the Azure portal for that specific resource.

现有资源上的“导出模板”页

针对存储帐户执行此操作会显示以下示例所示的模板:Doing so for a storage account reveals a template similar to this example:

...
"resources": [{
    "comments": "Generalized from resource: '/subscriptions/{subscriptionId}/resourceGroups/myResourceGroup/providers/Microsoft.Storage/storageAccounts/mystorageaccount'.",
    "type": "Microsoft.Storage/storageAccounts",
    "sku": {
        "name": "Standard_LRS",
        "tier": "Standard"
    },
    "kind": "Storage",
    "name": "[parameters('storageAccounts_mystorageaccount_name')]",
    "apiVersion": "2018-07-01",
    "location": "westus",
    "tags": {
        "ms-resource-usage": "azure-cloud-shell"
    },
    "scale": null,
    "properties": {
        "networkAcls": {
            "bypass": "AzureServices",
            "virtualNetworkRules": [],
            "ipRules": [],
            "defaultAction": "Allow"
        },
        "supportsHttpsTrafficOnly": false,
        "encryption": {
            "services": {
                "file": {
                    "enabled": true
                },
                "blob": {
                    "enabled": true
                }
            },
            "keySource": "Microsoft.Storage"
        }
    },
    "dependsOn": []
}]
...

“属性”下面提供了名为 supportsHttpsTrafficOnly、设置为 false 的值。 Under properties is a value named supportsHttpsTrafficOnly set to false. 此属性似乎是我们所要查找的属性。This property looks like it may be the property we're looking for. 此外,该资源的类型Microsoft.Storage/storageAccountsAlso, the type of the resource is Microsoft.Storage/storageAccounts. 该类型告知我们,要将策略限定于此类型的资源。The type lets us limit the policy to only resources of this type.

在门户中创建资源Create a resource in the portal

另一种方式是通过门户中的资源创建体验。Another way through the portal is the resource creation experience. 通过门户创建存储帐户时,“高级”选项卡下会提供“需要安全传输”选项。 While creating a storage account through the portal, an option under the Advanced tab is Security transfer required. 此属性具有“已禁用”和“已启用”选项。 This property has Disabled and Enabled options. 信息图标包含附加文本,确认此选项可能是我们所需的属性。The info icon has additional text that confirms this option is likely the property we want. 但是,门户不会在此屏幕上显示属性名称。However, the portal doesn't tell us the property name on this screen.

在“查看 + 创建”选项卡上,页面底部提供了“下载自动化模板”链接。 On the Review + create tab, a link is at the bottom of the page to Download a template for automation. 选择该链接会打开用于创建所配置的资源的模板。Selecting the link opens the template that creates the resource we configured. 在这种情况下,我们会看到两段重要信息:In this case, we see two key pieces of information:

...
"supportsHttpsTrafficOnly": {
    "type": "bool"
}
...
"properties": {
    "accessTier": "[parameters('accessTier')]",
    "supportsHttpsTrafficOnly": "[parameters('supportsHttpsTrafficOnly')]"
}
...

此信息告知属性类型,同时确认 supportsHttpsTrafficOnly 是我们正在查找的属性。This information tells us the property type and also confirms supportsHttpsTrafficOnly is the property we're looking for.

GitHub 上的快速入门模板Quickstart templates on GitHub

GitHub 上的 Azure 快速入门模板包含数百个针对不同资源生成的资源管理器模板。The Azure quickstart templates on GitHub has hundreds of Resource Manager templates built for different resources. 使用这些模板能够十分方便地查找所需的资源属性。These templates can be a great way to find the resource property you're looking for. 某些属性似乎是我们所要查找的属性,但它们控制了其他某个对象。Some properties may appear to be what you're looking for, but control something else.

资源参考文档Resource reference docs

若要验证 supportsHttpsTrafficOnly 是否为正确的属性,请在存储提供商网站上查看存储帐户资源的资源管理器模板参考。To validate supportsHttpsTrafficOnly is correct property, check the Resource Manager template reference for the storage account resource on the storage provider. 属性对象包含有效参数的列表。The properties object has a list of valid parameters. 选择 StorageAccountPropertiesCreateParameters-object 链接会显示可接受的属性表。Selecting the StorageAccountPropertiesCreateParameters-object link shows a table of acceptable properties. 若要满足业务要求,supportsHttpsTrafficOnly 必须存在,并且说明必须与所要查找的内容相匹配。supportsHttpsTrafficOnly is present and the description matches what we are looking for to meet the business requirements.

Azure 资源浏览器Azure Resource Explorer

浏览 Azure 资源的另一种方式是使用 Azure 资源浏览器(预览版)。Another way to explore your Azure resources is through the Azure Resource Explorer (Preview). 此工具使用订阅的上下文,因此,你需要在网站中使用 Azure 凭据进行身份验证。This tool uses the context of your subscription, so you need to authenticate to the website with your Azure credentials. 完成身份验证后,可按提供程序、订阅、资源组和资源进行浏览。Once authenticated, you can browse by providers, subscriptions, resource groups, and resources.

找到存储帐户资源并查看属性。Locate a storage account resource and look at the properties. 在此处还可以查看 supportsHttpsTrafficOnly 属性。We see the supportsHttpsTrafficOnly property here as well. 选择“文档”选项卡,可以看到,属性说明与我们在前面的参考文档中找到的信息相匹配。 Selecting the Documentation tab, we see that the property description matches what we found in the reference docs earlier.

查找属性别名Find the property alias

我们已识别资源属性,但需要将该属性映射到别名We've identified the resource property, but we need to map that property to an alias.

可通过多种方式确定 Azure 资源的别名。There are a few ways to determine the aliases for an Azure resource. 本教程将介绍其中的每种方式:We'll look at each for this tutorial:

  • Azure CLIAzure CLI
  • Azure PowerShellAzure PowerShell
  • Azure Resource GraphAzure Resource Graph

Azure CLIAzure CLI

在 Azure CLI 中,az provider 命令组用于搜索资源别名。In Azure CLI, the az provider command group is used to search for resource aliases. 我们将根据前面获取的有关 Azure 资源的详细信息来筛选 Microsoft.Storage 命名空间。We'll filter for the Microsoft.Storage namespace based on the details we got about the Azure resource earlier.

# Login first with az login if not using Cloud Shell

# Get Azure Policy aliases for type Microsoft.Storage
az provider show --namespace Microsoft.Storage --expand "resourceTypes/aliases" --query "resourceTypes[].aliases[].name"

在结果中,查看名为 supportsHttpsTrafficOnly 的存储帐户支持的别名。In the results, we see an alias supported by the storage accounts named supportsHttpsTrafficOnly. 存在此别名意味着可以编写策略来强制实施我们的业务要求!This existence of this alias means we can write the policy to enforce our business requirements!

Azure PowerShellAzure PowerShell

在 Azure PowerShell 中, Get-AzPolicyAlias cmdlet 用于搜索资源别名。In Azure PowerShell, the Get-AzPolicyAlias cmdlet is used to search for resource aliases. 我们将根据前面获取的有关 Azure 资源的详细信息来筛选 Microsoft.Storage 命名空间。We'll filter for the Microsoft.Storage namespace based on the details we got about the Azure resource earlier.

# Login first with Connect-AzAccount if not using Cloud Shell

# Use Get-AzPolicyAlias to list aliases for Microsoft.Storage
(Get-AzPolicyAlias -NamespaceMatch 'Microsoft.Storage').Aliases

与在 Azure CLI 中一样,结果会显示名为 supportsHttpsTrafficOnly 的存储帐户支持的别名。Like Azure CLI, the results show an alias supported by the storage accounts named supportsHttpsTrafficOnly.

Azure Resource GraphAzure Resource Graph

Azure Resource Graph 是一个新的预览版服务。Azure Resource Graph is a new service in Preview. 它是用于查找 Azure 资源属性的另一种方法。It enables another method to find properties of Azure resources. 下面是使用 Resource Graph 查找单个存储帐户的示例查询:Here is a sample query for looking at a single storage account with Resource Graph:

where type=~'microsoft.storage/storageaccounts'
| limit 1
az graph query -q "where type=~'microsoft.storage/storageaccounts' | limit 1"
Search-AzGraph -Query "where type=~'microsoft.storage/storageaccounts' | limit 1"

结果类似于在资源管理器模板中和通过 Azure 资源浏览器查找后获得的结果。The results look similar to what we see in the Resource Manager templates and through the Azure Resource Explorer. 但是,Azure Resource Graph 结果还可通过_投影_ _别名_数组来包含别名详细信息:However, Azure Resource Graph results can also include alias details by projecting the aliases array:

where type=~'microsoft.storage/storageaccounts'
| limit 1
| project aliases
az graph query -q "where type=~'microsoft.storage/storageaccounts' | limit 1 | project aliases"
Search-AzGraph -Query "where type=~'microsoft.storage/storageaccounts' | limit 1 | project aliases"

下面是存储帐户别名的示例输出:Here is example output from a storage account for aliases:

"aliases": {
    "Microsoft.Storage/storageAccounts/accessTier": null,
    "Microsoft.Storage/storageAccounts/accountType": "Standard_LRS",
    "Microsoft.Storage/storageAccounts/enableBlobEncryption": true,
    "Microsoft.Storage/storageAccounts/enableFileEncryption": true,
    "Microsoft.Storage/storageAccounts/encryption": {
        "keySource": "Microsoft.Storage",
        "services": {
            "blob": {
                "enabled": true,
                "lastEnabledTime": "2018-06-04T17:59:14.4970000Z"
            },
            "file": {
                "enabled": true,
                "lastEnabledTime": "2018-06-04T17:59:14.4970000Z"
            }
        }
    },
    "Microsoft.Storage/storageAccounts/encryption.keySource": "Microsoft.Storage",
    "Microsoft.Storage/storageAccounts/encryption.keyvaultproperties.keyname": null,
    "Microsoft.Storage/storageAccounts/encryption.keyvaultproperties.keyvaulturi": null,
    "Microsoft.Storage/storageAccounts/encryption.keyvaultproperties.keyversion": null,
    "Microsoft.Storage/storageAccounts/encryption.services": {
        "blob": {
            "enabled": true,
            "lastEnabledTime": "2018-06-04T17:59:14.4970000Z"
        },
        "file": {
            "enabled": true,
            "lastEnabledTime": "2018-06-04T17:59:14.4970000Z"
        }
    },
    "Microsoft.Storage/storageAccounts/encryption.services.blob": {
        "enabled": true,
        "lastEnabledTime": "2018-06-04T17:59:14.4970000Z"
    },
    "Microsoft.Storage/storageAccounts/encryption.services.blob.enabled": true,
    "Microsoft.Storage/storageAccounts/encryption.services.file": {
        "enabled": true,
        "lastEnabledTime": "2018-06-04T17:59:14.4970000Z"
    },
    "Microsoft.Storage/storageAccounts/encryption.services.file.enabled": true,
    "Microsoft.Storage/storageAccounts/networkAcls": {
        "bypass": "AzureServices",
        "defaultAction": "Allow",
        "ipRules": [],
        "virtualNetworkRules": []
    },
    "Microsoft.Storage/storageAccounts/networkAcls.bypass": "AzureServices",
    "Microsoft.Storage/storageAccounts/networkAcls.defaultAction": "Allow",
    "Microsoft.Storage/storageAccounts/networkAcls.ipRules": [],
    "Microsoft.Storage/storageAccounts/networkAcls.ipRules[*]": [],
    "Microsoft.Storage/storageAccounts/networkAcls.ipRules[*].action": [],
    "Microsoft.Storage/storageAccounts/networkAcls.ipRules[*].value": [],
    "Microsoft.Storage/storageAccounts/networkAcls.virtualNetworkRules": [],
    "Microsoft.Storage/storageAccounts/networkAcls.virtualNetworkRules[*]": [],
    "Microsoft.Storage/storageAccounts/networkAcls.virtualNetworkRules[*].action": [],
    "Microsoft.Storage/storageAccounts/networkAcls.virtualNetworkRules[*].id": [],
    "Microsoft.Storage/storageAccounts/networkAcls.virtualNetworkRules[*].state": [],
    "Microsoft.Storage/storageAccounts/primaryEndpoints": {
        "blob": "https://mystorageaccount.blob.core.windows.net/",
        "file": "https://mystorageaccount.file.core.windows.net/",
        "queue": "https://mystorageaccount.queue.core.windows.net/",
        "table": "https://mystorageaccount.table.core.windows.net/"
    },
    "Microsoft.Storage/storageAccounts/primaryEndpoints.blob": "https://mystorageaccount.blob.core.windows.net/",
    "Microsoft.Storage/storageAccounts/primaryEndpoints.file": "https://mystorageaccount.file.core.windows.net/",
    "Microsoft.Storage/storageAccounts/primaryEndpoints.queue": "https://mystorageaccount.queue.core.windows.net/",
    "Microsoft.Storage/storageAccounts/primaryEndpoints.table": "https://mystorageaccount.table.core.windows.net/",
    "Microsoft.Storage/storageAccounts/primaryEndpoints.web": null,
    "Microsoft.Storage/storageAccounts/primaryLocation": "eastus2",
    "Microsoft.Storage/storageAccounts/provisioningState": "Succeeded",
    "Microsoft.Storage/storageAccounts/sku.name": "Standard_LRS",
    "Microsoft.Storage/storageAccounts/sku.tier": "Standard",
    "Microsoft.Storage/storageAccounts/statusOfPrimary": "available",
    "Microsoft.Storage/storageAccounts/supportsHttpsTrafficOnly": false
}

可以通过 Cloud Shell 使用 Azure Resource Graph(预览版),快速轻松地浏览资源的属性。Azure Resource Graph (Preview) can be used through Cloud Shell, making it a fast and easy way to explore the properties of your resources.

确定要使用的效果Determine the effect to use

确定如何处理不合规的资源几乎与确定最初要评估的项一样重要。Deciding what to do with your non-compliant resources is nearly as important as deciding what to evaluate in the first place. 针对不合规资源做出的每种可能响应称为效果Each possible response to a non-compliant resource is called an effect. 效果控制是否要记录、阻止不合规的资源、在其中追加数据,或者将一个部署关联到其中,使该资源恢复合规状态。The effect controls if the non-compliant resource is logged, blocked, has data appended, or has a deployment associated to it for putting the resource back into a compliant state.

在本示例中,“拒绝”是所需的效果,因为我们不希望在 Azure 环境中创建不合规的资源。For our example, Deny is the effect we want as we do not want non-compliant resources created in our Azure environment. “审核”是策略效果的第一个合理选项,它确定策略在设置为“拒绝”之前的影响。Audit is a good first choice for a policy effect to determine what the impact of a policy is before setting it to Deny. 使更改每个分配的效果变得更轻松的方法之一是将效果参数化。One way to make changing the effect per assignment easier is to parameterize the effect. 有关详细信息,请参阅下面的参数See parameters below for the details on how.

撰写定义Compose the definition

我们现已获得属性详细信息和打算管理的别名。We now have the property details and alias for what we plan to manage. 接下来,我们将撰写策略规则本身。Next, we'll compose the policy rule itself. 如果你不熟悉策略语言,请参考策略定义结构了解如何构建策略定义。If you aren't yet familiar with the policy language, reference policy definition structure for how to structure the policy definition. 以下空白模板显示了策略定义的外观:Here is an empty template of what a policy definition looks like:

{
    "properties": {
        "displayName": "<displayName>",
        "description": "<description>",
        "mode": "<mode>",
        "parameters": {
                <parameters>
        },
        "policyRule": {
            "if": {
                <rule>
            },
            "then": {
                "effect": "<effect>"
            }
        }
    }
}

元数据Metadata

前三个组成部分是策略元数据。The first three components are policy metadata. 由于我们知道要为哪些对象创建规则,因此可以轻松提供这些组成部分的值。These components are easy to provide values for since we know what we are creating the rule for. Mode 主要与标记和资源位置相关。Mode is primarily about tags and resource location. 由于我们不需要将评估范围限制为支持标记的资源,因此将对 mode 使用 all 值。Since we don't need to limit evaluation to resources that support tags, we'll use the all value for mode.

"displayName": "Deny storage accounts not using only HTTPS",
"description": "Deny storage accounts not using only HTTPS. Checks the supportsHttpsTrafficOnly property on StorageAccounts.",
"mode": "all",

parametersParameters

尽管我们未使用参数来更改评估,但确实需要使用一个参数来允许更改效果以进行故障排除。While we didn't use a parameter for changing the evaluation, we do want to use a parameter to allow changing the effect for troubleshooting. 定义 effectType 参数,并将其值限制为 DenyDisabledWe'll define an effectType parameter and limit it to only Deny and Disabled. 这两个选项与我们的业务要求相符。These two options match our business requirements. 完成的参数块如以下示例所示:The finished parameters block looks like this example:

"parameters": {
    "effectType": {
        "type": "string",
        "defaultValue": "Deny",
        "allowedValues": [
            "Deny",
            "Disabled"
        ],
        "metadata": {
            "displayName": "Effect",
            "description": "Enable or disable the execution of the policy"
        }
    }
},

策略规则Policy rule

撰写策略规则是生成自定义策略定义的最后一步。Composing the policy rule is the final step in building our custom policy definition. 我们已指定两条语句用于测试:We've identified two statements to test for:

  • 存储帐户的类型是否为 Microsoft.Storage/storageAccountsThat the storage account type is Microsoft.Storage/storageAccounts
  • 存储帐户的 supportsHttpsTrafficOnly 不为 trueThat the storage account supportsHttpsTrafficOnly isn't true

由于这两条语句都需要为 true,因此将使用 allOf 逻辑运算符Since we need both of these statements to be true, we'll use the allOf logical operator. effectType 参数传递给效果,而不是进行静态声明。We'll pass the effectType parameter to the effect instead of making a static declaration. 完成的规则如以下示例所示:Our finished rule looks like this example:

"if": {
    "allOf": [
        {
            "field": "type",
            "equals": "Microsoft.Storage/storageAccounts"
        },
        {
            "field": "Microsoft.Storage/storageAccounts/supportsHttpsTrafficOnly",
            "notEquals": "true"
        }
    ]
},
"then": {
    "effect": "[parameters('effectType')]"
}

完成的定义Completed definition

定义策略的所有三个组成部分后,下面是完成的定义:With all three parts of the policy defined, here is our completed definition:

{
    "properties": {
        "displayName": "Deny storage accounts not using only HTTPS",
        "description": "Deny storage accounts not using only HTTPS. Checks the supportsHttpsTrafficOnly property on StorageAccounts.",
        "mode": "all",
        "parameters": {
            "effectType": {
                "type": "string",
                "defaultValue": "Deny",
                "allowedValues": [
                    "Deny",
                    "Disabled"
                ],
                "metadata": {
                    "displayName": "Effect",
                    "description": "Enable or disable the execution of the policy"
                }
            }
        },
        "policyRule": {
            "if": {
                "allOf": [
                    {
                        "field": "type",
                        "equals": "Microsoft.Storage/storageAccounts"
                    },
                    {
                        "field": "Microsoft.Storage/storageAccounts/supportsHttpsTrafficOnly",
                        "notEquals": "true"
                    }
                ]
            },
            "then": {
                "effect": "[parameters('effectType')]"
            }
        }
    }
}

完成的定义可用于创建新策略。The completed definition can be used to create a new policy. 门户和每个 SDK(Azure CLI、Azure PowerShell 和 REST API)以不同的方式接受定义,因此,请检查各自的命令,以验证用法是否正确。Portal and each SDK (Azure CLI, Azure PowerShell, and REST API) accept the definition in different ways, so review the commands for each to validate correct usage. 然后使用参数化的效果将定义分配到相应的资源,以管理存储帐户的安全性。Then assign it, using the parameterized effect, to appropriate resources to manage the security of your storage accounts.

审阅Review

在本教程中,你已成功完成以下任务:In this tutorial, you successfully accomplished the following tasks:

  • 确定了业务要求Identified your business requirements
  • 将每个要求映射到了 Azure 资源属性Mapped each requirement to an Azure resource property
  • 将属性映射到了别名Mapped the property to an alias
  • 确定了要使用的效果Determined the effect to use
  • 撰写了策略定义Composed the policy definition

后续步骤Next steps

接下来,请使用自定义策略定义来创建并分配策略:Next, use your custom policy definition to create and assign a policy: