Can I use an output from a resource in a provisioner which is part of the same resource?

I’m creating an EC2 instance and attempting to capture the public IP as an output before using it in a bash script that I’d like to execute upon successfully creating the instance:

output "public_ip" {
  value = aws_instance.example.public_ip  
}

resource "aws_instance" "example" {
  ami           = "ami-0a606d8395a538502"
  instance_type = "t2.micro"
  vpc_security_group_ids = [aws_security_group.sg.id]

  user_data = "${data.template_file.user_data.rendered}"

  provisioner "local-exec" {
    command = "bash utility.sh ${output.public_ip.value}"
  }
}

The error I’m getting:

Error: Reference to undeclared resource
│
│   on main.tf line 23, in resource "aws_instance" "example":
│   23:     command = "bash /utility.sh ${output.public_ip.value}"
│
│ A managed resource "output" "public_ip" has not been declared in the root module.

My folder structure is simple:

 Terrastuff
    |
    +main.tf
    |
    +py_exec.sh
    |
    +utility.sh

Do I need to create a module? I suspect the problem is it’s trying to pass in the output before it has it, so I’m wanting to know if there’s a way around that.

>Solution :

That’s not going to work, because you have a circular reference between the output and the resource. The resource shouldn’t depend on the output. Instead, use the self object:

resource "aws_instance" "example" {
  ami           = "ami-0a606d8395a538502"
  instance_type = "t2.micro"
  vpc_security_group_ids = [aws_security_group.sg.id]

  user_data = "${data.template_file.user_data.rendered}"

  provisioner "local-exec" {
    command = "bash utility.sh ${self.public_ip}"
  }
}

output "public_ip" {
  value = aws_instance.example.public_ip  
}

Leave a Reply