Vagrant is an open source tool for building and distributing virtual development environments. It provides framework to manage and create complete portable development environments.
Vagrant machines are provisioned on the top of VirtualBox, VMware, AWS, or any other provider supported by vagrant. This blog illustrates how we can launch and provision instances in EC2 using AWS provider supported by Vagrant.
Major advantage of using Vagrant to deploy AWS EC2 is that we can test our provisioning scripts in the actual environment where it will be deployed for production before deploying on actual EC2 machines.
I am assuming you have the latest version of Vagrant installed in your dev machine and familiar with Vagrantfile and its commandline. If you don’t know about Vagrant, you can visit the official documentation of Vagrant and learn about it.
You need to have a AWS account and the following
- AWS access key
- AWS secret key
- SSH keypair name
- SSH private key file (.pem extension)
- Make sure the your security group enables SSH (port 22) access from anywhere
The EC2 instance used to deploy here may not fit in your AWS Free Tier Plan and cost your money.
Setting Environment Variable
I like to set these up as environment variables to keep them out of the Vagrantfile. On Mac or Linux systems you can add this to your $HOME/.profile or $HOME/.bashrc file:
export AWS_KEY='your-access-key' export AWS_SECRET='your-secret-secret' export AWS_KEYNAME='your-keyname' export AWS_KEYPATH='your-keypath' export AWS_DEFAULT_REGION='your-region'
Will the steps to create a EC2 instance using vagrant:
- Install vagrant-aws plugin.
# vagrant plugin install vagrant-aws
- Fetch a Vagrant box image
Box images vary depending on the Vagrant “provider” that we use. Run the following command to download the dummy box which is provided by Vagrant-aws plugin:
# vagrant box add dummy https://github.com/mitchellh/vagrant-aws/raw/master/dummy.box
3.Configure Vagrant file
Make a directory to hold your Vagrant machine metadata.
Run the following commands:
# mkdir vagrant-aws # cd vagrant-aws # vagrant init
This will create a default Vagrant file in the present working directory which will be used to configure the vagrant machine. Edit this file as follows to specify the provider and configuration parameters to use AWS:
# Require the AWS provider plugin require 'vagrant-aws' # Create and configure the AWS instance(s) Vagrant.configure('2') do |config| # Use dummy AWS box config.vm.box = 'aws-dummy' # Specify AWS provider configuration config.vm.provider 'aws' do |aws, override| # Read AWS authentication information from environment variables aws.access_key_id = ENV['AWS_ACCESS_KEY_ID'] aws.secret_access_key = ENV['AWS_SECRET_ACCESS_KEY'] # Specify SSH keypair to use aws.keypair_name = 'ssh-keypair-name' # Specify region, AMI ID, and security group(s) aws.region = 'us-west-2' aws.ami = 'ami-20be7540' aws.security_groups = ['default'] # Specify username and private key path override.ssh.username = 'ubuntu' override.ssh.private_key_path = '~/.ssh/ssh-keypair-file' end end
- Launch the instance that is configured by the Vagrant file by running the following command:
# vagrant up --provider=aws
- Login to the AWS EC2 instance:
# vagrant ssh
The above setup will successfully provision a t2.micro EC2 machine via vagrant.
You can use this setup and integrate with other Vagrant provisioners such as Chef, Ansible etc. which will automatically install software and alter configurations directly on EC2 machines.
Working with newly created EC2 instance
You can connect via SSH, stop, reload or re-provision your newly created EC2 instance with regular Vagrant command like below
To SSH to instance # vagrant ssh To restart the instance or re-provision # vagrant reload [--provision] To stop # vagrant halt
- You need to configure a specific AMI for Vagrant to use. I find the Ubuntu Amazon EC2 AMI Finder very helpful to match the version and region I wanted to use.
- A common tripping point is the default security group not allowing SSH (port 22) from any IP address. Also make sure to add any other ports depending on your application (e.g., port 80 for HTTP).
- Once you have the basics working, make sure to read through the vagrant-aws project to understand all the options available.
- Make sure to vagrant destroy your VMs when done, and check the AWS Console to make sure they were terminated correctly (to avoid unexpected charges).
Why Use Vagrant with AWS?
The idea behind Vagrant—as I understand it—is to help simplify the creation of temporary environments to be used for testing, software development, etc. The ability to quickly and easily spin up instances on AWS makes using Vagrant with AWS a natural fit for these sorts of use cases, in my mind. It also keeps a consistent workflow for users: vagrant up creates local VMs or instantiates AWS instances, as appropriate.
In situations where you are creating more “permanent” infrastructure—such as deploying production applications onto AWS infrastructure—then I would say that Vagrant is not the right fit. In those cases, using a tool like Terraform (see my introductory post) or AWS CloudFormation would be more appropriate.