如何在 Terraform 中编写 if、else、elsif 条件语句

48

在 Terraform 中,有没有一种方法可以编写带有多个分支的条件语句?

我正在设置一个 Terraform 模块来创建 Amazon Aurora 集群。我需要有一个选项来进行跨区域复制,所以我需要根据源区域决定副本的区域。

6个回答

60

这是使用coalesce()函数的一种方法:

locals{
  prod = "${var.environment == "PROD" ? "east" : ""}"
  prod2 = "${var.environment == "PROD2" ? "west2" : ""}"
  nonprod = "${var.environment != "PROD" && var.environment != "PROD2" ? "west" : ""}"
  region = "${coalesce(local.prod,local.prod2, local.nonprod)}"
}

绝对是正确的方法,如果需要更多细节,我也发现这个链接很有帮助 https://ataiva.com/how-to-write-if-else-statements-in-terraform/ - AO_

29
locals {
  test = "${ condition ? value : (elif-condition ? elif-value : else-value)}"
}

如果你想采用更加字面的“if-elif-else”方法,你可以将if简写嵌套在其他简写中以产生类似的效果。如果你的使用情况也位于for循环内部,那么你也可以这样做:

locals {
  test = {
    for i in list : 
      key => "${ condition ? value : (elif-condition ? elif-value : else-value)}"
  }
}

适用于您使用“${}”语法的任何情况


这是一个非常棒的答案! - Alex

16

你可以尝试只使用maplookup。例如:

/* In your variables.tf */
variable "region_mapping" {
  description = "mapping for cross-region replication"
  default = {
    "us-east-1" = "us-east-2",
    "us-west-1" = "us-west-2"
  }
}

/* Then create use lookup to get the replication region from the deployment region */
resource "example" "example" {
  region = "${lookup(var.region_mapping, var.region)}"
}

如果您当前的集群部署在var.region,且其值为例如us-east-1,则查找将返回us-east-2作为您应该部署副本的区域。

根据您的需求进行调整。


1
这很有帮助,我最终使用了列表而不是映射,需要使用count.index来查找值,谢谢@Esteban Garcia。 - zqcolor

10
从terraform 0.12开始,你可以通过使用map来模拟开关,例如:
locals {
  environments = {
    prod = "east",
    prod2 = "west2"
  }
  
  region = lookup(environment_region, lower(var.environment), "west")
}

这样做的优点是,如果结果更加复杂,你可以从map中返回对象/列表,而不仅仅是简单的字符串。

例如,我有一个集中式命名模块,根据资源类型等不同规则组合名称。

locals {
  parts_map = {
    # NB Location should always be last to ensure geo-separation of names
    prefix = [ local.type.code, var.name, var.role, var.environment, module.location.code ]
    suffix = [ var.name, var.role, var.environment, local.type.code, module.location.code ]
    mode3  = [ var.name, local.type.code, var.role, var.environment, module.location.code ]
}

parts = compact(local.parts_map[local.type.order])

8

我为此付出了数小时的努力,试图创建数组以实现我的需求。根据@MrJ1m0thy的答案,我创建了这个包含多个选项的三元运算符,它模拟了if/elseif/else:

conditioning_a != "condition_a" ? "value1" : (conditioning_b == "condition_b" ? "value_b" : (conditioning_c == "condition_c" ? "value_c" : (conditioning_d == "condition_d" ? "value_d" : "value2")))

太好了!级联条件语句对我有用。 - Kundan

2
在 Terraform 0.12 及以下版本中,不存在 if/elseif/else 这样的语法。
但是,在 Terraform 条件语句 中,您可以使用传统的布尔逻辑。"Original Answer" 翻译成 "最初的回答"。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接