Skip to content

Terraform code to quickly spin up / tear down an EC2 instance in AWS. A persistent EBS volume is also created and mounted at /home.

License

Notifications You must be signed in to change notification settings

teticio/terraform-ec2

Repository files navigation

Terraform EC2

Terraform code to quickly spin up / tear down an EC2 instance in AWS. A persistent EBS volume is also created and mounted at /home.

While it is possible to start and stop EC2 instances and thus only pay for the compute you use, it is generally a good idea to be able to terminate and launch fresh instances. One way to do preserve your work is to decouple your home directory from the EC2 instance by mounting a separate EBS volume configured not to be destroyed on termination.

Usage

Ensure you have a public key (for example in ~/.ssh/id_rsa.pub). If not, you can create one with:

ssh-keygen

Create a terraform.tfvars file:

region          = "eu-west-2"         # AWS region
instance_type   = "t2.micro"          # EC2 instance type
volume_size     = 20                  # Size of home EBS volume in GB
public_key_path = "~/.ssh/id_rsa.pub" # Path to public key
ingress_ports   = [22]                # Ports to open

# Commands to run on startup (e.g. to install pip)
startup_commands = [
  <<-EOL
    apt-get update
    apt-get install -y python3-pip
  EOL
]

Then run:

terraform init
terraform apply -auto-approve

and take a note of the public IP address and ID of the instance. (You can recover these at any time with terraform output.) Alternatively, you can run ./create.sh <instance_type>.

You can then SSH into the instance with

ssh ubuntu@<public_ip>

or simply ./connect.sh.

You can terminate the instance from the command line by running:

aws ec2 terminate-instances --instance-ids <instance_id>
aws ec2 wait instance-terminated --instance-ids <instance_id>

or ./terminate.sh.

If you re-run the apply or ./create.sh command, Terraform will create a new instance with a new public IP address and attach the existing EBS volume to it. Note that your home EBS volume will persist and you will be charged $0.10 per GB-month whether or not it is attached to an EC2 instance (until you run terraform destroy -auto-approve).

To debug issues with the startup_commands, you can SSH into the instance and inspect the output from tail -f /var/log/cloud-init-output.log. Bear in mind that the script may still be running in the background. To wait for the script to finish run cloud-init status --wait.

Grow your own EBS

To increase your the size of your EBS volume without destroying your data, first change the volume_size variable in terraform.tfvars, run terraform apply -auto-approve and connect to your instance. In the instance, run:

if [ -e /dev/xvda ]; then
    sudo resize2fs /dev/xvda
else
    sudo resize2fs /dev/nvme1n1
fi

You can then run df -h /home to check that the volume has been resized.

Opening ports

You can, of course, tunnel to any port via SSH on port 22 with

ssh -L <local_port>:localhost:<remote_port> ubuntu@<public_ip>

but, if you want to open ports to the public, just set the variable

ingress_ports   = [22, 80, 443]       # Ports to open

to include the ports you want to make accessible (for example to run a web server on 80 and 443).

Bring your own AMI

If you plan to always install the same packages every time you spin up an instance, you can create your own AMI with the packages pre-installed by running the following commands:

instance_id=$(terraform output -json | jq -r '.instance_id.value')
aws ec2 stop-instances --instance-ids $instance_id
aws ec2 wait instance-stopped --instance-ids $instance_id
# Detach home EBS volume, otherwise a snapshot will be created
volume_id=$(terraform output -json | jq -r '.home_ebs_volume.value')
aws ec2 detach-volume --volume-id $volume_id
aws ec2 wait volume-available --volume-id $volume_id
image_id=$(aws ec2 create-image --instance-id $instance_id --name "my_ami" --query 'ImageId' --output text)
aws ec2 wait image-available --image-ids $image_id

Then add the following lines to terraform.tfvars to select your AMI next time you spin up an instance:

ami_owner       = "self"              # Owner of AMI
ami_name        = "my_ami"            # Name of AMI

About

Terraform code to quickly spin up / tear down an EC2 instance in AWS. A persistent EBS volume is also created and mounted at /home.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published