In part 1 of this series, we introduced the devops tool Vagrant. Vagrant makes it easy to create standardised environments in which software can be developed and deployed.
Vagrant creates these environments using “providers”. Examples of such providers are VirtualBox, KVM and VMWare. These three providers provide locally virtualised environments. Another example is Docker. Although Docker doesn’t employ virtualisation, it does provide standardisation through containerisation. There are also providers that allow one to create virtualised environments in the cloud, be it for Amazon AWS, Google Compute Engine or Microsoft Azure. VirtualBox is the only built-in provider Vagrant ships with. However, a plug-in mechanism exists that makes it easy to use additional providers.
In the previous post, some basic Vagrant concepts were introduced and VirtualBox served as the provider. In this post, we’ll see what changes are required in order to spin up our standardised environment on Amazon AWS, and how to manage it.
This post assumes that you are already familiar with the Amazon AWS cloud service. In particular, it assumes that you are have the following credentials set up and available:
- Access Key ID
- Secret Access Key
It also assumes that you have set up an SSH key and that you have properly configured a network security group to allow SSH access through the standard port, 22.
If any of this sounds unfamiliar to you, a number of useful links are given in the references below.
To have Amazon AWS serve as a Vagrant provider, it’s necessary to install a plugin. This is easy to do. Execute the following command in the terminal. Then wait until the process completes.
vagrant plugin install vagrant–aws
In the previous post, with VirtualBox as the provider, an Ubuntu 14.04 base image was used as the Vagrant box. As we move to Amazon AWS as our virtualisation provider, we also require a box. However, it won’t be an Ubuntu box, even if that’s the Operating System we’d ultimately like to have running on our virtual instance. Instead, we’ll have an AWS-specific proxy-box-of-sorts, and we’ll specify the Amazon Machine Image (AMI) we’d like to launch in our Vagrantfile.
To install this box, here called “dummy”, execute the following command:
vagrant box add dummy https://github.com/mitchellh/vagrant–aws/raw/master/dummy.box
Create a new directory in some convenient location and navigate into it:
As before, Vagrant-initialise the directory:
This command creates an unspoiled Vagrantfile file within the directory, effectively marking the directory as a Vagrant directory.
Open the Vagrantfile file and change its contents as follows, substituting your credentials and settings:
VAGRANTFILE_API_VERSION = “2”
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box = “dummy”
config.vm.provider :aws do |aws, override|
aws.access_key_id = “your_access_key_here”
aws.secret_access_key = “your_secret_access_key_here”
aws.security_groups = [“your_security_group_here”] # Group names if default VPC, group IDs otherwise.
aws.keypair_name = “your_keypair_name_here”
aws.region = “us-east-1”
aws.instance_type = “t1.micro”
aws.ami = “ami-32b9c05a”
override.ssh.username = “ubuntu”
override.ssh.private_key_path = “path_to_your_private_ssh_key_here” # Normally “./ssh/id_rsa”.
This configuration is set to launch a t1.micro instance in the us–east–1 AWS region using the 64-bit EBS AMI for Ubuntu 14.04.1 LTS, up to date as of 22 January 2015. (See here for the latest official daily AMIs for Ubuntu 14.04 LTS.)
To launch an instance, explicitly specify aws as the provider in the vagrant up command in the terminal:
vagrant up —provider=aws
If all the credentials and settings in the Vagrantfile file are properly set up, this should lead to output such as the following:
Bringing machine ‘default’ up with ‘aws’ provider...
==> default: Warning! The AWS provider doesn‘t support any of the Vagrant
==> default: high–level network configurations (`config.vm.network`). They
==> default: will be silently ignored.
==> default: Launching an instance with the following settings...
==> default: — Type: t1.micro
==> default: — AMI: ami–32b9c05a
==> default: — Region: us–east–1
==> default: — Keypair: hope1
==> default: — Block Device Mapping: 
==> default: — Terminate On Shutdown: false
==> default: — Monitoring: false
==> default: — EBS optimized: false
==> default: — Assigning a public IP address in a VPC: false
==> default: Waiting for instance to become “ready”...
==> default: Waiting for SSH to become available...
==> default: Machine is booted and ready for use!
==> default: Rsyncing folder: /Users/anthony/Desktop/vagrant_test/ => /vagrant
As in the case of the previous post, to gain command line access to the instance via SSH, issue the following command from within the Vagrant directory or a subdirectory:
You are now in command of a freshly minted but unprovisioned standardised environment. In the next blog post, we’ll explore how Chef can be used for automatic provisioning, allowing us to transform a vanilla environment such as this into a bespoke environment.
To exit the instance, type exit . This closes the SSH connection but the underlying virtual machine remains running. This can be confirmed by checking the AWS dashboard, or by issuing another call to vagrant ssh. VirtualBox instances are free to run since they run locally. However, cloud instances cost money. Therefore it’s important to destroy an instance once it’s no longer needed. This is done in the standard Vagrant way:
You will be asked to confirm the request.
The vagrant suspend command from the previous post doesn’t apply when AWS is the provider. On the other hand, the command vagrant halt stops an instance. To resume it, another call to vagrant up is required.
In the previous post, we saw how we were able to easily share resources between the external Vagrant-initialised directory and the standardised environment. Specifically, with VirtualBox as the provider, the external Vagrant-initialised directory and the /vagrant directory within the standardised environment are kept in sync continually and bi-directionally. (Under the hood, an NFS share is established by default.)
In the case where the AWS plugin serves as the provider, the sharing is more restricted: it is one-directional (from the external Vagrant-initialised directory towards the EC2 instance) and at specific cadences only (the calling of vagrant up , vagrant reload and vagrant provision). ( vagrant reload is simply a shortcut for vagrant halt followed by vagrant up ; vagrant provision will be used for provisioning in next post.)
In this post, we saw how we can use the same Vagrant life cycle commands ( vagrant up , vagrant halt , vagrant destroy , …) that we encountered before to manage Amazon AWS cloud instances. We also saw how to use the Vagrantfile file to configure such instances. Many more configuration options are available.
Finally, it’s important to remember to use vagrant destroy on cloud instances that are no longer needed. Otherwise you might rack up a bill that you don’t expect.