如何使用 Terraform >= 0.12 include/exclude 资源块中的可选属性

How do I include/exclude optional properties within a resource block using Terraform >= 0.12

我是 Terraform 的新手,但我正在尝试执行一些条件逻辑来构建资源块。

到目前为止,我天真的尝试看起来像这样,希望它能让您了解我的意图:

resource "azurerm_kubernetes_cluster_node_pool" "node_pools" {
  { for pool in var.node_pools:
    kubernetes_cluster_id = azurerm_kubernetes_cluster.aks.id
    name                  = pool.name
    vm_size               = pool.vm_size
    max_pods              = pool.max_pods
    vnet_subnet_id        = "${data.azurerm_virtual_network.vnet.id}/subnets/${pool.vnet_subnet_name}"
    os_type               = pool.os_type
    os_disk_size_gb       = pool.os_disk_size_gb
    node_taints           = pool.node_taints
    availability_zones    = pool.availability_zones
    node_labels           = pool.node_labels
    enable_auto_scaling   = pool.enable_auto_scaling
    max_count             = pool.max_count
    min_count             = pool.min_count
    if pool.enable_auto_scaling
  }
    { for pool in var.node_pools:
    kubernetes_cluster_id = azurerm_kubernetes_cluster.aks.id
    name                  = pool.name
    vm_size               = pool.vm_size
    max_pods              = pool.max_pods
    vnet_subnet_id        = "${data.azurerm_virtual_network.vnet.id}/subnets/${pool.vnet_subnet_name}"
    os_type               = pool.os_type
    os_disk_size_gb       = pool.os_disk_size_gb
    node_taints           = pool.node_taints
    availability_zones    = pool.availability_zones
    node_labels           = pool.node_labels
    enable_auto_scaling   = pool.enable_auto_scaling
    node_count            = pool.count
    if !pool.enable_auto_scaling
  }
}

如果 pool.enable_auto_scaling 为真,我想要 max_count 和 min_count 属性。如果它是假的,我只想要 node_count.

如果没有条件逻辑,当 enable_auto_scaling == true 时可能看起来像这样:

resource "azurerm_kubernetes_cluster_node_pool" "node_pools" {
  count                 = length(var.node_pools)
  kubernetes_cluster_id = azurerm_kubernetes_cluster.aks.id
  name                  = var.node_pools[count.index].name
  vm_size               = var.node_pools[count.index].vm_size
  max_pods              = var.node_pools[count.index].max_pods
  vnet_subnet_id        = "${data.azurerm_virtual_network.vnet.id}/subnets/${var.node_pools[count.index].vnet_subnet_name}"
  os_type               = var.node_pools[count.index].os_type
  os_disk_size_gb       = var.node_pools[count.index].os_disk_size_gb
  node_taints           = var.node_pools[count.index].node_taints
  availability_zones    = var.node_pools[count.index].availability_zones
  node_labels           = var.node_pools[count.index].node_labels
  enable_auto_scaling   = var.node_pools[count.index].enable_auto_scaling
  max_count             = var.node_pools[count.index].enable_auto_scaling ? var.node_pools[count.index].max_count : 0
  min_count             = var.node_pools[count.index].enable_auto_scaling ? var.node_pools[count.index].min_count : 0
}

当 enable_auto_scaling == false 时:

resource "azurerm_kubernetes_cluster_node_pool" "node_pools" {
  count                 = length(var.node_pools)
  kubernetes_cluster_id = azurerm_kubernetes_cluster.aks.id
  name                  = var.node_pools[count.index].name
  vm_size               = var.node_pools[count.index].vm_size
  max_pods              = var.node_pools[count.index].max_pods
  vnet_subnet_id        = "${data.azurerm_virtual_network.vnet.id}/subnets/${var.node_pools[count.index].vnet_subnet_name}"
  os_type               = var.node_pools[count.index].os_type
  os_disk_size_gb       = var.node_pools[count.index].os_disk_size_gb
  node_taints           = var.node_pools[count.index].node_taints
  availability_zones    = var.node_pools[count.index].availability_zones
  node_labels           = var.node_pools[count.index].node_labels
  enable_auto_scaling   = var.node_pools[count.index].enable_auto_scaling
  node_count            = var.node_pools[count.index].enable_auto_scaling ? var.node_pools[count.index].min_count : var.node_pools[count.index].count
}

我的 variables.tf 文件包含一个定义如下的变量:

variable "node_pools" {
  type = list(object({
    name                = string
    count               = number
    vm_size             = string
    max_pods            = number
    vnet_subnet_name    = string
    os_type             = string
    os_disk_size_gb     = number
    node_taints         = list(string)
    availability_zones  = list(string)
    node_labels         = map(string)
    enable_auto_scaling = bool
    max_count           = number
    min_count           = number
  }))
}

我在构建语法正确的资源块时遇到问题。

你会如何解决这个问题?

将 max_count / min_count / node_count 设置为零或 null 不起作用,如果属性存在,Azure RM API 将 return 错误, 似乎唯一有效的方法是完全从资源块中排除属性。

对于 resource 块中的资源参数,省略参数并将其设置为 null 是等效的,因此如果您需要“有条件地省略”参数,则可以将问题重述为有条件地将其设置为 null:

var.node_pools[count.index].enable_auto_scaling ? var.node_pools[count.index].min_count : null

这与假结果 0 不同,因为 null 允许提供者决定为该参数使用什么值,而 0 强制设置它为零(因此 Terraform 会将未来的非零值视为 drift 并计划再次将其更改回来)。

您的 azurerm_kubernetes_cluster_node_pool 可以包含所有 min_count、max_count 和 node_count。如果您想不设置它们,请使用 null,提供者将其解释为就好像它们根本没有在资源块中声明一样。

需要修复的具体参数如下:

max_count  = var.node_pools[count.index].enable_auto_scaling ? var.node_pools[count.index].max_count : null
min_count  = var.node_pools[count.index].enable_auto_scaling ? var.node_pools[count.index].min_count : null
node_count = var.node_pools[count.index].enable_auto_scaling ? null: var.node_pools[count.index].count
  • max_countmin_count 默认为 null 如果enable_auto_scalingfalse
  • node_count 默认为 null 如果 enable_auto_scaling正确

在上下文中,这看起来像:

resource "azurerm_kubernetes_cluster_node_pool" "node_pools" {
  count                 = length(var.node_pools)
  kubernetes_cluster_id = azurerm_kubernetes_cluster.aks.id
  name                  = var.node_pools[count.index].name
  vm_size               = var.node_pools[count.index].vm_size
  max_pods              = var.node_pools[count.index].max_pods
  vnet_subnet_id        = "${data.azurerm_virtual_network.vnet.id}/subnets/${var.node_pools[count.index].vnet_subnet_name}"
  os_type               = var.node_pools[count.index].os_type
  os_disk_size_gb       = var.node_pools[count.index].os_disk_size_gb
  node_taints           = var.node_pools[count.index].node_taints
  availability_zones    = var.node_pools[count.index].availability_zones
  node_labels           = var.node_pools[count.index].node_labels
  enable_auto_scaling   = var.node_pools[count.index].enable_auto_scaling
  max_count             = var.node_pools[count.index].enable_auto_scaling ? var.node_pools[count.index].max_count : null
  min_count             = var.node_pools[count.index].enable_auto_scaling ? var.node_pools[count.index].min_count : null
  node_count            = var.node_pools[count.index].enable_auto_scaling ? null: var.node_pools[count.index].count
}