教程:通过 Azure Policy 管理标记治理

标记是将 Azure 资源组整理到分类中的关键部分。 遵循标记管理最佳做法时,标记可以作为使用 Azure Policy 应用业务策略的基础。 无论你使用标记的方式和原因是什么,重要的是你可以在 Azure 资源上快速添加、更改和删除这些标记。 若要了解你的 Azure 资源是否支持标记,请参阅标记支持

Azure Policy 的修改效果旨在帮助管理标记,而无论你处于资源调控的哪个阶段。 Modify 在以下情况下有帮助:

  • 你不熟悉云,并且没有标记治理经验。
  • 已经拥有数以千计的资源,但没有标记治理经验。
  • 已经具有需要更改的现有分类。

在本教程中,请完成以下任务:

  • 确定业务要求
  • 将每个要求映射到策略定义
  • 将标记策略分组为一个计划

先决条件

需要一个 Azure 订阅才能完成此教程。 如果没有 Azure 订阅,请在开始之前创建一个试用版订阅

确定要求

与任何良好的治理控制实现一样,要求应源自业务需求,并且在创建技术控制之前应该得到充分理解。 对于本方案教程,以下各项是我们的业务要求:

  • 所有资源上有两个所需标记:CostCenterEnv
  • CostCenter 必须在所有容器和单个资源上
    • 资源继承自它们所在的容器,但可以单独重写。
  • Env 必须在所有容器和单个资源上。
    • 资源根据容器命名方案确定环境,并且不能重写。
    • 容器中的所有资源都属于相同环境。

配置 CostCenter 标记

就特定于由 Azure Policy 管理的 Azure 环境而言,CostCenter 标记要求会调用以下结果:

  • 拒绝缺少 CostCenter 标记的资源组。
  • 修改资源以在缺少 CostCenter 标记时从父资源组添加此标记

拒绝缺少 CostCenter 标记的资源组

由于资源组的 CostCenter 不能由资源组的名称确定,因此必须在创建资源组的请求中定义标记。 具有拒绝效果的以下策略规则会阻止创建或更新没有 CostCenter 标记的资源组

"if": {
  "allOf": [
    {
      "field": "type",
      "equals": "Microsoft.Resources/subscriptions/resourceGroups"
    },
    {
      "field": "tags['CostCenter']",
      "exists": false
    }
  ]
},
"then": {
  "effect": "deny"
}

注意

由于此策略规则以资源组为目标,策略定义上的 mode 必须是“All”,而不是“Indexed”。

修改资源以在缺少 CostCenter 标记时继承此标记

第二个“CostCenter”需要的是任何资源在缺少标记时从父资源组继承标记。 如果已在资源上定义了标记,则即使该标记与父资源组不同,也必须将其单独保留。 以下策略规则使用修改

"policyRule": {
  "if": {
    "field": "tags['CostCenter']",
    "exists": "false"
  },
  "then": {
    "effect": "modify",
    "details": {
      "roleDefinitionIds": [
        "/providers/microsoft.authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c"
      ],
      "operations": [
        {
          "operation": "add",
          "field": "tags['CostCenter']",
          "value": "[resourcegroup().tags['CostCenter']]"
        }
      ]
    }
  }
}

此策略规则使用 add 操作,而不是 addOrReplace,因为我们不想要在修正现有资源时更改标记值。 它还使用 [resourcegroup()] 模板函数从父资源组获取标记值。

备注

由于此策略规则以支持标记的资源为目标,因此策略定义上的模式必须为“已编入索引”。 此配置还确保此策略跳过资源组。

配置 Env 标记

就特定于由 Azure Policy 管理的 Azure 环境而言,Env 标记要求会调用以下结果:

  • 根据资源组的命名方案修改资源组上的 Env 标记
  • 将资源组中所有资源的 Env 标记修改为与父资源组相同

基于名称修改资源组 Env 标记

对于在 Azure 环境中存在的每个环境,需要修改策略。 每个策略的“modify”策略类似于以下策略定义:

"policyRule": {
  "if": {
    "allOf": [
      {
        "field": "type",
        "equals": "Microsoft.Resources/subscriptions/resourceGroups"
      },
      {
        "field": "name",
        "like": "prd-*"
      },
      {
        "field": "tags['Env']",
        "notEquals": "Production"
      }
    ]
  },
  "then": {
    "effect": "modify",
    "details": {
      "roleDefinitionIds": [
        "/providers/microsoft.authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c"
      ],
      "operations": [
        {
          "operation": "addOrReplace",
          "field": "tags['Env']",
          "value": "Production"
        }
      ]
    }
  }
}

注意

由于此策略规则以资源组为目标,策略定义上的 mode 必须是“All”,而不是“Indexed”。

此策略只将资源组与用于 prd- 生产资源的示例命名方案匹配。 更复杂的命名方案可以通过几个“match”条件而不是本例中的单个“like”条件来实现。

修改资源以继承 Env 标记

业务需求要求所有资源都具有与其父资源组相同的 Env 标记。 无法重写此标记,因此请使用具有修改效果的 addOrReplace 操作。 示例“modify”策略类似于以下规则:

"policyRule": {
  "if": {
    "anyOf": [
      {
        "field": "tags['Env']",
        "notEquals": "[resourcegroup().tags['Env']]"
      },
      {
        "field": "tags['Env']",
        "exists": false
      }
    ]
  },
  "then": {
    "effect": "modify",
    "details": {
      "roleDefinitionIds": [
        "/providers/microsoft.authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c"
      ],
      "operations": [
        {
          "operation": "addOrReplace",
          "field": "tags['Env']",
          "value": "[resourcegroup().tags['Env']]"
        }
      ]
    }
  }
}

注意

由于此策略规则以支持标记的资源为目标,因此策略定义上的 mode 必须为“Indexed”。 此配置还确保此策略跳过资源组。

此策略规则查找没有 Env 标记的父资源组值或缺少 Env 标记的任何资源。 匹配资源的 Env 标记设置为了父资源组值,即使标记已在资源上但具有不同的值也是如此。

分配计划并修正资源

创建标记策略后,将它们加入到标记治理的单个计划中,并将其分配给管理组或订阅。 该计划和包含的策略随后会评估现有资源的合规性,并改变与策略规则中的“if”属性相匹配的新资源或更新资源的请求。 但是,该策略不会自动使用定义的标记更改更新现有的不合规资源。

deployIfNotExists 策略一样,“modify”策略使用修正任务来更改现有的不合规资源。 按照有关如何修正资源的说明来识别不合规的“modify”资源,然后将标记更正为已定义的分类。

清理资源

如果今后不再使用本教程中的资源,请使用以下步骤删除创建的所有分配或定义:

  1. 在“Azure Policy”页左侧的“创作”下选择“定义”(如果尝试删除分配,则选择“分配”) 。

  2. 搜索要删除的新计划或策略定义(或分配)。

  3. 右键单击定义或分配对应的行或选择其末尾的省略号,然后选择“删除定义”或“删除分配”。

审阅

本教程介绍了以下任务:

  • 确定了业务要求
  • 将每个要求映射到策略定义
  • 将标记策略分组为一个计划

后续步骤

若要了解有关策略定义结构的详细信息,请查看以下文章: