I often create classic load balancers with Terraform. The TF outputs of these projects should include the (current) IP address of the loadbalancers. To accomplish this I have the following in my code:
data "dns_a_record_set" "lb_dns_a" {
host = "${aws_elb.myelb.dns_name}"
}
output "load_balancer_ip" {
value = "${data.dns_a_record_set.lb_dns_a.addrs}"
}
This does work, except for when initially creating the ELB. More often than not, there is quite the delay between creating the ELB and its DNS name being resolvable, so that I get an error that the DNS name cannot be resolved. After a couple of seconds/minutes every terraform refresh; terraform output;
shows the correct current IP address of the ELB. I guess I need to inject some sort of hold down timer to give the DNS record time to become available, when first deploying the infrastructure.
How can I implement such a hold down timer, so that the ELB is created and then TF waits for (say) 2 minutes before it creates data.dns_a_record_set.lb_dns_a
?
The best solution would be to wait until the name can be resolved successfully, before proceeding.
P.S.: I only have this problem with ELB. ALB and NLB seem to be quicker, or it just takes long enough to create listeners and target groups so that their DNS names are always resolvable by the time the outputs are created.
There is something called the null_resource
, which can be used in combination with depends_on
, to mess a bit with Terraform, like this:
resource "null_resource" "patience" {
depends_on = [ "aws_elb.myelb" ]
triggers {
lb_dns_name = "${aws_elb.myeln.dns_name}"
}
provisioner "local-exec" {
command = "sleep 300"
}
}
data "dns_a_record_set" "lb_dns_a" {
depends_on = [ "null_resource.patience" ]
host = "${aws_elb.myelb.dns_name}"
}
With this null_resource
I inject something in the build graph that can only be created after the ELB has been created but has to preceede the creation of data.dns_a_record_set.lb_dns_a
. That is precisely where I want my holddown timer. With the null_resource
I can use the local-exec
provisioner to have TF run the bash command sleep 300
, which results in Terraform waiting for 5 minutes between creating the elb and doing the lookup. Problem solved.
A more sophisticated solution has local-exec
actually do the name resolving until it succeeds at least once.