【问题标题】:Terraform: Conditional creation of a resource based on a variable in .tfvarsTerraform:基于 .tfvars 中的变量有条件地创建资源
【发布时间】:2020-05-30 13:08:04
【问题描述】:

我在.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
}

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

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 v0.12.10,但如果需要我可以切换到另一个版本。

标签: terraform terraform-provider-cloudflare


【解决方案1】:

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

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

【讨论】:

  • 是否还有一种方法可以在不使用索引的情况下引用此资源?例如cloudflare_record.record[0].name?
  • 如果您使用计数功能,则需要索引。如果你不想硬编码 0,你可以使用 count.index。见:terraform.io/docs/language/meta-arguments/count.html
  • 如果资源由于计数字段而没有被创建,那么下面的行将失败。 cloudflare_record.record[0].some_field.然后怎么输出这个值
  • @VishalSharma - 我自己是新手,但有人建议您可以使用星号 * 代替括号(至少在插入字符串时):stackoverflow.com/questions/51654863/…跨度>
【解决方案2】:

我遇到了基于变量创建 AWS 资源的类似问题。

请求:

  • 生产环境,使用导入证书;
  • 对于开发环境,请求 ACM 证书并通过 DNS 创建 Route53 记录对其进行验证。

我尝试如下代码。它在生产环境中抱怨 AWS 颁发的 aws_acm_certificate.alb[] 为空。我希望三元运算符“?:”快捷方式。

关于如何解决我的问题有什么建议吗?

谢谢,

老虎

# alb Cert
data "aws_acm_certificate" "vault-alb-imported" {
  counti = var.vault-cert-arn == "" ? 0 : 1 
  domain = "vault-alb.${var.domain}"
  types  = ["IMPORTED"]
}

resource "aws_acm_certificate" "alb" {
  count             = var.cert-arn == "" ? 1 : 0 
  domain_name       = "alb.${var.domain}"
  validation_method = "DNS"

  lifecycle {
    create_before_destroy = true
  }

  tags = merge(var.default-tags, tomap({
    Name = "alb"
  }))
}

resource "aws_route53_record" "alb-cert" {
  for_each = var.cert-arn == "" ? {} : { 
    for dvo in aws_acm_certificate.alb[0].domain_validation_options : dvo.domain_name => {
      name   = dvo.resource_record_name
      record = dvo.resource_record_value
      type   = dvo.resource_record_type
    }
  }
  allow_overwrite = true
  name            = each.value.name
  records         = [each.value.record]
  ttl             = 60
  type            = each.value.type
  zone_id         = var.public-hosted-zone-id
} 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-26
    • 2021-12-12
    • 2019-10-20
    • 2022-10-25
    • 1970-01-01
    • 2017-12-09
    • 2019-08-04
    相关资源
    最近更新 更多