使用Azure policy 来保证Azure 的安全和强制合规

发布于:2025-04-11 ⋅ 阅读:(31) ⋅ 点赞:(0)

在Azure 中部署资源时,一个需要实施的关键方面是护栏。这是在组织级别部署资源时的关键安全要求之一。

我将展示如何通过 Azure Policy 实现护栏,以及如何通过 Terraform 实现。

了解护栏:


在云计算和基础设施管理的背景下,护栏是指一组用于管理云资源部署和运行的规则或策略。

它们是主动措施,旨在确保资源符合合规性标准和安全策略,以便您的组织在公有云空间中安全部署。

它在 Azure 中用于哪些方面?


在 Azure 中,我们可以利用 Azure Policy 来管理资源的配置。

策略驱动的治理是其云采用框架 (CAF) 的核心设计之一。我将在本文结尾简要介绍如何在其企业级模块中实施它。

Azure Policy 采用 JSON 格式编写,用于评估资源是否合规。

仅举一个逻辑书写示例:

    "policyRule": {
            "if": {
                "not": {
                    "field": "location",
                    "in": "[parameters('allowedLocations')]"
                }
            },
            "then": {
                "effect": "deny"
            }
        }

这是一个非常简单的策略。只要资源位于允许的部署位置边界内,您就可以部署。如果您不在允许的位置,则策略会拒绝您的部署。

在 Azure 中,要实施任何策略,都需要两个步骤:

  1. 创建策略定义——这是策略逻辑的来源
  2. 分配策略本身

如何在 Azure 门户中创建和分配策略?


如果您在搜索栏中搜索“策略”,您将看到此页面。

有两个选项:您可以创建“策略定义”或“计划定义”。我们暂时先跳过“计划定义”。选择“创建策略定义”。

对于“策略定义”,其范围可以限定在管理组级别或订阅级别。在这里,我将范围限定在我的订阅级别。

在策略规则部分,您应该会看到

Azure 默认生成此策略规则。在第 11 行,将生效值从“audit”更改为“deny”。这样,只有满足策略规则时才允许创建资源。我们稍后会看到此策略规则的生效情况。

现在,当您搜索策略时,您将找到您的自定义策略。

单击策略链接和分配按钮。

如果您注意到,Azure 允许您将分配范围限定在整个订阅或单个资源组上。

让我们将范围保持在订阅级别。

暂时忽略“高级”选项卡。我将在另一篇文章中详细介绍此设置,届时我将深入探讨 Azure 策略。

您可以使用“高级”选项卡下的资源选择器来缩小范围,但目前处于预览模式。

在“参数”选项卡下,您可以选择允许的位置。在本演示中,我选择了“亚洲东部”。

点击下方的“审核+创建”按钮,然后在后续页面上点击“创建”。

您将在通知中看到此消息。

部署已生效 Azure Policy 的存储帐户


我将使用之前完成的设置。您可以在此处参考该设置。

这是 Terraform 的优势之一;它测试和部署速度更快。:)

在 main.tf 中,我将位置从 southeastasia更改为 eastus。

resource "azurerm_storage_account" "mystorage" {
  name                     = "mystorage${random_string.storage_suffix.result}"
  resource_group_name      = azurerm_resource_group.sample_rg.name
  location                 = "eastus"
  account_tier             = "Standard"
  account_replication_type = "LRS"
}

您将面临此错误。

如果您是新手,您可能会想知道如何理解这一点。

让我将AdditionalInfo之后的部分复制到JSON格式化程序。

