Automated Deployment of AWS EC2 Instances With Vagrant and Puppet

The DevOps landscape is continuously evolving at an ever-increasing pace. Some of the tools and approaches that I had gotten accustomed to have just gotten better providing me with more options to play with, which is always a good thing.

One of the tools we use in our delivery process is vagrant by Mitchell Hashimoto. This allows us to provide all our developers an isolated environment to deploy and test applications on their local machines repeatedly and consistently.

By default, vagrant runs on virtualbox virtual machines. But, recently vagrant has been extended to run on AWS EC2, as well as other environments. This move has already impacted our tool chain and there are a number of other interesting features like parallel provisioning on AWS on the horizon.

So, to get started, you can get the latest version of vagrant (1.2.2 as of this post) at http://downloads.vagrantup.com/ for your operating system.

Then install the vagrant-aws plugin as follows –

Install vagrant-aws pluginlink
1
$ vagrant plugin install vagrant-aws

The next step is to setup your local environment with AWS credentials. Many projects would likely commit their Vagrant configuration to some version control repository. However it’s best to reference your local environment for the required keys. To do so, add the following to your local users’ ~/.profile file

Configuring AWS Credentials on your local machine
1
2
 export AWS_ACCESS_KEY="AKXXXXXXXXXXXXXXX"
 export AWS_SECRET_KEY="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"

Then we need to source the ~/.profile to make the variables available in the current shell session

source the ~/.profile file
1
 source ~/.profile

Every AWS EC2 instance would have an ssh key pair. I keep my ssh private key in ~/.ssh/development.pem

Now that we have our local environment in shape, we need to setup our vagrant configuration file – Vagrantfile. Copy this example Vagrantfile to your project root and modify with your details accordingly –

Example Vagrantfile for an AWS EC2 instance
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Vagrant.configure("2") do |config|
  config.vm.box = "ubuntu_aws"
  config.vm.box_url = "https://github.com/mitchellh/vagrant-aws/raw/master/dummy.box"
  config.vm.synced_folder "../.", "/vagrant", id: "vagrant-root"
  config.vm.provider :aws do |aws, override|
    aws.keypair_name = "development"
    override.ssh.private_key_path = "~/.ssh/development.pem"
    aws.instance_type = "t1.micro"
    aws.security_groups = "development"
    aws.ami = "ami-c5afc2ac"
    override.ssh.username = "ubuntu"
    aws.tags = {
      'Name' => 'Web App',
     }
  end

  config.vm.provision :puppet do |puppet|
    puppet.manifests_path = "puppet/manifests"
    puppet.manifest_file  = "init.pp"
    puppet.options = ["--fileserverconfig=/vagrant/puppet/fileserver.conf"]
  end
end

Then run the following to launch the instance from your project root –

launch EC2 instancelink
1
$ vagrant up --provider=aws

And there you have it ! You can ssh into the instance with the following –

ssh into the EC2 instancelink
1
$ vagrant ssh

Enjoy!

Comments