Vagrant: AWS (Launch multiple instances)

By | 23/10/2015

Introduction

A while ago, I provided a short intro on deploying a single virtual machine onto AWS (see this post). Since I was wondering how difficult it would be to deploy multiple EC2 instances I gave this a try as well. It turned out to be relatively simple, below are my findings.

Since the Vagrantfile is basically Ruby language and -I admit- I’m not really a Ruby geek, I have been using a JSON file to provide the configuration details of my servers. I then parsed this JSON file in the Vagrantfile.

The JSON file is shown below. Essentially this file provides the necessary details for AWS, such as the keys, the region and availability zone you would want the servers to reside in, but also the instance details including the type and some tags). Really there is nothing more to it, just a rather simple JSON file.

{
    "access_key": "",
    "secret_key": "",
    "region": "eu-west-1",
    "availability_zone": "a",
    "security_groups": "sg-c47cd5a0",
    "keypair_name": "",
    "ssh_username": "ec2-user",
    "ssh_private_key_path": "",
    "subnet_id" : "subnet-05f39e5c",
    "instances": {
        "instance-001": {
	    "ami_id": "ami-69b9941e",
            "instance_type": "t2.small",
	    "tags": {
	       "Name": "Instance-001",
               "Role": "webserver"
            }
        },
        "instance-002": {
            "ami_id": "ami-69b9941e",
            "instance_type": "t2.medium",
            "tags": { 
               "Name": "Instance-002",
               "Role": "webserver"  
            }
	},
        "instance-003": {
            "ami_id": "ami-25158352",
            "instance_type": "t2.small",
            "tags": { 
               "Name": "Instance-003",
               "Role": "database"  
            }        
	}
    }
}

As mentioned before, the Vagrantfile would then be used to parse the JSON file. This happens immediately in the first line. We stored everything in the aws_config variable and use this variable to provide the information to the config2.vm.provider which is needed by Vagrant. The complete Vagrant file can be found below.

aws_config = (JSON.parse(File.read("aws-multiple.json")))

Vagrant.configure("2") do |config|

    config.vm.box = "dummy"
    config.vm.box_url = "https://github.com/mitchellh/vagrant-aws/raw/master/dummy.box"

    aws_config['instances'].each do |instance|
        instance_key   = instance[0]
        instance_value = instance[1]

        config.vm.define instance_key do |config2|
	    ec2_tags = instance_value['tags']

            config2.vm.provider :aws do |ec2, override|
                ec2.access_key_id = aws_config['access_key']
                ec2.secret_access_key = aws_config['secret_key']
                ec2.keypair_name = aws_config['keypair_name']
                ec2.region = aws_config['region']
                ec2.availability_zone = aws_config['region']+aws_config['availability_zone']
                ec2.subnet_id = aws_config['subnet_id']
                ec2.security_groups = aws_config['security_groups']
                ec2.ami = instance_value['ami_id']
                ec2.instance_type = instance_value['instance_type']
                ec2.tags = {
			'Name' => ec2_tags['Name'],
			'Role' => ec2_tags['Role']
		}
		override.ssh.username = aws_config['ssh_username']
                override.ssh.private_key_path = aws_config['ssh_private_key_path']
            end

        end
    end
end

Once we have the JSON file and the Vagrantfile in our directory, you can run ‘vagrant up’ and if all goes well, you will see multiple machines being launched on AWS. Obviously, as in previous Vagrant related posts, one can also SSH in using the SSH keys as provided in the JSON file.

