azure 地形块中的可选变量

2hh7jdfx  于 2023-03-19  发布在  其他
关注(0)|答案(2)|浏览(122)

我想部署一个**azurerm_linux_function_app**,根据访问限制,我需要一个来自VNET的限制,其他时候我需要一个IP地址限制。代码为:

resource "azurerm_linux_function_app" "function_app" {
  name                = var.function_app_name
  resource_group_name = var.resource_group_name
  location            = "northeurope"
    
  storage_account_name       = var.storage_account_name
  service_plan_id            = var.service_plan_id
    
  identity {
    type = "SystemAssigned"
  }

  site_config {
    dynamic "ip_restriction" {
      for_each = var.enable_restriction == true ? [1] : []
        content {
          virtual_network_subnet_id = var.subnet_id
          ip_address                = var.ip_address
        }
    }

    application_stack {
      python_version = "3.8"
    }
  }
}

在名为“ip_restriction”的块中,我希望同时使用两个变量,但有时我希望使用VNET id,而其他时候需要IP地址。

fkaflof6

fkaflof61#

你能为每种情况设置2个动态块吗?这些变量中只有一个会被设置,对吗?

resource "azurerm_linux_function_app" "function_app" {
  name                = var.function_app_name
  resource_group_name = var.resource_group_name
  location            = "northeurope"

  storage_account_name       = var.storage_account_name
  service_plan_id            = var.service_plan_id

  identity {
    type = "SystemAssigned"
  }
  site_config {
    dynamic "ip_restriction"{
      for_each = var.enable_restriction == true && var.subnet_id != "" ? [1] : []
      content {
        virtual_network_subnet_id = var.subnet_id
      }
    }
    dynamic "ip_restriction"{
      for_each = var.enable_restriction == true && var.ip_address != "" ? [1] : []
      content {
        ip_address                = var.ip_address
      }
    }
    application_stack {
      python_version = "3.8"
    }
  }
}
esyap4oy

esyap4oy2#

对于resource块内的参数以及嵌套在其中的块(如ip_restriction),将值null赋给参数完全等同于将其完全省略:从提供者的Angular 来看,它无法区分,因为Terraform语言在向提供者发送配置时会自动发送null来表示“未设置”。
因此,如果你确保你的两个变量都是null,当你想让他们被重置时,你会得到正确的行为,基本上是“免费的”。null是在Terraform中表示一个值缺失的正确方法;空字符串不适于表示“unset”,因为空字符串对于某些自变量是有效值。
例如:

variable "subnet_id" {
  type    = string
  default = null
}

variable "ip_address" {
  type    = string
  default = null
}

resource "azurerm_linux_function_app" "function_app" {
  # ...

  site_config {
    dynamic "ip_restriction" {
      for_each = var.enable_restriction == true ? [1] : []
      content {
        # If either variable is null then the provider will
        # treat it as if unset.
        virtual_network_subnet_id = var.subnet_id
        ip_address                = var.ip_address
      }
    }

    # ...
  }
}

如果您只使用子网ID和IP地址作为IP限制的一部分,并且在任何其他上下文中都不需要它们,则对此建模的惯用方法是使ip_restriction成为对象类型的单个输入变量,并使用它的存在来决定是否包含ip_restriction块:

variable "ip_restriction" {
  type = object({
    subnet_id  = optional(string)
    ip_address = optional(string)
  })
  default = null
}

resource "azurerm_linux_function_app" "function_app" {
  # ...

  site_config {
    dynamic "ip_restriction" {
      for_each = var.ip_restriction[*]
      content {
        virtual_network_subnet_id = ip_restriction.value.subnet_id
        ip_address                = ip_restriction.value.ip_address
      }
    }

    # ...
  }
}

这种结构有助于更清楚地说明这些不同值之间的相互关系,并避免在ip_restriction块根本未启用时设置subnet_idip_address的无意义情况:当对象内部的属性为非空时,整个对象不可能为空。

相关问题