Terraform: invoking a startup script for an EC2 aws_instance

You can bake a startup script directly into the creation of your EC2 instance when using Terraform.  Although complex post-configuration should be left to tools such as Ansible, essential bootstrap type commands or custom routes for instances in private subnets are reasons why you might need to use this hook.

Below is an example of an inline bash script specified in the ‘user_data’ parameter that logs a test message and then queries the ec2 metadata service for its private IP address.

resource "aws_instance" "myinstance" {
  ...

  user_data = <<-EOF
    #!/bin/bash
    echo test of user_data | sudo tee /tmp/user_data.log
    curl http://169.254.169.254/latest/meta-data/local-ipv4 | sudo tee -a /tmp/user_data.log
  EOF

}

You can also reference the contents of a local file (local to terraform)

resource "aws_instance" "myinstance" {
  ...

  user_data = file("${path.module}/startup.sh")
}

Or you can use a ‘template_file’ as shown below.

data "template_file" "default" {
  template = file("${path.module}/startup.sh")
  vars = {
    foo = "bar"
  }
}


resource "aws_instance" "myinstance" {
  ...

  user_data = data.template_file.default.rendered
}

REFERENCES

aws, retrieve instance metadata

stackoverflow, pulling metadata

stackoverflow, metadata for public and private IP

terraform.io, aws_instance