我目前正在尝试使用 Terraform 将策略计划定义部署到 Azure。除了我使用整数参数值的策略外,一切正常。为了确定问题,我创建了一个小示例来测试部署:
main.tf
resource "azurerm_policy_set_definition" "instance" {
name = "INT TEST"
display_name = "INT TEST"
policy_type = "Custom"
management_group_id = "/providers/microsoft.management/managementgroups/example_management_group"
parameters = jsonencode(var.initiative_params_int)
dynamic "policy_definition_reference" {
for_each = var.initiative_with_int_parameters
iterator = policy_definition
content {
policy_definition_id = policy_definition.key
parameter_values = length(policy_definition.value) == 0 ? null : jsonencode({ for name, value in tomap(policy_definition.value) : name => { "value" = value } })
}
}
}
变量.tf
variable "initiative_with_int_parameters" {
default = {
"/providers/Microsoft.Authorization/policyDefinitions/cee51871-e572-4576-855c-047c820360f0" = {
effect = "[parameters('denyAll')]"
minimumRSAKeySize = 2048
}
"/providers/Microsoft.Authorization/policyDefinitions/82067dbb-e53b-4e06-b631-546d197452d9" = {
effect = "[parameters('denyAll')]"
minimumRSAKeySize = 2048
}
"/providers/Microsoft.Authorization/policyDefinitions/12430be1-6cc8-4527-a9a8-e3d38f250096" = {
effect = "[parameters('denyAll')]"
modeRequirement = "Prevention"
}
}
}
variable "initiative_params_int" {
default = {
denyAll = {
type = "String"
defaultValue = "Deny"
metadata = {
displayName = "Deny All"
description = "Deny all requests"
}
}
}
}
当我尝试运行“terraform apply”并输入“yes”时,出现以下错误:
Error: creating Policy Set Definition "INT TEST": policy.SetDefinitionsClient#CreateOrUpdateAtManagementGroup: Failure responding to request: StatusCode=400 -- Original Error: autorest/azure: Service returned an error. Status=400 Code="InvalidPolicyParameterType" Message="The policy parameter 'minimumRSAKeySize' does not match the expected parameter type defined in the policy definition 'cee51871-e572-4576-855c-047c820360f0'. Details 'The expected policy parameter type: 'Integer'. The actual policy parameter type 'String'.'."
│
│ with azurerm_policy_set_definition.instance,
│ on main.tf line 137, in resource "azurerm_policy_set_definition" "instance":
│ 137: resource "azurerm_policy_set_definition" "instance" {
当我省略上述两个策略而只使用第三个时,一切正常,部署成功。
我认为显式类型转换可能会有所帮助
minimumRSAKeySize = tonumber(2048)
但显然我无法对整数值进行类型转换。我还尝试将“minimumRSAKeySize”的值输入为字符串,但随后出现了上述相同的错误。
我怀疑这里的问题是您没有为输入变量定义类型约束,因此 Terraform 试图猜测您想要的类型约束,但猜测不正确并得出结论认为您打算声明
type = map(map(string))
,因此强制将 minimumRSAKeySize
转换为字符串。
如果这是问题所在,那么您应该能够通过在每个输入变量上声明一个显式类型约束来解决它,这样 Terraform 就不需要猜测了。例如:
variable "initiative_with_int_parameters" {
type = map(object({
effect = string
minimumRSAKeySize = optional(number)
modeRequirement = optional(string)
}))
default = {
"/providers/Microsoft.Authorization/policyDefinitions/cee51871-e572-4576-855c-047c820360f0" = {
effect = "[parameters('denyAll')]"
minimumRSAKeySize = 2048
}
"/providers/Microsoft.Authorization/policyDefinitions/82067dbb-e53b-4e06-b631-546d197452d9" = {
effect = "[parameters('denyAll')]"
minimumRSAKeySize = 2048
}
"/providers/Microsoft.Authorization/policyDefinitions/12430be1-6cc8-4527-a9a8-e3d38f250096" = {
effect = "[parameters('denyAll')]"
modeRequirement = "Prevention"
}
}
}
variable "initiative_params_int" {
type = map(object({
type = string
defaultValue = string
metadata = object({
displayName = string
description = string
})
}))
default = {
denyAll = {
type = "String"
defaultValue = "Deny"
metadata = {
displayName = "Deny All"
description = "Deny all requests"
}
}
}
}
一般来说,所有 Terraform 变量都应该有类型约束。 Terraform 不需要它来向后兼容具有更有限类型系统的非常旧版本的 Terraform,但是准确地告诉 Terraform 您想要的类型意味着您的配置将更具可读性,Terraform 不需要猜测什么类型约束你的意思是,如果你使用不正确的值来定义这个变量,Terraform 将能够给你更好的反馈。