如何使地形资源块有条件

问题描述

我有一个 aws_acm_certificate,我想在本地运行我的 tf 时避免使用它(因为我不想获取域名等)。我也不想在本地运行时注释掉所有涉及的代码。我的大多数其他块 (such as a provider's assume_role) 在本地运行时都能够被排除在外。我怎样才能用完整的资源做到这一点?

我希望能够将 count 值设置为环境 tfvars 文件中的变量:

resource "aws_acm_certificate" "cert" {
  count = var.islocal == true ? 0 : 1

  domain_name       = "www.mysite.com"
  validation_method = "DNS"

  lifecycle {
    create_before_destroy = true
  }
}

这会导致其他问题,例如需要在其他地方引用该资源。比如输出资源的结果就会有问题:

output "acm_cert_domain_validation_options" {
  description = "deFinition of aws certificate requested for cloudfront"
  value = aws_acm_certificate.cert[0].domain_validation_options
}

在这种情况下,如果 count 变量是 0输出将在 plan 上失败,我不能在那里使用相同的方法,因为不支持 count来自output

除了简单地不输出值,有没有办法安全地有条件地排除整个块?

解决方法

这可能会很棘手,具体取决于相互依赖的资源的数量,但在您的情况下可以使用的方法是在本地运行计划时使用 -target

想象以下带有 S3 和 ACM 证书的 terraform 代码,您只想在本地执行 S3 代码并避免 ACM:

resource "aws_s3_bucket" "my_s3_bucket" {
  bucket_prefix = "whatever-"
  acl    = "private"
}

resource "aws_acm_certificate" "cert" {

  domain_name       = "www.mysite.com"
  validation_method = "DNS"

  lifecycle {
    create_before_destroy = true
  }
}


output "acm_cert_domain_validation_options" {
  description = "definition of aws certificate requested for cloudfront"
  value = aws_acm_certificate.cert[0].domain_validation_options
}

然后我可以运行:

terraform plan -target=aws_s3_bucket.my_s3_bucket

这样,terraform 将避免运行 ACM 代码(包括输出)。 您可以添加多个目标:

terraform plan -target=aws_s3_bucket.my_s3_bucket -target=aws_s3_bucket.my_s3_bucket_2

如果不是绝对必要,我总是尽量避免使用计数器,从而尽可能保持 terraform 代码的清晰,否则 terraform 代码可能会变得难以遵循和维护。