amazon-web-servicesterraformcloud-init

Using Rendered Cloud-Init with Node Public DNS in Terraform


I am trying to use cloud-init and terraform to execute scripts on first boot of my instance. A simplified version of what I'm trying to do looks like the following:

#cloud-config

runcmd:
  - echo { node_name}
data "template_file" "user_data" {
  template = file("../../cloud-init/init-vm.yaml")

  # Set variables for the template
  vars = {
    bacalhauservice = aws_instance.instance.public_dns
  }
}

resource "aws_instance" "instance" {
  ami                    = var.instance_ami
  instance_type          = var.instance_type
  subnet_id              = var.subnet_public_id
  vpc_security_group_ids = var.security_group_ids
  key_name               = var.key_pair_name
  availability_zone      = var.availability_zone
  user_data              = data.template_file.user_data.rendered

}

This doesn't work - it's circular. What are my options?


Solution

  • It isn't possible for the user_data value for an EC2 instance to include the IP address of that same instance, because the IP address isn't allocated until after the API call to create the EC2 instance, which must include the user_data value.

    Therefore you will need to find a different approach to solve your problem. There are a few different options:


    Also please note that template_file and the provider it belongs to have been deprecated for a long time. The modern replacement is the built-in function templatefile, which you can use like this:

      user_data = templatefile("${path.module}/../../cloud-init/init-vm.yaml", {
        bacalhauservice = network_interface.example.private_ip
      })