Home > front end >  Terraform: Delete resource before creating another resource
Terraform: Delete resource before creating another resource

Time:07-29

OVERVIEW

I'd like to create a Route53 DNS record. Depending on a variable it will either be a CNAME record or an ALIAS record.

On the first run, this works OK because neither of the records exists.

However, when updating the variable var.route_53_redirection_type to change the record type the terraform apply fails because it attempts to create the new record before the old one is deleted.

Error: [ERR]: Error building changeset: InvalidChangeBatch: [RRSet of type A with DNS name redirect is not permitted because a conflicting RRSet of type CNAME with the same DNS name already exists in zone.]

When terraform apply is run again it works because the record had been deleted on the previous run.

Here is the code:

resource "aws_route53_record" "alias" {                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       
  count = var.route_53_redirection_type == "ALIAS" ? 1 : 0
  zone_id = data.aws_route53_zone.public.zone_id
  name    = "redirect"
  type    = "A"
  alias {
    name                   = module.alb.alb_dns_name
    zone_id                = module.alb.alb_zone_id
    evaluate_target_health = true
  }
  
}

resource "aws_route53_record" "cname" {
  count = var.route_53_redirection_type == "CNAME" ? 1 : 0
  zone_id = data.aws_route53_zone.public.zone_id
  name    = "redirect"
  type    = "CNAME"
  ttl     = "5"
  records        = ["www.google.com"]
}

QUESTIONS

  • Is it possible to ensure the deletion happens before the creation?
  • Is there a better approach entirely, which removes the dependency?

NOTES I've looked at lifecycle and depends_on but neither of these seem applicable in this case.

Thanks in advance!

CodePudding user response:

Any specific reason for updating the record type?

But if this is requirement of deleting any specific resource, we can always use destroy as destroy command can be used to destroy a complete set of cloud infrastructure or a targeted resource.

 terraform destroy --target aws_route53_record.cname

CodePudding user response:

I think it would be really hard to achieve what you want based on the requirements. I think that a better way of approaching this would be using dynamic block [1] and for_each [2] (still not sure that would work as expected). The code would then look like:

resource "aws_route53_record" "record" {                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       
  zone_id = data.aws_route53_zone.public.zone_id
  name    = "redirect"
  type    = var.route_53_redirection_type == "ALIAS" ? "A" : "CNAME"
  ttl     = var.route_53_redirection_type == "ALIAS" ? null : 5

  dynamic "alias" {
    for_each = var.route_53_redirection_type == "ALIAS" ? [1] : []
    content {
      name                   = module.alb.alb_dns_name
      zone_id                = module.alb.alb_zone_id
      evaluate_target_health = true
    }
  }

}

[1] https://www.terraform.io/language/expressions/dynamic-blocks

[2] https://www.terraform.io/language/meta-arguments/for_each

  • Related