教程:创建自定义策略定义
客户可以通过自定义策略定义来定义自己的 Azure 使用规则。 这些规则通常强制实施:
- 安全做法。
- 成本管理。
- 组织特定的规则(例如命名或位置)。
无论创建自定义策略的业务推动因素是什么,定义新自定义策略的步骤都是相同的。
创建自定义策略之前,请查看策略示例,以确定是否存在符合需求的策略。
遵循以下步骤创建自定义策略:
- 确定业务要求
- 将每个要求映射到 Azure 资源属性
- 将属性映射到别名
- 确定要使用的效果
- 撰写策略定义
先决条件
如果没有 Azure 订阅,请在开始前创建一个试用版订阅。
确定要求
在创建策略定义之前,必须了解策略的意图。 本教程将使用常见的企业安全要求作为目标来演示相关步骤:
- 必须在每个存储帐户中启用 HTTPS。
- 必须在每个存储帐户中启用 HTTP。
要求中应该明确规定“正常”和“不正常”资源状态。
尽管我们已定义资源的预期状态,但尚未定义如何处理不合规的资源。 Azure Policy 支持许多效果。 本教程将业务要求定义为阻止创建不符合业务规则的资源。 为了满足此目标,我们将使用拒绝效果。 我们还需要使用相应的选项来暂停特定分配的策略。 使用已禁用效果,并将其设为策略定义中的参数。
确定资源属性
根据业务要求,要使用 Azure Policy 审核的 Azure 资源为存储帐户。 但是,我们不知道要在策略定义中使用的属性。 Azure Policy 将会评估资源的 JSON 表示形式,因此,需要了解可在该资源中使用的属性。
可通过多种方式确定 Azure 资源的属性。 本教程将介绍其中的每种方式:
- Azure 资源管理器模板(ARM 模板)。
- 导出现有资源。
- 创建体验。
- 快速入门模板 (GitHub)。
- 模板参考文档。
- Azure 资源浏览器。
ARM 模板
可通过多种方式查看包含要管理的属性的 ARM 模板。
门户中的现有资源
查找属性的最简单方法是查找相同类型的现有资源。 已使用所要强制实施的设置配置的资源也会提供用于比较的值。 在 Azure 门户中,找到该特定资源的“设置”中的“导出模板”页。
警告
Azure 门户导出的 ARM 模板无法直接插入到 deployIfNotExists 策略定义中 ARM 模板的 deployment
属性。
针对存储帐户执行此操作会显示以下示例所示的模板:
"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": "chinanorth",
"tags": {
"ms-resource-usage": "azure-cli"
},
"scale": null,
"properties": {
"networkAcls": {
"bypass": "AzureServices",
"virtualNetworkRules": [],
"ipRules": [],
"defaultAction": "Allow"
},
"supportsHttpsTrafficOnly": false,
"encryption": {
"services": {
"file": {
"enabled": true
},
"blob": {
"enabled": true
}
},
"keySource": "Microsoft.Storage"
}
},
"dependsOn": []
}
]
在 properties
下,一个名为 supportsHttpsTrafficOnly
的值设置为 false
。 此属性似乎是我们所要查找的属性。 另外,资源的 type
为 Microsoft.Storage/storageAccounts
。 该类型告知我们,要将策略限定于此类型的资源。
在门户中创建资源
另一种方式是通过门户中的资源创建体验。 通过门户创建存储帐户时,“高级”选项卡下会提供“需要安全传输”选项。 此属性具有“已禁用”和“已启用”选项。 信息图标包含更多文本,该文本确认此选项可能是我们所需的属性。 但是,门户不会在此屏幕上显示属性名称。
在“查看 + 创建”选项卡上,页面底部提供了“下载自动化模板”链接。 选择该链接会打开用于创建所配置的资源的模板。 在这种情况下,我们会看到两段重要信息:
...
"supportsHttpsTrafficOnly": {
"type": "bool"
}
...
"properties": {
"accessTier": "[parameters('accessTier')]",
"supportsHttpsTrafficOnly": "[parameters('supportsHttpsTrafficOnly')]"
}
...
此信息告知属性类型,同时确认 supportsHttpsTrafficOnly
是我们正在查找的属性。
GitHub 上的快速入门模板
GitHub 上的 Azure 快速入门模板包含数百个针对不同资源生成的 ARM 模板。 使用这些模板能够十分方便地查找所需的资源属性。 某些属性似乎是我们所要查找的属性,但它们控制了其他某个对象。
资源参考文档
若要验证 supportsHttpsTrafficOnly
是否为正确的属性,请在存储提供商网站上查看存储帐户资源的 ARM 模板参考。 属性对象包含有效参数的列表。 选择 StorageAccountPropertiesCreateParameters
对象链接会显示可接受的属性的表。 supportsHttpsTrafficOnly
存在,并且描述符合我们的业务需求的要求。
查找属性别名
我们已识别该资源属性,但需要将该属性映射到别名。
可通过多种方式确定 Azure 资源的别名。 本教程将介绍其中的每种方式:
- Azure CLI。
- Azure PowerShell。
Azure CLI
在 Azure CLI 中,az provider
命令组用于搜索资源别名。 我们将根据前面获取的有关 Azure 资源的详细信息来筛选 Microsoft.Storage
命名空间。
# Login first with below commands
az cloud set -n AzureChinaCloud
az login
# Get Azure Policy aliases for type Microsoft.Storage
az provider show --namespace Microsoft.Storage --expand "resourceTypes/aliases" --query "resourceTypes[].aliases[].name"
在结果中,查看名为 supportsHttpsTrafficOnly
的存储帐户支持的别名。 存在此别名意味着可以编写策略来强制实施我们的业务要求!
Azure PowerShell
在 Azure PowerShell 中, Get-AzPolicyAlias
cmdlet 用于搜索资源别名。 将根据前面获取的有关 Azure 资源的详细信息来筛选 Microsoft.Storage
命名空间。
# Login first with Connect-AzAccount -Environment AzureChinaCloud cmdlet
Connect-AzAccount -Environment AzureChinaCloud
# Use Get-AzPolicyAlias to list aliases for Microsoft.Storage
(Get-AzPolicyAlias -NamespaceMatch 'Microsoft.Storage').Aliases
与在 Azure CLI 中一样,结果会显示名为 supportsHttpsTrafficOnly
的存储帐户支持的别名。
确定要使用的效果
确定如何处理不合规的资源几乎与确定最初要评估的项一样重要。 针对不合规资源做出的每种可能响应称为效果。 效果控制是否要记录、阻止不合规的资源、在其中追加数据,或者将一个部署关联到其中,使该资源恢复合规状态。
在本示例中,deny
是所需的效果,因为我们不希望在 Azure 环境中创建不合规的资源。 “审核”是策略效果的第一个合理选项,它确定策略在设置为 deny
之前的影响。 使更改每个分配的效果变得更轻松的方法之一是将效果参数化。 有关详细信息,请参阅参数。
撰写定义
我们现已获得属性详细信息和打算管理的别名。 接下来,我们将撰写策略规则本身。 如果你不熟悉策略语言,请参考策略定义结构了解如何构建策略定义。 以下空白模板显示了策略定义的外观:
{
"properties": {
"displayName": "<displayName>",
"description": "<description>",
"mode": "<mode>",
"parameters": {
<parameters>
},
"policyRule": {
"if": {
<rule>
},
"then": {
"effect": "<effect>"
}
}
}
}
Metadata
前三个组成部分是策略元数据。 由于我们知道要为哪些对象创建规则,因此可以轻松提供这些组成部分的值。 Mode 主要与标记和资源位置相关。 由于我们不需要将评估范围限制为支持标记的资源,因此将为 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",
参数
尽管我们未使用参数来更改评估,但确实需要使用一个参数来允许更改 effect
以进行故障排除。 定义一个 effectType
参数并将其限制为仅限 deny
和 disabled
。 这两个选项与我们的业务要求相符。 完成的参数块如以下示例所示:
"parameters": {
"effectType": {
"type": "string",
"defaultValue": "Deny",
"allowedValues": [
"Deny",
"Disabled"
],
"metadata": {
"displayName": "Effect",
"description": "Enable or disable the execution of the policy"
}
}
},
策略规则
撰写策略规则是生成自定义策略定义的最后一步。 我们已指定两条语句用于测试:
- 存储帐户
type
是Microsoft.Storage/storageAccounts
。 - 存储帐户
supportsHttpsTrafficOnly
不是true
。
由于这两条语句都需要为 true,因此请使用 allOf
逻辑运算符。 将 effectType
参数传递给效果,而不是进行静态声明。 完成的规则如以下示例所示:
"if": {
"allOf": [
{
"field": "type",
"equals": "Microsoft.Storage/storageAccounts"
},
{
"field": "Microsoft.Storage/storageAccounts/supportsHttpsTrafficOnly",
"notEquals": "true"
}
]
},
"then": {
"effect": "[parameters('effectType')]"
}
完成的定义
定义策略的所有三个组成部分后,下面是完成的定义:
{
"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')]"
}
}
}
}
完成的定义可用于创建新策略。 门户和每个 SDK(Azure CLI、Azure PowerShell 和 REST API)以不同的方式接受定义,因此,请检查各自的命令,以验证用法是否正确。 然后使用参数化的效果将定义分配到相应的资源,以管理存储帐户的安全性。
清理资源
如果今后不再使用本教程中的资源,请使用以下步骤删除创建的所有分配或定义:
在“Azure Policy”页左侧的“创作”下选择“定义”(如果尝试删除分配,则选择“分配”) 。
搜索要删除的新计划或策略定义(或分配)。
右键单击定义(或分配)对应的行或选择其末尾的省略号,然后选择“删除定义”(或“删除分配”)。
审阅
在本教程中,你已成功完成以下任务:
- 确定了业务要求
- 将每个要求映射到了 Azure 资源属性
- 将属性映射到了别名
- 确定了要使用的效果
- 撰写了策略定义
后续步骤
接下来,请使用自定义策略定义来创建并分配策略: