Matt W
Matt W

Reputation: 12423

How to make a terraform resource block conditional

I have a aws_acm_certificate which I would like to avoid when running my tf locally (because I don't want to acquire a domain name, etc). I also don't want to comment out all the involved code when running locally. Most of my other blocks (such as a provider's assume_role) have been able to be excluded when running locally. How can I do this with a complete resource?

I was expecting to be able to set the count value to a variable in an environment tfvars file:

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

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

  lifecycle {
    create_before_destroy = true
  }
}

This leads to other problems, like the need to reference that resource in other place. For example, outputting the result of the resource becomes problematic:

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

In this case, if the count var is 0 the output will fail on plan and I can't use the same approach there because count is not supported by output.

Other than simply not outputting the value, is there a way to conditional exclude entire blocks safely?

Upvotes: 3

Views: 1447

Answers (1)

Jaime S
Jaime S

Reputation: 1698

It could be tricky depending on how many resources are inter-depedent, but something that could work in your case is the use of -target when you run your plan locally.

Imagine the following terraform code with an S3 and ACM certificate, and you only want to execute locally the S3 code and avoid the 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
}

Then I could run:

terraform plan -target=aws_s3_bucket.my_s3_bucket

In that way terraform will avoid to run the ACM code (including the outputs). You can add many targets:

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

I always try keep the terraform code as clear as possible by avoiding using counters if they are not strictly necessary, otherwise the terraform code could become difficult to follow and maintain.

Upvotes: 1

Related Questions