I’ve been using Amazon Web Services for a while now have have decided to migrate this blog to it. For a personal project like a blog, setting up a server on AWS involves a lot of manual steps. The usual steps include:
- Login to the AWS Console.
- Go to EC2, follow steps to create an instance.
- Choose which image to use.
- Choose size of instance.
- Create a security group.
- Create new key file.
- Download key file and move to a standard location.
- Copy and paste the new ip, ssh into the machine.
- Install web server and other components.
- Exit ssh, scp copy files across (at a minimum).
While each step is simple, together it is a remarkably error prone process, especially if you do it infrequently. Additionally it creates security and consistency headaches in that you have to keep the state of your server, the current packages installed, where your keys are for access, etc, all in your head.
I wanted an automated way to do this - a more ‘infrastructure as code’ approach. I chose to use https://github.com/mitchellh/vagrant-aws
as I’ve used vagrant before and find it easy to use. What follows is a step-by-step set of instructions to setup a server and website using vagrant-aws
.
Initial AWS Preliminaries
I’m assuming you already have an AWS Account and also have an access key / secret key pair downloaded from AWS with at least permission to create EC2 instances.
The first step is to install the AWS CLI. This allows you to interact with AWS through the command line. I’m using pacman here for example but these packages are pretty easy to install on any machine.
sudo pacman -S aws-cli
Configure aws-cli with your keys and region:
aws configure
Test it out:
aws ec2 describe-instances
You should see a list of the AWS instances you already have running.
Vagrant
Next make sure you have vagrant and vagrant-aws on your system and install the dummy
box.
sudo pacman -S vagrant
vagrant plugin install vagrant-aws
vagrant box add dummy https://github.com/mitchellh/vagrant-aws/raw/master/dummy.box
The dummy box is an empty vagrant box as we will be using an AWS ami (in this case Ubuntu 14.04 LTS) as our base image.
deploy-aws
Download the git repo https://github.com/trengrj/deploy-aws.
git clone https://github.com/trengrj/deploy-aws && cd deploy-aws
This repository consists of a Vagrantfile
which specifies how the server is created, a www
directory which is copied as the webroot to the new server, and a set of scripts for managing aws environment variables, keypairs, and security groups.
The scripts will read your current credentials from the same directory AWS CLI uses.
Here is the Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :
# Vagrant on AWS Example
# Provisioning script
provision_script = <<SCRIPT
#!/bin/bash
SYNC_DIRECTORY=/home/ubuntu/sync
sudo apt-get update
sudo apt-get install -y nginx
sudo cp ${SYNC_DIRECTORY}/conf/nginx.conf /etc/nginx/sites-enabled/default
sudo cp -r ${SYNC_DIRECTORY}/www /var/www
sudo service nginx restart
echo Provisioning complete
SCRIPT
Vagrant.configure(2) do |config|
config.vm.box = 'dummy'
config.vm.synced_folder '.', '/home/ubuntu/sync', type: 'rsync', rsync__exclude: '.git/'
config.vm.provision :shell, :inline => provision_script
config.vm.provider :aws do |aws, override|
#AWS Settings
aws.access_key_id = ENV['AWS_KEY']
aws.secret_access_key = ENV['AWS_SECRET']
aws.keypair_name = ENV['AWS_KEYNAME']
aws.region = ENV['AWS_REGION']
aws.ami = 'ami-6c14310f'
aws.instance_type = 't2.micro'
aws.security_groups = ['web-ssh']
aws.tags = {
'Name' => 'deploy-blog'
}
#Override Settings
override.ssh.username = 'ubuntu'
override.ssh.private_key_path = ENV['AWS_KEYPATH']
end
end
Deployment
Create a new security group (note this creates a security group called web-ssh which allows inbound HTTP, HTTPS, and SSH.
./scripts/create-security-group.sh
Create a new keypair.
./scripts/create-keypair.sh
Load AWS environment and Deploy!
You can view ip of the server as follows.
./scripts/get-ip.sh