使用Terraform/Azure Policy限制仅Prod订阅创建Savings Plan
限制仅Prod订阅创建Azure Savings Plan的Terraform策略修正方案
问题背景
租户内有10余个分布在不同管理组的订阅,需要通过Terraform配置Azure Policy,仅允许Prod订阅创建Savings Plan。当前编写的策略未拦截非Prod订阅的创建操作,核心问题集中在资源类型路径和订阅ID判断逻辑上。
原策略代码:
resource "azurerm_policy_definition" "restrict_savings_plan" { name = "restrict-savings-plan-creation" policy_type = "Custom" mode = "All" display_name = "Restrict Savings Plan Creation to Prod Subscription" policy_rule = <<POLICY { "if": { "allOf": [ { "field": "type", "equals": "Microsoft.Billing billingAccounts/savingsPlanOrders/savingsPlans"//Not sure if this is correct }, { "value": "[subscription().Id]", //Kinda iffy about this "notEquals": "Prod-subscription-id" } ] }, "then": { "effect": "deny" } } POLICY }
修正说明与代码
1. 修正Savings Plan资源类型
原代码中资源类型的格式错误,正确的Azure Savings Plan资源类型应为Microsoft.Billing/savingsPlanOrders/savingsPlans(用斜杠分隔,而非空格),这是策略能匹配到Savings Plan资源的前提。
2. 修正订阅ID判断逻辑
原代码中用value引用subscription().Id的写法有误,直接用field: "subscriptionId"即可获取当前订阅ID,同时注意Azure表达式中subscription().id的id是小写(原代码大写Id会导致解析失败)。
修正后的完整代码
resource "azurerm_policy_definition" "restrict_savings_plan" { name = "restrict-savings-plan-creation" policy_type = "Custom" mode = "All" display_name = "Restrict Savings Plan Creation to Prod Subscription" policy_rule = <<POLICY { "if": { "allOf": [ { "field": "type", "equals": "Microsoft.Billing/savingsPlanOrders/savingsPlans" }, { "field": "subscriptionId", "notEquals": "your-prod-subscription-guid-here" } ] }, "then": { "effect": "deny" } } POLICY }
额外注意事项
- 把代码中的
your-prod-subscription-guid-here替换为实际的Prod订阅GUID(比如xxxx-xxxx-xxxx-xxxx格式) - 策略模式使用
All是正确的,因为Savings Plan属于全局资源,需要该模式才能覆盖 - 部署后建议将策略分配到包含所有订阅的根管理组,或者直接分配到所有非Prod订阅,确保策略覆盖范围正确
内容的提问来源于stack exchange,提问作者VAP
相关产品推荐
相关产品推荐

