11

My question is similar to this git hub post:

https://github.com/hashicorp/terraform/issues/745

It is also related to another stack exchange post of mine:

Terraform stalls while trying to get IP addresses of multiple instances?

I am trying to bootstrap several servers and there are several commands I need to run on my instances that require the IP addresses of all the other instances. However I cannot access the variables that hold the IP addresses of my newly created instances until they are created. So when I try to run a provisioner "remote-exec" block like this:

  provisioner "remote-exec" {
    inline = [
      "sudo apt-get update",
      "sudo apt-get install -y curl",
      "echo ${openstack_compute_instance_v2.consul.0.network.0.fixed_ip_v4}",
      "echo ${openstack_compute_instance_v2.consul.1.network.1.fixed_ip_v4}",
      "echo ${openstack_compute_instance_v2.consul.2.network.2.fixed_ip_v4}"
    ]
  }

Nothing happens because all the instances are waiting for all the other instances to finish being created and so nothing is created in the first place. So I need a way for my resources to be created and then run my provisioner "remote-exec" block commands after they are created and terraform can access the IP addresses of all my instances.

Community
  • 1
  • 1
Alex Cohen
  • 5,596
  • 16
  • 54
  • 104
  • Possible duplicate of [Terraform stalls while trying to get IP addresses of multiple instances?](http://stackoverflow.com/questions/37823770/terraform-stalls-while-trying-to-get-ip-addresses-of-multiple-instances) – ydaetskcoR Jun 19 '16 at 10:53

2 Answers2

10

The solution is to create a resource "null_resource" "nameYouWant" { } and then run your commands inside that. They will run after the initial resources are created:

resource "aws_instance" "consul" {
  count = 3
  ami = "ami-ce5a9fa3"
  instance_type = "t2.micro"
  key_name = "ansible_aws"
  tags {
    Name = "consul"
  }
}

resource "null_resource" "configure-consul-ips" {
  count = 3

  connection {
    user = "ubuntu"
    private_key="${file("/home/ubuntu/.ssh/id_rsa")}"
    agent = true
    timeout = "3m"
  }

  provisioner "remote-exec" {
    inline = [
      "sudo apt-get update",
      "sudo apt-get install -y curl",
      "sudo echo '${join("\n", aws_instance.consul.*.private_ip)}' > /home/ubuntu/test.txt"
    ]
  }
}

Also see the answer here:

Terraform stalls while trying to get IP addresses of multiple instances?

Thank you so much @ydaetskcor for the answer

Community
  • 1
  • 1
Alex Cohen
  • 5,596
  • 16
  • 54
  • 104
  • 5
    Hi @Alex Cohen, one question, how does the "connection" block defined in "null_resource" know where to connect? I.e., how does it know the ec2 instance address? you didn't specify it in the "connection" block. (If you defined the "connection" block in "aws_instance", I would have no such a question.) – Bruce Mar 26 '18 at 23:25
  • @Bruce I have the same doubt about this. How do you map `null_resource` connection and remote execution to resources? – Sebastian Jan 18 '19 at 04:19
5

In addition to @alex-cohen answer, another tip from https://github.com/hashicorp/terraform/issues/8266#issuecomment-454377049.

If you want to initiate a call to local-exec, regardless of a resource creation, use triggers:

resource "null_resource" "deployment" {
  provisioner "local-exec" {
    command = "echo ${PATH} > output.log"
  }
  triggers = {
    always_run = timestamp()
  }
}
antonbormotov
  • 1,821
  • 2
  • 20
  • 32