我正在尝试通过 AzureRM Terraform 提供商的 azurerm-resource-group-template-deployment 资源使用 ARM 模板创建一些治理规则(Microsoft Defender for Cloud),但是我找不到像往常一样处理该问题的方法抱怨模板内容有所不同。这是资源和模板定义:
locals {
scope_id = var.scope_id
scope_name = var.scope_name
rules = {
for rule in var.governance_rules : rule.priority == null ? 1 : rule.priority => {
rule_suffix_name = rule.rule_suffix_name,
is_disabled = rule.is_disabled == null ? false : rule.is_disabled,
owner_email_address = rule.owner_email_address,
priority = rule.priority == null ? 1 : rule.priority,
condition_set = rule.condition_set == null ? "[\"High\"]" : rule.condition_set,
grace_period_enabled = rule.grace_period_enabled == null ? true : rule.grace_period_enabled,
disable_manager_notification = rule.disable_manager_notification == null ? true : rule.disable_manager_notification,
disable_owner_notification = rule.disable_owner_notification == null ? false : rule.disable_owner_notification,
remediation_time_frame = rule.remediation_time_frame == null ? "30.00:00:00" : rule.remediation_time_frame,
}
}
}
resource "azurerm_resource_group_template_deployment" "governance_rules" {
for_each = local.rules
name = lower("${local.scope_name}-${each.value.rule_suffix_name}-rule")
resource_group_name = var.governance_rules_rg
deployment_mode = "Complete"
template_content = <<TEMPLATE
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [
{
"type": "Microsoft.Security/governanceRules",
"apiVersion": "2022-01-01-preview",
"name": "${uuid()}",
"scope": "${local.scope_id}",
"properties": {
"conditionSets": [
{
"conditions": [
{
"property": "properties.metadata.severity",
"value": "${jsonencode(each.value.condition_set)}",
"operator": "In"
}
]
}
],
"description": "Governance Rules",
"displayName": "${jsonencode(lower("${local.scope_name}-${each.value.rule_suffix_name}-rule"))}",
"excludedScopes": [],
"governanceEmailNotification": {
"disableManagerEmailNotification": ${jsonencode(each.value.disable_manager_notification)},
"disableOwnerEmailNotification": ${jsonencode(each.value.disable_owner_notification)}
},
"includeMemberScopes": false,
"isDisabled": ${jsonencode(each.value.is_disabled)},
"isGracePeriod": ${jsonencode(each.value.grace_period_enabled)},
"metadata": {},
"ownerSource": {
"type": "Manually",
"value": "${jsonencode(each.value.owner_email_address)}"
},
"remediationTimeframe": "${jsonencode(each.value.remediation_time_frame)}",
"rulePriority": ${jsonencode(each.value.priority)},
"ruleType": "Integrated",
"sourceResourceType": "Assessments"
}
}
],
}
TEMPLATE
}
variable "governance_rules" {
type = list(object({
condition_set = optional(string)
disable_manager_notification = optional(bool)
disable_owner_notification = optional(bool)
grace_period_enabled = optional(bool)
is_disabled = optional(bool)
owner_email_address = string
priority = optional(number)
remediation_time_frame = optional(string)
rule_suffix_name = string
}))
}
计划是相应生成的,但是应用失败,错误如下:
│错误:扩展`template_content`:对象键:值对后的无效字符'\'
│ with module.module_name.module.subscription_governance_rules.azurerm_resource_group_template_deployment.governance_rules["1"],
│modules/governance-rules/main.tf 第 20 行,资源“azurerm_resource_group_template_deployment”“governance_rules”:
│20:资源“azurerm_resource_group_template_deployment”“governance_rules”{
最初我尝试过不使用双引号和 jsonencode,但即使添加它们之后问题仍然存在。我也尝试了许多不同的组合,但是错误总是相同的,并且不是描述性的,因为它甚至没有告诉错误的行。
我已向 API 发出请求,以获取从门户手动创建的现有规则的 ARM 模板作为参考。看起来像这样:
{
"value": [
{
"id": "/providers/microsoft.management/managementgroups/mgdefault/providers/microsoft.security/governancerules/<uuid>",
"name": "<governance_rule_uuid>",
"type": "microsoft.security/governancerules",
"properties": {
"tenantId": "<tenant_id>",
"displayName": "temprule",
"description": "description",
"isDisabled": false,
"ruleType": "Integrated",
"rulePriority": 100,
"remediationTimeframe": "30.00:00:00",
"isGracePeriod": true,
"ownerSource": {
"type": "Manually",
"value": "[email protected]"
},
"conditionSets": [
{
"conditions": [
{
"property": "properties.metadata.severity",
"value": "[\"High\"]",
"operator": "In"
}
]
}
],
"sourceResourceType": "Assessments",
"excludedScopes": [],
"includeMemberScopes": false,
"governanceEmailNotification": {
"disableManagerEmailNotification": true,
"disableOwnerEmailNotification": true,
"emailNotificationDayOfWeek": "Sunday"
}
}
}
]
}
文档中的资源格式如下所示:
{
"type": "Microsoft.Security/governanceRules",
"apiVersion": "2022-01-01-preview",
"name": "string",
"scope": "string",
"properties": {
"conditionSets": [ object ],
"description": "string",
"displayName": "string",
"excludedScopes": [ "string" ],
"governanceEmailNotification": {
"disableManagerEmailNotification": "bool",
"disableOwnerEmailNotification": "bool"
},
"includeMemberScopes": "bool",
"isDisabled": "bool",
"isGracePeriod": "bool",
"metadata": {},
"ownerSource": {
"type": "string",
"value": "string"
},
"remediationTimeframe": "string",
"rulePriority": "int",
"ruleType": "string",
"sourceResourceType": "Assessments"
}
}
有什么想法可以让这项工作发挥作用吗?
提前致谢!
我尝试通过 AzureRM Terraform 提供程序的 azurerm-resource-group-template-deployment 资源使用 ARM 模板创建一些治理规则。我能够成功地提供要求。
您遇到的错误“对象键:值对后的无效字符''”表示您的 JSON 模板中可能存在转义字符问题。为了解决此问题并为您提供符合您要求的 Terraform 配置,我将根据提供的 ARM 模板重写 Terraform 代码。
对于要配置的配置,我遵循下面提到的结构以及所有相关文件。
my_terraform_project/
├── modules/
│ └── governance_rules/
│ ├── main.tf
│ ├── variables.tf
│ └── outputs.tf
├── main.tf
├── variables.tf
├── outputs.tf
├── terraform.tfvars
└── provider.tf
我的terraform配置文件:
terraform_project/main.tf
# Module for creating governance rules
module "governance_rules" {
source = "./modules/governance_rules"
scope_id = var.scope_id
scope_name = var.scope_name
governance_rules_rg = var.governance_rules_rg
governance_rules = var.governance_rules
}
# Define other resources or configurations as needed
terraform_project/variables.tf
# variables.tf
variable "scope_id" {
description = "The ID of the scope."
type = string
}
variable "scope_name" {
description = "The name of the scope."
type = string
}
variable "governance_rules_rg" {
description = "The name of the resource group where governance rules will be deployed."
type = string
}
variable "governance_rules" {
type = list(object({
condition_set = optional(list(string))
disable_manager_notification = optional(bool)
disable_owner_notification = optional(bool)
grace_period_enabled = optional(bool)
is_disabled = optional(bool)
owner_email_address = string
priority = optional(number)
remediation_time_frame = optional(string)
rule_suffix_name = string
}))
}
# Define other global variables if needed
terraform_project/terraform.tfvars:
scope_id = "/subscriptions/b83c1ed3-c5b6-***b-***a-2b83*****c23f"
scope_name = "My Azure Subscription"
governance_rules_rg = "v-sakavya"
governance_rules = [
{
rule_suffix_name = "Rule1"
owner_email_address = "[email protected]"
# Other rule properties
},
{
rule_suffix_name = "Rule2"
owner_email_address = "[email protected]"
# Other rule properties
},
# Add more rules as needed
]
terraform_project/modules/governance_rules/variables.tf:
# modules/governance_rules/variables.tf
variable "scope_id" {
description = "The ID of the scope."
type = string
}
variable "scope_name" {
description = "The name of the scope."
type = string
}
variable "governance_rules_rg" {
description = "The name of the resource group where governance rules will be deployed."
type = string
}
variable "governance_rules" {
type = list(object({
condition_set = optional(list(string))
disable_manager_notification = optional(bool)
disable_owner_notification = optional(bool)
grace_period_enabled = optional(bool)
is_disabled = optional(bool)
owner_email_address = string
priority = optional(number)
remediation_time_frame = optional(string)
rule_suffix_name = string
}))
}
# Define other module-specific variables if needed
terraform_project/modules/governance_rules/main.tf:
# modules/governance_rules/main.tf
locals {
filtered_rules = {
for rule in var.governance_rules :
rule.priority => {
rule_suffix_name = rule.rule_suffix_name
is_disabled = coalesce(rule.is_disabled, false)
owner_email_address = rule.owner_email_address
priority = coalesce(rule.priority, 1)
condition_set = coalesce(rule.condition_set, ["High"])
grace_period_enabled = coalesce(rule.grace_period_enabled, true)
disable_manager_notification = coalesce(rule.disable_manager_notification, true)
disable_owner_notification = coalesce(rule.disable_owner_notification, false)
remediation_time_frame = coalesce(rule.remediation_time_frame, "30.00:00:00")
} if rule.priority != null
}
}
resource "azurerm_resource_group_template_deployment" "governance_rules" {
for_each = local.filtered_rules # Use local.filtered_rules here
name = lower("${var.scope_name}-${each.value.rule_suffix_name}-rule")
resource_group_name = var.governance_rules_rg
deployment_mode = "Complete"
template_content = jsonencode({
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [
{
"type": "Microsoft.Security/governanceRules",
"apiVersion": "2022-01-01-preview",
"name": "${uuid()}",
"scope": var.scope_id,
"properties": {
"conditionSets": [
{
"conditions": [
{
"property": "properties.metadata.severity",
"value": each.value.condition_set,
"operator": "In"
}
]
}
],
"description": "Governance Rules",
"displayName": "${var.scope_name}-${each.value.rule_suffix_name}-rule",
"excludedScopes": [],
"governanceEmailNotification": {
"disableManagerEmailNotification": each.value.disable_manager_notification,
"disableOwnerEmailNotification": each.value.disable_owner_notification
},
"includeMemberScopes": false,
"isDisabled": each.value.is_disabled,
"isGracePeriod": each.value.grace_period_enabled,
"metadata": {},
"ownerSource": {
"type": "Manually",
"value": each.value.owner_email_address
},
"remediationTimeframe": each.value.remediation_time_frame,
"rulePriority": each.value.priority,
"ruleType": "Integrated",
"sourceResourceType": "Assessments"
}
}
]
})
}
输出:
命令
terraform_plan:
命令
terraform_apply -var-file .\terraform.tfvars