Wednesday, November 13, 2019

Retrieve List of AWS EC2 Instances in CSV with Ruby Script


1) Ensure Ruby is installed with at least version 2.3

For new CentOS/RHEL 8, run "sudo yum install @ruby"
For newer Ubuntu 16.04 and above, run "sudo apt install ruby"

For Old CentOS/RHEL 6 and 7, follow the steps from these links:
- https://lists.centos.org/pipermail/centos-announce/2016-July/021984.html
- https://www.softwarecollections.org/en/scls/rhscl/rh-ruby23/
- https://www.server-world.info/en/note?os=CentOS_6&p=ruby23

For Old Ubuntu 14.04, follow this link:
- https://www.server-world.info/en/note?os=Ubuntu_14.04&p=ruby23


2) Install Ruby AWS SDK libraries:

$ gem install aws-sdk

3) Create default config and credentials

$ mkdir ~/.aws
$ cd ~/.aws

$ vi config
[default]
region=us-west-2
output=json

$ vi credentials
[default]
aws_access_key_id=AAAAAOSFODNN7EXAMPLE
aws_secret_access_key=wJalrXUtnFEMIxK7MDENGxbPxRfiCYEXAMPLEKEY

4) Create Ruby script or run the commands from irb

# Import any necessary libraries
require 'aws-sdk-ec2'
require 'csv'

# Use cert from AWS SDK
Aws.use_bundled_cert!

# Define friendly name variables for each region
$regions = {
    :Virginia => ['us-east-1 ', 'US1'],
    :Ohio => ['us-east-2 ', 'US2'],
    :California => ['us-west-1 ', 'US3'],
    :Oregon => ['us-west-2 ', 'US4'],
    :Mumbai => ['ap-south-1 ', 'IN'],
    :Seoul => ['ap-northeast-2', 'KR'],
    :Singapore => ['ap-southeast-1', 'SG'],
    :Sydney => ['ap-southeast-2', 'AU'],
    :Tokyo => ['ap-northeast-1', 'JP'],
    :Canada => ['ca-central-1 ', 'CA'],
    :Frankfurt => ['eu-central-1 ', 'DE'],
    :Ireland => ['eu-west-1 ', 'IR'],
    :London => ['eu-west-2 ', 'UK'],
    :Paris => ['eu-west-3 ', 'FR'],
    :'Sao Paulo' => ['sa-east-1 ', 'BZ'],
}

# Prepare CSV header
$csv_array = [[
    "Location",
    "ID",
    "Name",
    "Type",
    "State",
    "Key Name",
    "Private IP",
    "Public IP",
    "Launch Time",
    "Core Count",
    "Image Name",
]]

# Function to generate CSV string
def generate_csv_string
    csv_string = CSV.generate do |csv|
        $csv_array.each do |row|
            csv << row
        end
    end
    return csv_string
end

# Loop all regions
def retrieve_all_regions
    $regions.each do |name,region|
        retrieve_from_region(name, region[0].strip, region[1].strip)
    end
end

# Retrieve the instances from specific region
def retrieve_from_region( name, reg, shortname )
    ec2 = Aws::EC2::Resource.new(region: reg)
    ec2.instances.each do |i|
        $csv_array << [
            "#{name.to_s} (#{shortname.to_s})",
            i.id.to_s,
            i.tags.select{|t| t.key=="Name"}[0]&.value.to_s,
            i.instance_type.to_s,
            i.state.name.to_s,
            i.key_name.to_s,
            i.private_ip_address.to_s,
            i.public_ip_address.to_s,
            i.launch_time.to_s,
            i.cpu_options.core_count.to_s,
            (i.image.name.to_s rescue ""),
        ]
    end
end

# Run it
if (__FILE__ == $0)
    retrieve_all_regions
    File.open("./myaws_instaces.csv", "w") {|f| f.write( generate_csv_string) }
end

5) Done, life is made simpler with Ruby