Search code examples
terraforminfrastructure-as-code

Create conditionally a resource that contains a for_each argument


I'm trying to achieve the next behavior (pseudocode):

if var.zone_id is null:
  create no route53 record
else
  create many route53 records (using for_each)

This is my current configuration before applying any condition:

resource "aws_route53_record" "cert-validation" {
  for_each = {
    for dvo in aws_acm_certificate.main.domain_validation_options : dvo.domain_name => {
      //some attributes
    }
  }
  // more attributes
}

I tried to use this:

count = var.zone_id == null ? 0 : 1

Problem is that resource already has a for_each argument so my solution does not make much sense. I tried also something like this:

locals {
  dvos = var.zone_id == null ? [] : aws_acm_certificate.main.domain_validation_options
}

And iterate over local.dvos. But it does not work because a local cannot have a reference to a resource.

How could I solve this?

Thank you in advance


Solution

  • The for expression syntax includes an optional if clause that you can use to filter elements from the result. In your case you want to filter all of them when some condition is true, which you can achieve by writing an if clause that doesn't refer to either of the iterator variables:

    resource "aws_route53_record" "cert-validation" {
      for_each = {
        for dvo in aws_acm_certificate.main.domain_validation_options : 
        dvo.domain_name => {
          //some attributes
        }
        if var.zone_id != null
      }
      // more attributes
    }
    

    If var.zone_id is null then this will filter out all of the elements, causing the value assigned to for_each to be an empty object. This would therefore declare zero instances of this resource in that case.