Sanjay M. P.
Sanjay M. P.

Reputation: 1009

Make null resource to wait on aws_route53_record in Terraform

resource "aws_route53_record" "record" {
    zone_id = data.aws_route53_zone.selected.zone_id
    name    = "${var.sfs_instance_name}.example.com"
    type    = "A"
    ttl     = "60"
    records = ["${aws_eip.sfs.public_ip}"]
  }

resource "null_resource" "sfs-ssl-certs" {

  connection {
    type        = "ssh"
    user        = "centos"
    host        = aws_eip.sfs.public_ip
    private_key = file("../keys/${var.sfs_instance_name}.pem")
  }

  provisioner "remote-exec" {
    inline = [
      "set -x",
      "sudo certbot --nginx -d ${var.sfs_instance_name}.example.com --register-unsafely-without-email --agree-tos --force-renewal --non-interactive > /home/centos/get_cert.log"
    ]
}

Creating nginx ssl for the domain name "${var.sfs_instance_name}.example.com" on the fly, the entry is added at the end of the execution so the certbox ssl cert creation fails, how can i overcome it, can i wait upon the resource "aws_route53_record" entry creation or is there any other workaround ?

Upvotes: 3

Views: 1226

Answers (2)

ydaetskcoR
ydaetskcoR

Reputation: 56987

You can avoid the depends_on here by properly interpolating the value out of the resource instead:

resource "aws_route53_record" "record" {
    zone_id = data.aws_route53_zone.selected.zone_id
    name    = "${var.sfs_instance_name}.example.com"
    type    = "A"
    ttl     = "60"
    records = [aws_eip.sfs.public_ip]
  }

resource "null_resource" "sfs-ssl-certs" {

  connection {
    type        = "ssh"
    user        = "centos"
    host        = aws_eip.sfs.public_ip
    private_key = file("../keys/${var.sfs_instance_name}.pem")
  }

  provisioner "remote-exec" {
    inline = [
      "set -x",
      "sudo certbot --nginx -d ${aws_route53_record.record.name} --register-unsafely-without-email --agree-tos --force-renewal --non-interactive > /home/centos/get_cert.log"
    ]
}

Terraform only needs the depends_on parameter when it's not possible to tell the other resource about the dependency chain directly by interpolating values of the resource into the other resources. In general if you can avoid using it and stick to direct resource interpolation then it makes things better. As another other positive side it avoids you having to build the DNS record name by string concatenation in two places.

The Terraform documentation around resource dependencies also suggest avoid depends_on unless absolutely necessary:

Most resources in a configuration don't have any particular relationship, and Terraform can make changes to several unrelated resources in parallel.

However, some resources must be processed after other specific resources; sometimes this is because of how the resource works, and sometimes the resource's configuration just requires information generated by another resource.

Most resource dependencies are handled automatically. Terraform analyses any expressions within a resource block to find references to other objects, and treats those references as implicit ordering requirements when creating, updating, or destroying resources. Since most resources with behavioral dependencies on other resources also refer to those resources' data, it's usually not necessary to manually specify dependencies between resources.

However, some dependencies cannot be recognized implicitly in configuration. For example, if Terraform must manage access control policies and take actions that require those policies to be present, there is a hidden dependency between the access policy and a resource whose creation depends on it. In these rare cases, the depends_on meta-argument can explicitly specify a dependency.

Upvotes: 0

Marcin
Marcin

Reputation: 238687

I think the solution is to add depends_on:

resource "null_resource" "sfs-ssl-certs" {

  depends_on = [aws_route53_record.record]

  connection {
    type        = "ssh"
    user        = "centos"
    host        = aws_eip.sfs.public_ip
    private_key = file("../keys/${var.sfs_instance_name}.pem")
  }

  provisioner "remote-exec" {
    inline = [
      "set -x",
      "sudo certbot --nginx -d ${var.sfs_instance_name}.example.com --register-unsafely-without-email --agree-tos --force-renewal --non-interactive > /home/centos/get_cert.log"
    ]
}

Upvotes: 1

Related Questions