基于 .tfvars 中的变量有条件创建资源

问题描述 投票:0回答:4

我在

.tf
文件中定义了对多个应用程序通用的资源。我通过
.tfvars
文件填充许多字段。我需要完全基于
.tfvars
中的变量省略一些资源。

例如,如果我有这样的资源:

resource "cloudflare_record" "record" {
  zone_id = "${data.cloudflare_zones.domain.zones[0].id}"
  name    = "${var.subdomain}"
  value   = "${var.origin_server}"
  type    = "CNAME"
  ttl     = 1
  proxied = true
}

但是后来我在

cloudflare = false
文件中声明了类似
.tfvars
的内容,我希望能够执行以下操作:

if var.cloudflare {
  resource "cloudflare_record" "record" {
    zone_id = "${data.cloudflare_zones.domain.zones[0].id}"
    name    = "${var.subdomain}"
    value   = "${var.origin_server}"
    type    = "CNAME"
    ttl     = 1
    proxied = true
 }
}

我看过动态块,但看起来您只能使用它们来编辑资源中的字段和块。我需要能够忽略整个资源。

terraform terraform-provider-cloudflare
4个回答
303
投票

使用

count
中声明的变量添加带有三元条件的
.tfvars
参数,如下所示:

resource "cloudflare_record" "record" {
  count = var.cloudflare ? 1 : 0
  zone_id = "${data.cloudflare_zones.domain.zones[0].id}"
  name    = "${var.subdomain}"
  value   = "${var.origin_server}"
  type    = "CNAME"
  ttl     = 1
  proxied = true
}

在此示例中,

var.cloudflare
是在
.tfvars
文件中声明的布尔值。如果为真,将创建 1
record
的计数。如果为 false,将创建 0
record
计数。

count
应用后,资源成为一个组,因此稍后在参考中使用组的
0-index

cloudflare_record.record[0].some_field

52
投票

扩展@Joel Guerra的答案,在使用

count
确定是否部署资源后,您可以使用
one()
函数来引用没有索引的资源(即不必使用
[0]
) .

例如,定义如下资源后

resource "cloudflare_record" "record" {
  count = var.cloudflare ? 1 : 0
}

定义一个局部变量,如下所示

locals {
  cloudflare_record_somefield = one(cloudflare_record.record[*].some_field)
}

现在您可以使用

代替
cloudflare_record.record[0].some_field

local.cloudflare_record_somefield

如果计数为 0(例如

var.cloudflare
false
并且未创建资源),则
local.cloudflare_record_somefield
将返回
null
(而不是在使用
[0]
建立索引时返回错误)。

参考:https://developer.hashicorp.com/terraform/language/functions/one


8
投票

我看到的一个问题是,如果您尝试创建的资源已经在使用 for_each ,那么您不能在资源中同时使用 count 和 for_each 。 我仍在尝试寻找答案,如果我找到更好的东西,我会更新。


7
投票

示例场景:您可能想要创建或不创建(切换/使用标志/有条件创建)VM。但除了虚拟机之外,您可能还必须创建/不创建其负载均衡器、目标组和安全组等。

互联网上其他答案的问题是,当您在资源上使用三元运算符时,并且当您尝试在其他资源上引用它时,您总是会收到引用错误或索引错误或空元组错误。

要解决此问题,同时指向条件资源,您可以使用

try
语法

resource "aws_vpc" "main" {
  count = var.test_flag ? 1 : 0
  cidr_block       = var.vpc_cidr
  instance_tenancy = var.vpc_instance_tenancy

  tags = {
     Name = "${var.cluster_name}-vpc"
  }

}

resource "aws_internet_gateway" "gw" {
  count =   try(var.test_flag ? 1 : 0, 0) // try block is important here because it has a dependency, here the VPC, but VPC might not need a try block because it is the parent.

  vpc_id = aws_vpc.main[0].id

  tags = {
    Name = "${var.cluster_name}-IG"
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.