terraform resource time_sleep: Waiting for resources to be ready before using them

terraform resource time_sleep depends_on sleep

2 min read | by Jordi Prats

Some times we need to wait some time before using some of the resources to give some time to the previous resources to be ready. For this kind of situations we can use the resource time_sleep combined with depends_on to achieve this functionality on terraform

Using time_sleep we can use two kinds of delays:

  • create_duration: Time to wait on resource creation
  • destroy_duration: Time to wait on resource destruction

So, if we have set the create_duration, it will wait just on the resource creation. If we manually delete the resource that is waiting for we will have to also remove this object (terraform state rm or using the -replace option (taint)) from the terraform state for it to wait again on the next apply.

To be able to properly wait for the resources we will have to add depends_on between the resources to create a chain. On the following example we are installing a Kubernetes application using helm, them we are waiting for 300s for the resources to be ready and finally, we are trying to retrieve the load balancer's hostname using the kubernetes_ingress data source:

resource "helm_release" "ampa" {
  name       = "ampa"
  chart      = "/home/git/ampa/helm-ampa"
  timeout    = 600

  namespace = var.namespace
}

resource "time_sleep" "wait_for_ingress_alb" {
  create_duration = "300s"

  depends_on = [helm_release.ampa]
}

data "kubernetes_ingress" "web" {
  metadata {
    name      = "votacions-ampa"
    namespace = var.namespace
  }

  time_sleep = [time_sleep.wait_for_ingress_alb]
}

Using this code, we can be sure that by the time we need the load balancer's hostname to create a DNS record, it is going to be available:

data "aws_route53_zone" "private_r53_zone" {
  name         = var.domain_name
  private_zone = true
}


resource "aws_route53_record" "deck_private_r53_record" {
  count   = length(module.ampa.endpoint) > 0 ? 1 : 0
  zone_id = data.aws_route53_zone.private_r53_zone.zone_id
  name    = "${var.appname}.${var.domain_name}"
  type    = "CNAME"

  records = [data.kubernetes_ingress.web.load_balancer_ingress[0].hostname]
  ttl     = "600"
}

Posted on 23/06/2021