macbookpro:aws-multiple wim$ sudo vagrant up
Bringing machine 'instance-001' up with 'aws' provider...
Bringing machine 'instance-002' up with 'aws' provider...
Bringing machine 'instance-003' up with 'aws' provider...
==> instance-002: Warning! The AWS provider doesn't support any of the Vagrant
==> instance-002: high-level network configurations (`config.vm.network`). They
==> instance-002: will be silently ignored.
==> instance-002: Warning! You're launching this instance into a VPC without an
==> instance-002: elastic IP. Please verify you're properly connected to a VPN so
==> instance-002: you can access this machine, otherwise Vagrant will not be able
==> instance-002: to SSH into it.
==> instance-002: Launching an instance with the following settings...
==> instance-002:  -- Type: t2.medium
==> instance-003: Warning! The AWS provider doesn't support any of the Vagrant
==> instance-003: high-level network configurations (`config.vm.network`). They
==> instance-003: will be silently ignored.
==> instance-002:  -- AMI: ami-69b9941e
==> instance-003: Warning! You're launching this instance into a VPC without an
==> instance-003: elastic IP. Please verify you're properly connected to a VPN so
==> instance-003: you can access this machine, otherwise Vagrant will not be able
==> instance-003: to SSH into it.
==> instance-003: Launching an instance with the following settings...
==> instance-002:  -- Region: eu-west-1
==> instance-002:  -- Availability Zone: eu-west-1a
==> instance-002:  -- Keypair: Keypair_Amazon_wauterw_Ireland
==> instance-002:  -- Subnet ID: subnet-05f39e5c
==> instance-001: Warning! The AWS provider doesn't support any of the Vagrant
==> instance-001: high-level network configurations (`config.vm.network`). They
==> instance-001: will be silently ignored.
==> instance-003:  -- Type: t2.small
==> instance-001: Warning! You're launching this instance into a VPC without an
==> instance-001: elastic IP. Please verify you're properly connected to a VPN so
==> instance-001: you can access this machine, otherwise Vagrant will not be able
==> instance-001: to SSH into it.
==> instance-002:  -- Security Groups: ["sg-c47cd5a0"]
==> instance-003:  -- AMI: ami-25158352
==> instance-001: Launching an instance with the following settings...
==> instance-002:  -- Block Device Mapping: []
==> instance-002:  -- Terminate On Shutdown: false
==> instance-003:  -- Region: eu-west-1
==> instance-002:  -- Monitoring: false
==> instance-001:  -- Type: t2.small
==> instance-003:  -- Availability Zone: eu-west-1a
==> instance-002:  -- EBS optimized: false
==> instance-003:  -- Keypair: Keypair_Amazon_wauterw_Ireland
==> instance-001:  -- AMI: ami-69b9941e
==> instance-003:  -- Subnet ID: subnet-05f39e5c
==> instance-002:  -- Assigning a public IP address in a VPC: false
==> instance-001:  -- Region: eu-west-1
==> instance-003:  -- Security Groups: ["sg-c47cd5a0"]
==> instance-001:  -- Availability Zone: eu-west-1a
==> instance-003:  -- Block Device Mapping: []
==> instance-003:  -- Terminate On Shutdown: false
==> instance-003:  -- Monitoring: false
==> instance-001:  -- Keypair: Keypair_Amazon_wauterw_Ireland
==> instance-001:  -- Subnet ID: subnet-05f39e5c
==> instance-001:  -- Security Groups: ["sg-c47cd5a0"]
==> instance-001:  -- Block Device Mapping: []
==> instance-003:  -- EBS optimized: false
==> instance-001:  -- Terminate On Shutdown: false
==> instance-003:  -- Assigning a public IP address in a VPC: false
==> instance-001:  -- Monitoring: false
==> instance-001:  -- EBS optimized: false
==> instance-001:  -- Assigning a public IP address in a VPC: false
==> instance-001: Warning! Vagrant might not be able to SSH into the instance.
==> instance-001: Please check your security groups settings.
==> instance-002: Warning! Vagrant might not be able to SSH into the instance.
==> instance-002: Please check your security groups settings.
==> instance-003: Warning! Vagrant might not be able to SSH into the instance.
==> instance-003: Please check your security groups settings.
==> instance-003: Waiting for instance to become "ready"...
==> instance-002: Waiting for instance to become "ready"...
==> instance-001: Waiting for instance to become "ready"...
==> instance-003: Waiting for SSH to become available...
==> instance-002: Waiting for SSH to become available...
==> instance-001: Waiting for SSH to become available...
==> instance-002: Machine is booted and ready for use!
==> instance-003: Machine is booted and ready for use!
==> instance-001: Machine is booted and ready for use!

In case you wouldn’t believe this piece of magic, see the result in below screenshot 🙂

AWS_Vagrant_multipleinstances