From past experience of trying to get things up and running with AWS (Amazon Web Services), it can be a bit of a faff trying to work out what to set where the first time. So here’s an example of how to get a browser based application up and running on EC2 using vagrant from the command line.
(If you want to work through sorting the settings out via the AWS online management console, try Oliver Veits’ tutorial AWS Automation based on Vagrant — Part 2: Installation and Usage of the Vagrant AWS Plugin; you might also need to refer to Part 1: Getting started with AWS.)
This post in part assumes you know how to provision your own virtual machine locally using Vagrant. Here are the steps you need to take to be able to run an AWS provisioner (on a Mac or Linux machine… not sure about Windows?).
First up – sign up for AWS (get credit via the Github Education Pack)…
Pick up some credentials via AWS root Security Credentials (Access Keys (Access Key ID and Secret Access Key)):
Ensure that the key is active (Make Active).
There’s quite a bit of set up to do to configure the provisioner script. This can be done on the command line using the Amazon Command Line Interface (AWS CLI):
pip install --upgrade --user awscli
Now you need to configure the AWS CLI:
aws configure
Use the security credentials you picked up to configure the client*.
When we launch the AWS machine, vagrant needs to be able to access it via ssh using the public IP address automatically assigned to the machine. In deployment too, if we’re building specific services we want to be able to access over the web, we need to open up access to the ports those services are listening on.
By default, the machine will be locked down, so we need to open up specific ports by setting security rules. These are assigned on the basis of a security group. So lets create one of those (mine is named after the course VM I’m building…):
aws ec2 create-security-group --group-name tm351cloud --description "Security group for tm351 services"
We’re going to use this group in the .security_groups parameter in the Vagrantfile.
Now we need to create the security group rules. In my case, I want to open up ssh (port 22) to allow incoming traffic from my IP address, and ports 80, 35180 and 35181 to allow http traffic from anywhere. (The /0 suffix in the rules allows any IP format.)
MYIP=$(curl http://checkip.amazonaws.com/) aws ec2 authorize-security-group-ingress --group-name tm351cloud --protocol tcp --port 22 --cidr ${MYIP}/0 aws ec2 authorize-security-group-ingress --group-name tm351cloud --protocol tcp --port 80 --cidr 0.0.0.0/0 aws ec2 authorize-security-group-ingress --group-name tm351cloud --protocol tcp --port 35180 --cidr 0.0.0.0/0 aws ec2 authorize-security-group-ingress --group-name tm351cloud --protocol tcp --port 35181 --cidr 0.0.0.0/0 # Check the policies aws ec2 describe-security-groups --group-names tm351cloud
Having opened up at least the ssh port 22, we need to set up some SSH keys with a particular name (vagrantaws) that we will use with the vagrant .keypair_name parameter, and save them to a local file (vagrantaws.pem) with the appropriate permissions.
aws ec2 create-key-pair --key-name vagrantaws --query 'KeyMaterial' --output text > vagrantaws.pem chmod 400 vagrantaws.pem
The vagrant provisioner also requires specific access tokens (.access_key_id, .secret_access_key, .session_token) to access EC2. Create these tokens, entering your own duration (in seconds):
aws sts get-session-token --duration-seconds 129600
Now we can start to look at the Vagrant set up. Install the vagrant AWS provisioner:
vagrant plugin install vagrant-aws
After setting up the Vagrantfile, you will be able to provision your machine on AWS using:
vagrant up --provider=aws
Add a dummy box:
vagrant box add awsdummy https://github.com/mitchellh/vagrant-aws/raw/master/dummy.box
Now let’s look at the Vagrantfile:
#Set up the provider block config.vm.provider :aws do |aws, override| #Use the ec2 security group set previously aws.security_groups = ["tm351cloud"] #Whatever name we want override.vm.hostname = "tm351aws" #The name of the dummy box we added override.vm.box = "awsdummy" #Set up machine access using our keypair name and ssh key path override.ssh.username = "ubuntu" aws.keypair_name="vagrantaws" override.ssh.private_key_path = "vagrantaws.pem" #Use the values generated by the session token generator aws.access_key_id = "YOUR_KEY_ID" aws.secret_access_key = "YOUR_SECRET_ACCESS_KEY" aws.session_token = "YOUR_SESSION_TOKEN" #Specify a region and valid ami for that region, along with the desired instance size aws.region = "eu-west-1" aws.ami = "ami-971238f1" aws.instance_type="t2.small" end
Running vagrant up --provider=aws
should run the Vagrant provisioner with the AWS provider. Running vagrant destroy
will tear down the machine (so you don’t keep paying for it… I think the users, security groups and keypairs are free?)
To check on the IP address of your instance, run:
aws ec2 describe-instances
or check on the AWS EC2 console. You can also check the machine is ripped down correctly when you have finished with it from there.
(I need to check what happens if you vagrant suspend
and then vagrant resume
. Presumably, the state is preserved, but you are billed for storage, if not running time?)
*Alternatively, we could create a specific user with more limited credentials.
Create a user we can use to help set up the credentials to use with the vagrant provisioner:
aws iam create-user --user-name vagrant
Now we need to give that user permissions to build our EC2 instance, by attaching an appropriate security policy (AmazonEC2FullAccess). In other words, the Vagrantfile will make use of the AWS vagrant
user to provision the machine, so we need to give that AWS user the appropraite permissions on AWS:
aws iam attach-user-policy --user-name vagrant --policy-arn arn:aws:iam::aws:policy/AmazonEC2FullAccess
Generate some keys:
aws iam create-access-key --user-name vagrant
Then run aws configure
with the new keys.
One thought on “Getting Web Services Up and Running on Amazon Web Services (AWS) Using Vagrant and the AWS CLI”
Comments are closed.