{
  "info": {
    "evaluationDetails": {
      "evaluatedExpressions": [
        {
          "expression": "location",
          "expressionKind": "Field",
          "expressionValue": "eastus",
          "operator": "In",
          "path": "location",
          "result": "False",
          "targetValue": [
            "eastasia"
          ]
        }
      ]
    },
    "policyAssignmentDisplayName": "only allow resource deployment in eastasia",
    "policyAssignmentId": "/subscriptions/2f4d1194-1803-4c3b-a1ae-c5ffc2a51bb8/providers/Microsoft.Authorization/policyAssignments/d56725209dca4a9caad93952",
    "policyAssignmentName": "d56725209dca4a9caad93952",
    "policyAssignmentParameters": {
      
    },
    "policyAssignmentScope": "/subscriptions/2f4d1194-1803-4c3b-a1ae-c5ffc2a51bb8",
    "policyDefinitionDisplayName": "only allow resource deployment in eastasia",
    "policyDefinitionEffect": "deny",
    "policyDefinitionId": "/subscriptions/2f4d1194-1803-4c3b-a1ae-c5ffc2a51bb8/providers/Microsoft.Authorization/policyDefinitions/20f2d468-45cc-4086-9f9f-1b884e1476fb",
    "policyDefinitionName": "20f2d468-45cc-4086-9f9f-1b884e1476fb",
    "policyDefinitionVersion": "1.0.0",
    "policyEnrollmentIds": [
      
    ],
    "policyExemptionIds": [
      
    ]
  },
  "type": "PolicyViolation"
}
]

格式化之后就比较合理了,可以看到之前我配置的location不等于eastasia,导致Policy拒绝了资源的创建。

使用 Terraform 创建 Azure Policy


现在您已经看到了 Policy 的实际效果,那么如何在 Terraform 中创建它呢?我们使用 azurerm_policy_definition 资源块。

resource "azurerm_policy_definition" "testpolicy" {
  name         = "TestPolicy"
  policy_type  = "Custom"
  mode         = "All"
  display_name = "Only allow specific locations for resource deployment"
  metadata     = <<METADATA
{
  "category": "General",
  "created_by": "Terraform"
}
METADATA

  policy_rule = <<POLICY_RULE
{
 "if": {
  "not": {
   "field": "location",
   "in": "[parameters('allowedLocations')]"
  }
 },
 "then": {
     "effect": "[parameters('effect')]"
 }
}
POLICY_RULE


  parameters = <<PARAMETERS
{
  "allowedLocations": {
    "type": "Array",
    "metadata": {
      "displayName": "Allowed locations",
      "description": "The list of allowed locations for resources.",
      "strongType": "location"
    }
  },
  "effect": {
    "type": "String",
    "metadata": {
      "displayName": "Effect type for the policy",
      "description": "Effect type for the policy"
    },
    "allowedValues": ["audit", "deny"]
  }
}
PARAMETERS

}

我对之前的策略定义做了一些修改。

我添加了元数据以显示该策略是由 Terraform 创建的,并添加了一个新参数“effect”。这将允许我在策略分配期间切换策略效果。

我通常使用“audit”效果的原因是为了测试策略逻辑。这里我不会详细介绍 Azure Policy 的结构。

使用 terraform plan 验证 Terraform 脚本。如果一切正常,请运行 terraform apply 。

现在您将在portal中看到相同的策略定义,其中包含“created_by: Terraform”元数据和 2 个可用效果。

使用 Terraform 分配 Azure 策略


通过 Terraform 分配策略

resource "azurerm_subscription_policy_assignment" "mypolicy_assignment" {
  name                 = "mypolicy_assignment"
  policy_definition_id = azurerm_policy_definition.testpolicy.id
  subscription_id      = data.azurerm_subscription.current.id
}

还记得我之前提到过策略分配可以发生在两个范围吗?在 Terraform 中,策略分配也有两个不同的资源块:azurerm_subscription_policy_assignment 和 azurerm_resource_group_policy_assignment。

如果您的订阅有一个管理组,并且想要在该级别分配策略,那么还有一个名为 azurerm_management_group_policy_assignment 的资源块。

由于我的策略定义中包含两个参数,因此我必须在策略分配中传入两个参数值。

运行 Terraform Apply 后,您应该会在订阅(或资源组,取决于您的范围)中看到策略分配。

结论


理解并实施防护措施对于确保安全、合规且高效的云环境至关重要。

Azure Policy 为组织提供了一种强制执行合规性和治理标准的方法,而 Terraform 则可用于以可扩展且高效的方式实施策略。