在Azure 中部署资源时,一个需要实施的关键方面是护栏。这是在组织级别部署资源时的关键安全要求之一。
我将展示如何通过 Azure Policy 实现护栏,以及如何通过 Terraform 实现。
了解护栏:
在云计算和基础设施管理的背景下,护栏是指一组用于管理云资源部署和运行的规则或策略。
它们是主动措施,旨在确保资源符合合规性标准和安全策略,以便您的组织在公有云空间中安全部署。
它在 Azure 中用于哪些方面?
在 Azure 中,我们可以利用 Azure Policy 来管理资源的配置。
策略驱动的治理是其云采用框架 (CAF) 的核心设计之一。我将在本文结尾简要介绍如何在其企业级模块中实施它。
Azure Policy 采用 JSON 格式编写,用于评估资源是否合规。
仅举一个逻辑书写示例:
"policyRule": {
"if": {
"not": {
"field": "location",
"in": "[parameters('allowedLocations')]"
}
},
"then": {
"effect": "deny"
}
}
这是一个非常简单的策略。只要资源位于允许的部署位置边界内,您就可以部署。如果您不在允许的位置,则策略会拒绝您的部署。
在 Azure 中,要实施任何策略,都需要两个步骤:
- 创建策略定义——这是策略逻辑的来源
- 分配策略本身
如何在 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 则可用于以可扩展且高效的方式实施策略。