首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >模块中的Terraform条件

模块中的Terraform条件
EN

Stack Overflow用户
提问于 2020-01-16 10:56:49
回答 2查看 6.7K关注 0票数 0

在调用应用网关模块时,我试图创建一些简单的逻辑。

在创建WAF v2应用程序网关时,我希望指定更多简单应用程序网关无法处理的属性,它们不会被描述。

代码语言:javascript
复制
resource "azurerm_application_gateway" {
  name                = var.appgatewayname
  resource_group_name = data.azurerm_resource_group.rg.name
  location            = data.azurerm_resource_group.rg.location

......................

  waf_configuration {
    enabled                  = "${length(var.waf_configuration) > 0 ? lookup(var.waf_configuration, "enabled", "") : null }"
    firewall_mode            = "${length(var.waf_configuration) > 0 ? lookup(var.waf_configuration, "firewall_mode", "") : null }"
............

呼叫模块:

代码语言:javascript
复制
module "GWdemo" {
  source      = "./...."

  sku-name     = "WAF_v2"
  sku-tier     = "WAF_v2"
  sku-capacity = 1
  waf-configuration = [
    {
      enabled                  = true
      firewall_mode            = "Detection"
}

我是否认为,如果指定了waf-配置映射,它应该指定以下设置,如果不是null,则应用以下设置?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-01-21 18:58:18

在使用Terraform时,我们通常希望将涉及条件测试的问题重构为可能包含元素的集合,也可能不包含元素的集合,因为Terraform语言特性面向的是将集合逐个元素转换为配置。

在您的示例中,您有一个已经是list的变量,因此它可以确保它的默认值是空列表而不是null,因此可以只生成每个元素的一个waf_configuration块:

代码语言:javascript
复制
variable "waf_configuration" {
  type = list(object({
    enabled       = bool
    firewall_mode = string
  }))
  default = []
}

然后,您可以使用区块来生成该列表中每个元素的一个waf_configuration块:

代码语言:javascript
复制
  dynamic "waf_configuration" {
    for_each = var.waf_configuration
    content {
      enabled       = waf_configuration.value.enabled
      firewall_mode = waf_configuration.value.firewall_mode
    }
  }

虽然它似乎不适用于这个特定的示例,但另一个常见的模式是一个变量,它可以被设置为启用某物或未设置为禁用它。例如,如果您的模块设计为只接受一个可选的WAF配置,则可以定义如下所示的变量:

代码语言:javascript
复制
variable "waf_configuration" {
  type = object({
    enabled       = bool
    firewall_mode = string
  })
  default = null
}

如上所述,在Terraform中使用类似的东西的最好方法是将其重命名为可能为空的列表。因为这是一种常见的情况,所以通过splat表达式有一个缩写

代码语言:javascript
复制
  dynamic "waf_configuration" {
    for_each = var.waf_configuration[*]
    content {
      enabled       = waf_configuration.value.enabled
      firewall_mode = waf_configuration.value.firewall_mode
    }
  }

当我们将[*]运算符应用于非列表/非集类型的值时,Terraform将测试该值是否为null。如果它为null,则结果将是一个空列表,而如果它不是null,则结果将是包含该值的单个元素列表。

在转换成一个列表之后,我们可以按照通常的方式在for_each参数中将它使用到dynamic中,从content块中的那个可能的单个元素访问属性。我们不需要对每个参数重复附加条件,因为只有当列表为非空时才计算content块内容。

票数 3
EN

Stack Overflow用户

发布于 2020-01-16 13:03:49

我鼓励您升级到Terraformv0.12.x,这应该会容易得多。我将利用新的动态块语法,根据需要使用的任何条件使块可选。

这是一个粗略的例子,但应该能让你朝着正确的方向前进。

代码语言:javascript
复制
dynamic "waf-configuration " {
  for_each = length(var.waf_configuration) > 0 ? [] : [1]
  content {
    enabled       = "${length(var.waf_configuration) > 0 ? lookup(var.waf_configuration, "enabled", "") : null }"
    firewall_mode = "${length(var.waf_configuration) > 0 ? lookup(var.waf_configuration, "firewall_mode", "") : null }"
  }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59768114

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档