John Trengrove

home posts about

Automated Deployment to AWS with vagrant-aws

18 Jun 2016

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:

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!

source ./scripts/aws-env.sh
vagrant up --provider=aws

You can view ip of the server as follows.

./scripts/get-ip.sh