Using Template Files and File Function to Deploy EC2 Instances

Hands-On Lab

 

Photo of Travis Thomsen

Travis Thomsen

Course Development Director in Content

Length

01:00:00

Difficulty

Advanced

After one of our co-workers left the company, our manager tasked us with finishing a Terraform module that was never finished. The module will be used to create EC2 instances and configured using user data, but the user data portion was also left incomplete. The instances should be accessible using the bastion SSH key.

What are Hands-On Labs?

Hands-On Labs are scenario-based learning environments where learners can practice without consequences. Don't compromise a system or waste money on expensive downloads. Practice real-world skills without the real-world risk, no assembly required.

Using Template Files and File Function to Deploy EC2 Instances

The Scenario

After one of our co-workers left the company, our manager tasked us with finishing a Terraform module that was never finished. The module will be used to create EC2 instances and configured using user data, but the user data portion was also left incomplete.

The instances should be accessible using the bastion SSH key.

Logging In

Use the IP address and credentials provided on the hands-on lab overview page, and log in with SSH to the server.

There's a fair bit of creating and editing files in this lab. All of the examples here involve using Vim, but use whichever text editor is most comfortable.

Create a New SSH Key for cloud_user

Create the SSH Key:

ssh-keygen

Update the Compute Module's main.tf File

Edit main.tf:

vi compute/main.tf

main.tf contents:

#-----compute/main.tf

data "aws_ami" "server_ami" {
  owners = ["amazon"]
  most_recent = true

  filter {
    name   = "name"
    values = ["amzn-ami-hvm*-x86_64-gp2"]
  }
}

# Need to access the public key file referenced in var.public_key_path

resource "aws_key_pair" "tf_auth" {
  key_name   = "${var.key_name}"
  public_key = "${file(var.public_key_path)}"
}

# Template file goes here
data "template_file" "user-init" {
  count    = 2
  template = "${file("${path.module}/userdata.tpl")}"

  vars {
    message = "hello from the server"
  }
}

resource "aws_instance" "tf_server" {
  count         = "${var.instance_count}"
  instance_type = "${var.instance_type}"
  ami           = "${data.aws_ami.server_ami.id}"

  tags {
    Name = "tf_server-${count.index +1}"
  }

  key_name               = "${aws_key_pair.tf_auth.id}"
  vpc_security_group_ids = ["${var.security_group}"]
  subnet_id              = "${element(var.subnets, count.index)}"
  user_data              = "${data.template_file.user-init.*.rendered[count.index]}"
}

Deploy the Infrastructure

Initialize Terraform:

terraform init

Validate the files:

terraform validate

Deploy the EC2 instances:

terraform apply -auto-approve

Conclusion

After a successful apply command, our mission is accomplished. But to check, we can log into our AWS console, and check in the EC2 instances section. We'll see three that are running. One is what we've been making our changes on, but there are a couple of others, tf_server-1 and tf_server-2, that we can examine. Clicking the Apply dropdown in in the Instances screen, then navigating to Instance Settings > View/Change User Data, will bring us to a window where we can see things we specified in our main.tf file. Congratulations!