Monday, August 11, 2014

Expertimenting with Ruby, Sinatra & AWS

Lately I have started to explore Ruby and as part of my ramp-up I am getting familiar with all kind of interesting libraries and frameworks this language has to offer. One of these libraries is called Sinatra - which basically allows you to create web based REST api server side applications with minimum effort. The installation is as simple as -

sudo gem install sinatra

I immediately wanted to test it and the first thing that came to my mind was - Wouldn't it be cool to receive list of all my AWS EC2 instances by making a REST api call? Sounded easy enough. To accomplish this task I have also used the AWS SDK gem, which similarly can be installed with:

sudo gem install aws-sdk 

Make sure to have ruby development package installed for that to work (on Ubuntu 14.04 the package is called ruby1.9.1-dev).

OK, so now when we have all the pre-requirements  installed it's time to get our hands dirty...
So first of all we will need to import these libraries into our Ruby code:

require 'aws-sdk'
require 'sinatra'

Next I'll create a connector to AWS EC2 and pass it our AWS credentials and the relevant region:

ec2 = AWS::EC2::Client.new(region: 'eu-west-1',
    access_key_id: 'xxxx',
    secret_access_key: 'xxxx')


We will use the describe_instances method on the 'ec2' object to query our instances.
An object called 'resp' will hold the response from EC2 and will include all the information about our environment and present it as a nested hash:

resp = ec2.describe_instances

 .... we will iterate over the relevant has keys to filter out the desired output from the nested hash, collecting everything into array called 'machine_array':

machine_array = [ ]
resp[:reservation_set].each do |reservation_set|
    reservation_set[:instances_
set].each do |instance_set|
                       instance_set[:tag_set].sort.each do |name|

                       machine_array.push(name[:value]+" ")   
                  end
           end
end


I will embed it into a function called 'aws_list' that will return the machine_array (see final piece of code below):

Finally we will invoke the Sinatra web server and configure it in such way that our function will be executed each time a HTTP GET method to /aws_list is made:

get '/aws_list' do
    aws_list
end


That's all!
This is the code I have ended up with:
 
#!/usr/bin/ruby
require 'aws-sdk'
require 'sinatra'

def aws_list
machine_array = [ ]
ec2 = AWS::EC2::Client.new(region: 'eu-west-1',
    access_key_id: 'xxxx',
        secret_access_key: 'xxxx')
resp = ec2.describe_instances
resp[:reservation_set].each do |reservation_set|
    reservation_set[:instances_
set].each do |instance_set|
                instance_set[:tag_set].sort.each do |name|
           
machine_array.push(name[:value]+" ")
           
        end
    end
end
return
machine_array 
end

#invoke aws_list when HTTP request to /aws_list is received

get '/aws_list' do
    aws_list
end

No comments: