capazon 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+ == 2007/03/27
2
+
3
+ * Initial Release
4
+ * Provides Capistrano tasks wrapping the Amazon EC2 API
@@ -0,0 +1,14 @@
1
+ Rakefile
2
+ README.txt
3
+ CHANGELOG.txt
4
+ Manifest.txt
5
+ setup.rb
6
+ examples/deploy.rb
7
+ lib/capazon/capistrano_plugin.rb
8
+ lib/capazon/configuration.rb
9
+ lib/capazon/meta_tasks.rb
10
+ lib/capazon/tasks.rb
11
+ lib/capazon/version.rb
12
+ lib/capazon.rb
13
+ test/test_helper.rb
14
+ test/capazon_test.rb
@@ -0,0 +1,55 @@
1
+ = Capazon
2
+
3
+ Capistrano tasks to manage Amazon EC2 Images.
4
+
5
+ == Installation
6
+
7
+ * <tt>gem install capazon</tt>
8
+ * Edit your your <tt>config/deploy.rb</tt>:
9
+
10
+ require 'capazon'
11
+
12
+ #AWS login info
13
+ set :aws_access_key_id, 'XXX'
14
+ set :aws_secret_access_key, 'X'
15
+
16
+ # Name of the keypair used to spawn and connect to the Amazon EC2 Instance
17
+ # Defaults to one created by the setup_keypair task
18
+ set :aws_keypair_name, "#{application}-capazon"
19
+
20
+ # Path to the private key for the Amazon EC2 Instance mentioned above
21
+ # Detaults to one created by setup_keypair task
22
+ set :aws_private_key_path, "#{Dir.pwd}/#{aws_keypair_name}-key"
23
+
24
+ #defaults to an ubuntu image
25
+ #set :aws_ami_id, "ami-e4b6538d"
26
+
27
+ #defaults to, um, default
28
+ #set :aws_security_group, "default"
29
+
30
+ == Tasks
31
+
32
+ ===== Notes:
33
+
34
+ * <em>All tasks <b>require</b> aws_access_key_id and aws_secret_access_key.</em>
35
+ * <em>All tasks optionally take environment variables in lieu of capistrano configuration variables.</em>
36
+
37
+ [+create_keypair+] Create a keypair aws_keypair_name and write out the generate private key to aws_private_key_path.
38
+ [+delete_keypair+] Deletes keypair aws_keypair_name.
39
+ [+describe_keypairs+] Describes keypairs.
40
+ [+describe_images+] Describes AMIs you have privilege to execute.
41
+ [+run_instance+] Runs an instance of aws_ami_id with access available via aws_keypair_name.
42
+ [+terminate_instance+] Terminates aws_instance_id.
43
+ [+describe_instances+] Describes running AMIs.
44
+ [+authorize_web_and_ssh_access+] Opens tcp access on port 80 and 22 to the aws_security_group.
45
+
46
+ ==== Experimental Tasks
47
+
48
+ [+run_and_configure_instance+] Runs an instance of aws_ami_id with access available via aws_keypair_name, and - very experimentally - changes the root password, adds a user, gives that user sudo rights, then writes out a new deploy.rb to allow this new instance to be used with the 'deprec' gem.
49
+
50
+ == Meta
51
+
52
+ Rubyforge Project Page:: http://rubyforge.org/projects/capazon
53
+ Author:: Jesse Newland (http://soylentfoo.jnewland.com) (jnewland@gmail.com[maito:jnewland@gmail.com])
54
+ Copyright:: Copyright (c) 2007 Jesse Newland
55
+ License:: Distributes under the same terms as Ruby
@@ -0,0 +1,54 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/clean'
4
+ require 'rake/testtask'
5
+ require 'rake/packagetask'
6
+ require 'rake/gempackagetask'
7
+ require 'rake/rdoctask'
8
+ require 'rake/contrib/rubyforgepublisher'
9
+ require 'fileutils'
10
+ require 'hoe'
11
+ include FileUtils
12
+ require File.join(File.dirname(__FILE__), 'lib', 'capazon', 'version')
13
+
14
+ AUTHOR = "jnewland"
15
+ EMAIL = "jnewland@gmail.com"
16
+ DESCRIPTION = "A Capistrano extension library to manage Amazon EC2 instances"
17
+ GEM_NAME = "capazon"
18
+ RUBYFORGE_PROJECT = "capazon"
19
+ HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
20
+
21
+
22
+ NAME = "capazon"
23
+ VERS = ENV['VERSION'] || (Capazon::VERSION::STRING)
24
+ CLEAN.include ['**/.*.sw?', '*.gem', '.config']
25
+ RDOC_OPTS = ['--quiet', '--title', "capazon documentation",
26
+ "--opname", "index.html",
27
+ "--line-numbers",
28
+ "--main", "README",
29
+ "--inline-source"]
30
+
31
+ class Hoe
32
+ def extra_deps
33
+ @extra_deps.reject { |x| Array(x).first == 'hoe' }
34
+ end
35
+ end
36
+
37
+ # Generate all the Rake tasks
38
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
39
+ hoe = Hoe.new(GEM_NAME, VERS) do |p|
40
+ p.author = AUTHOR
41
+ p.description = DESCRIPTION
42
+ p.email = EMAIL
43
+ p.summary = DESCRIPTION
44
+ p.url = HOMEPATH
45
+ p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
46
+ p.test_globs = ["test/**/*_test.rb"]
47
+ p.clean_globs = CLEAN #An array of file patterns to delete on clean.
48
+
49
+ # == Optional
50
+ p.changes = p.paragraphs_of('CHANGELOG.txt', 0..1).join("\n\n")
51
+ #p.extra_deps << %w(amazon-ec2 capistrano deprec mongrel_cluster)
52
+ p.extra_deps << %w(amazon-ec2 capistrano)
53
+ #p.spec_extras - A hash of extra values to set in the gemspec.
54
+ end
@@ -0,0 +1,22 @@
1
+ require 'capazon'
2
+
3
+ set :application, "railsapp"
4
+ set :repository, "http://svnhost.com/svn/#{application}"
5
+
6
+ set :aws_access_key_id, 'XXX'
7
+ set :aws_secret_access_key, 'X'
8
+ set :user, "desired_user"
9
+ set :username, user
10
+
11
+ # Name of the keypair used to spawn and connect to the Amazon EC2 Instance
12
+ # Defaults to one created by the setup_keypair task
13
+ set :aws_keypair_name, "#{application}-capazon"
14
+
15
+ # Path to the private key for the Amazon EC2 Instance mentioned above
16
+ # Detaults to one created by setup_keypair task
17
+ set :aws_private_key_path, "#{Dir.pwd}/#{aws_keypair_name}-key"
18
+
19
+ #defaults to an ubuntu image
20
+ #set :aws_ami_id, "ami-e4b6538d"
21
+
22
+ #set :aws_security_group, "default"
@@ -0,0 +1,3 @@
1
+ require 'rubygems'
2
+ ##
3
+ Dir[File.join(File.dirname(__FILE__), 'capazon/**/*.rb')].sort.each { |lib| require lib }
@@ -0,0 +1,106 @@
1
+ # Capistrano Plugin to provide access to the amazon-ec2 gem's methods
2
+ #
3
+ # Author:: Jesse Newland (jnewland@gmail.com)
4
+ # Copyright:: Copyright (c) 2007 Jesse Newland
5
+ # License:: Distributes under the same terms as Ruby
6
+
7
+ gem 'amazon-ec2'
8
+ require 'ec2'
9
+ module CapistranoPlugin
10
+
11
+ #returns an EC2::AWSAuthConnection object
12
+ def connect(auth)
13
+ amazon = EC2::AWSAuthConnection.new(auth[:AWS_ACCESS_KEY_ID], auth[:AWS_SECRET_ACCESS_KEY])
14
+ raise Exception, "Connection to AWS failed. Check your Access Key ID and Secret Access Key - http://aws.amazon.com/" if amazon.nil?
15
+ return amazon
16
+ end
17
+
18
+ def setup_keypair(auth,keypair_name,private_key_path=nil)
19
+ amazon = connect(auth)
20
+
21
+ #verify keypair doesn't already exist
22
+ raise Exception, "Keypair #{keypair_name} already exists." unless amazon.describe_keypairs(keypair_name).parse.empty?
23
+
24
+ #create keypair
25
+ private_key = amazon.create_keypair(keypair_name)
26
+ raise Exception, "Private Key not correctly generated" unless private_key.parse[0][0] == "KEYPAIR"
27
+ puts "Keypair \"#{keypair_name}\" generated"
28
+
29
+ unless private_key_path == nil
30
+ #write private key to file
31
+ text_private_key = private_key.parse.inject("") { |text_private_key, a| a.join("\t") + "\n" }
32
+ File.open(private_key_path, 'w') do |file|
33
+ file.write(text_private_key)
34
+ end
35
+ system "chmod 600 #{private_key_path}"
36
+ puts "Written to ./#{private_key_path}"
37
+ end
38
+ end
39
+
40
+ def delete_keypair(auth,keypair_name)
41
+ amazon = connect(auth)
42
+
43
+ raise Exception, "Keypair #{keypair_name} does not exist." if amazon.describe_keypairs(keypair_name).parse.empty?
44
+ keypair_response = amazon.delete_keypair(keypair_name).parse.to_s
45
+ raise Exception, "Failed Authorizing Web Access" unless keypair_response == "Keypair deleted."
46
+ puts "Keypair \"#{keypair_name}\" deleted"
47
+ end
48
+
49
+ def authorize_access(auth,group_name,ip_protocol,from_port,to_port,cidr_ip="0.0.0.0/0")
50
+ amazon = connect(auth)
51
+ web_security_response = amazon.authorize_security_group_ingress("", :groupName => group_name, :ipProtocol => ip_protocol, :fromPort => from_port, :toPort => to_port, :cidrIp => cidr_ip).parse.to_s
52
+ raise "Failed Authorizing Web Access" unless web_security_response == "Ingress authorized."
53
+ puts "Access Granted for #{group_name} group on interface #{cidr_ip} for #{ip_protocol} port(s) #{from_port} to #{to_port}."
54
+ end
55
+
56
+ def run_instance(auth,ami_id,keypair_name,group_ids=[],min_count=1,max_count=1,user_data=nil,base64_encoded=false)
57
+ amazon = connect(auth)
58
+ instance = amazon.run_instances(ami_id, :minCount=>min_count, :maxCount=>max_count, :keyname=>keypair_name, :groupIds=>group_ids, :userData=>user_data, :base64Encoded=>base64_encoded).parse[1]
59
+ raise Exception, "Instance did not start" unless instance[4] == "pending"
60
+ instance_id = instance[1]
61
+ puts "Instance #{instance_id} Startup Pending"
62
+
63
+ #loop checking for instance startup
64
+ puts "Checking every 10 seconds to detect startup for up to 5 minutes"
65
+ tries = 0
66
+ begin
67
+ instance_desc = amazon.describe_instances.parse.select { |i| i[1] == instance_id.to_s }[0]
68
+ raise "Server Not Running" unless instance_desc[4] == "running"
69
+ sleep 5
70
+ return instance_desc
71
+ rescue
72
+ puts "."
73
+ sleep 10
74
+ tries += 1
75
+ retry unless tries == 35
76
+ raise "Server Not Running"
77
+ end
78
+ end
79
+
80
+ def terminate_instance(auth,instance_id)
81
+ amazon = connect(auth)
82
+ amazon.terminate_instances(instance_id).parse
83
+ end
84
+
85
+ def describe_images(auth,imageIds=[], owners=[], executableBy=[])
86
+ amazon = connect(auth)
87
+ amazon.describe_images(imageIds,owners,executableBy).parse
88
+ end
89
+
90
+ def describe_instances(auth,instanceIds=[])
91
+ amazon = connect(auth)
92
+ amazon.describe_instances(instanceIds).parse
93
+ end
94
+
95
+ # def reboot_instances(*instance_ids)
96
+ # puts "not yet implmented"
97
+ # end
98
+
99
+ def describe_keypairs(auth,keyNames=[])
100
+ amazon = connect(auth)
101
+ amazon.describe_keypairs(keyNames).parse
102
+ end
103
+
104
+
105
+ end
106
+ Capistrano.plugin :capazon, CapistranoPlugin
@@ -0,0 +1,10 @@
1
+ # Author:: Jesse Newland (jnewland@gmail.com)
2
+ # Copyright:: Copyright (c) 2007 Jesse Newland
3
+ # License:: Distributes under the same terms as Ruby
4
+
5
+ Capistrano.configuration(:must_exist).load do
6
+ require 'deprec/recipes'
7
+
8
+ set :aws_ami_id, "ami-e4b6538d"
9
+ set :aws_security_group, "default"
10
+ end
@@ -0,0 +1,82 @@
1
+ # Author:: Jesse Newland (jnewland@gmail.com)
2
+ # Copyright:: Copyright (c) 2007 Jesse Newland
3
+ # License:: Distributes under the same terms as Ruby
4
+
5
+ Capistrano.configuration(:must_exist).load do
6
+ desc <<-DESC
7
+ Runs an instance of AWS_AMI_ID with AWS_KEYPAIR_NAME, and - very experimentally - changes the root password, adds a user, gives that user sudo rights, then writes out a new deploy.rb to allow this new instance to be used with the 'deprec' gem.
8
+ Requires Amazon authorization credentials:
9
+ AWS_ACCESS_KEY_ID, AWS_KEYPAIR_NAMEE
10
+ DESC
11
+ task :run_and_configure_instance do
12
+ create_keypair
13
+
14
+ access_key_id = ENV['AWS_ACCESS_KEY_ID'] || aws_access_key_id
15
+ secret_access_key = ENV['AWS_SECRET_ACCESS_KEY'] || aws_secret_access_key
16
+ ami_id = ENV['AWS_AMI_ID'] || aws_ami_id
17
+ keypair_name = ENV['AWS_KEYPAIR_NAME'] || aws_keypair_name
18
+ private_key_path = ENV['AWS_PRIVATE_KEY_PATH'] || aws_private_key_path
19
+ instance_desc = capazon.run_instance({:AWS_ACCESS_KEY_ID => access_key_id, :AWS_SECRET_ACCESS_KEY => secret_access_key},ami_id,keypair_name)
20
+
21
+ authorize_web_and_ssh_access
22
+
23
+ puts "Waiting one additional minute for startup..."
24
+ sleep 60
25
+
26
+ #change password
27
+ puts "Connecting to #{instance_desc[3]}..."
28
+ puts "Please create a secure root password"
29
+ system "ssh -o StrictHostKeyChecking=no -i #{private_key_path} root@#{instance_desc[3]} passwd"
30
+ puts "Creating #{user} user"
31
+ system "ssh -o StrictHostKeyChecking=no -i #{private_key_path} root@#{instance_desc[3]} 'groupadd wheel;useradd -m -G wheel -s /bin/bash #{user};passwd #{user}'"
32
+ puts "Adding wheel group to sudoers"
33
+ system "ssh -o StrictHostKeyChecking=no -i #{private_key_path} root@#{instance_desc[3]} 'chmod 640 /etc/sudoers; echo -e \"#{user}\tALL=(ALL)\tALL\" >> /etc/sudoers;chmod 440 /etc/sudoers'"
34
+ # puts "Setting up loopback interface"
35
+ # system "ssh -o StrictHostKeyChecking=no -i #{private_key_path} root@#{instance_desc[3]} 'echo -e \"127.0.0.1\tlocalhost\" > /etc/hosts;echo -e \"iface lo inet loopback\" >> /etc/network/interfaces;ifup lo'"
36
+ # puts "Appending source list"
37
+ # system "ssh -o StrictHostKeyChecking=no -i #{private_key_path} root@#{instance_desc[3]} 'echo -e \"deb http://archive.ubuntu.com/ubuntu edgy main restricted universe multiverse\ndeb http://archive.ubuntu.com/ubuntu/ edgy-updates main restricted universe multiverse\" >/etc/apt/sources.list'"
38
+
39
+ #append capazon config info
40
+
41
+ original = File.open("config/deploy.rb")
42
+ backup = File.open("config/deploy.rb.capazon", "w")
43
+ while original.gets do
44
+ backup.print $_
45
+ end
46
+ backup.close
47
+ original.close
48
+
49
+ puts "Overwriting capistrano configuration..."
50
+ system "yes | deprec --apply-to . --name #{application} --domain #{instance_desc[3]}"
51
+
52
+ puts "Updating deprec config with amazon information..."
53
+
54
+ deprec = File.open("config/deploy.rb")
55
+ capazon = File.open("config/deploy.rb.capazon")
56
+ deprec_capazon = File.open("config/deploy.rb.deprec_capazon", "w")
57
+
58
+ while deprec.gets do
59
+ if $. == 1 then
60
+ deprec_capazon.print "#Capazon Configuration\n"
61
+ deprec_capazon.print "\nset :aws_instance_id, '#{instance_desc[1]}'\n\n"
62
+ while capazon.gets do
63
+ unless $. == 1 || $_ == nil
64
+ deprec_capazon.print $_
65
+ end
66
+ end
67
+ end
68
+ unless $_ == nil || /^set :repository/.match($_) || /^set :application/.match($_) || /XXX/.match($_)
69
+ deprec_capazon.print $_
70
+ end
71
+ end
72
+
73
+ capazon.close
74
+ deprec.close
75
+ deprec_capazon.close
76
+ File.rename("config/deploy.rb", "config/deploy.rb.deprec")
77
+ File.rename("config/deploy.rb.deprec_capazon", "config/deploy.rb")
78
+
79
+ puts "Done!"
80
+ end
81
+
82
+ end
@@ -0,0 +1,112 @@
1
+ # Capistrano Plugin to provide access to the amazon-ec2 gem's methods
2
+ # Author:: Jesse Newland (jnewland@gmail.com)
3
+ # Copyright:: Copyright (c) 2007 Jesse Newland
4
+ # License:: Distributes under the same terms as Ruby
5
+
6
+ Capistrano.configuration(:must_exist).load do
7
+
8
+ desc <<-DESC
9
+ Create a keypair AWS_KEYPAIR_NAME and
10
+ write out the generate private key to AWS_PRIVATE_KEY_PATH.
11
+ Requires Amazon authorization credentials:
12
+ AWS_ACCESS_KEY_ID, AWS_KEYPAIR_NAME
13
+ DESC
14
+ task :create_keypair do
15
+ access_key_id = ENV['AWS_ACCESS_KEY_ID'] || aws_access_key_id
16
+ secret_access_key = ENV['AWS_SECRET_ACCESS_KEY'] || aws_secret_access_key
17
+ keypair_name = ENV['AWS_KEYPAIR_NAME'] || aws_keypair_name
18
+ private_key_path = ENV['AWS_PRIVATE_KEY_PATH'] || aws_private_key_path
19
+ capazon.setup_keypair({:AWS_ACCESS_KEY_ID => access_key_id, :AWS_SECRET_ACCESS_KEY => secret_access_key}, keypair_name, private_key_path)
20
+ end
21
+
22
+ desc <<-DESC
23
+ Deletes keypair AWS_KEYPAIR_NAME.
24
+ Requires Amazon authorization credentials:
25
+ AWS_ACCESS_KEY_ID, AWS_KEYPAIR_NAME
26
+ DESC
27
+ task :delete_keypair do
28
+ access_key_id = ENV['AWS_ACCESS_KEY_ID'] || aws_access_key_id
29
+ secret_access_key = ENV['AWS_SECRET_ACCESS_KEY'] || aws_secret_access_key
30
+ keypair_name = ENV['AWS_KEYPAIR_NAME'] || aws_keypair_name
31
+ capazon.delete_keypair({:AWS_ACCESS_KEY_ID => access_key_id, :AWS_SECRET_ACCESS_KEY => secret_access_key}, keypair_name)
32
+ end
33
+
34
+ desc <<-DESC
35
+ Runs an instance of AWS_AMI_ID with AWS_KEYPAIR_NAME.
36
+ Requires Amazon authorization credentials:
37
+ AWS_ACCESS_KEY_ID, AWS_KEYPAIR_NAME
38
+ DESC
39
+ task :run_instance do
40
+ access_key_id = ENV['AWS_ACCESS_KEY_ID'] || aws_access_key_id
41
+ secret_access_key = ENV['AWS_SECRET_ACCESS_KEY'] || aws_secret_access_key
42
+ ami_id = ENV['AWS_AMI_ID'] || aws_ami_id
43
+ keypair_name = ENV['AWS_KEYPAIR_NAME'] || aws_keypair_name
44
+ instance_desc = capazon.run_instance({:AWS_ACCESS_KEY_ID => access_key_id, :AWS_SECRET_ACCESS_KEY => secret_access_key},ami_id,keypair_name)
45
+ puts instance_desc.join("\t")
46
+ end
47
+
48
+ desc <<-DESC
49
+ Opens tcp access on port 80 and 22 to the specified security group.
50
+ Requires Amazon authorization credentials:
51
+ AWS_ACCESS_KEY_ID, AWS_KEYPAIR_NAME
52
+ DESC
53
+ task :authorize_web_and_ssh_access do
54
+ access_key_id = ENV['AWS_ACCESS_KEY_ID'] || aws_access_key_id
55
+ secret_access_key = ENV['AWS_SECRET_ACCESS_KEY'] || aws_secret_access_key
56
+ group_name = ENV['AWS_SECURITY_GROUP'] || (aws_security_group rescue "default")
57
+ capazon.authorize_access({:AWS_ACCESS_KEY_ID => access_key_id, :AWS_SECRET_ACCESS_KEY => secret_access_key},group_name,"tcp","80","80","0.0.0.0/0")
58
+ capazon.authorize_access({:AWS_ACCESS_KEY_ID => access_key_id, :AWS_SECRET_ACCESS_KEY => secret_access_key},group_name,"tcp","22","22","0.0.0.0/0")
59
+ end
60
+
61
+ desc <<-DESC
62
+ Terminates AWS_INSTANCE_ID.
63
+ Requires Amazon authorization credentials:
64
+ AWS_ACCESS_KEY_ID, AWS_KEYPAIR_NAME
65
+ DESC
66
+ task :terminate_instance do
67
+ access_key_id = ENV['AWS_ACCESS_KEY_ID'] || aws_access_key_id
68
+ secret_access_key = ENV['AWS_SECRET_ACCESS_KEY'] || aws_secret_access_key
69
+ instance_id = ENV['AWS_INSTANCE_ID'] || aws_instance_id
70
+ respnse = capazon.terminate_instance({:AWS_ACCESS_KEY_ID => access_key_id, :AWS_SECRET_ACCESS_KEY => secret_access_key}, instance_id)
71
+ puts respnse.join("\t")
72
+ end
73
+
74
+ desc <<-DESC
75
+ Describes keypairs.
76
+ Requires Amazon authorization credentials:
77
+ AWS_ACCESS_KEY_ID, AWS_KEYPAIR_NAME
78
+ DESC
79
+ task :describe_keypairs do
80
+ access_key_id = ENV['AWS_ACCESS_KEY_ID'] || aws_access_key_id
81
+ secret_access_key = ENV['AWS_SECRET_ACCESS_KEY'] || aws_secret_access_key
82
+ capazon.describe_keypairs({:AWS_ACCESS_KEY_ID => access_key_id, :AWS_SECRET_ACCESS_KEY => secret_access_key}).each do |keypair|
83
+ puts keypair.join("\t")
84
+ end
85
+ end
86
+
87
+ desc <<-DESC
88
+ Describes running AMIs.
89
+ Requires Amazon authorization credentials:
90
+ AWS_ACCESS_KEY_ID, AWS_KEYPAIR_NAME
91
+ DESC
92
+ task :describe_instances do
93
+ access_key_id = ENV['AWS_ACCESS_KEY_ID'] || aws_access_key_id
94
+ secret_access_key = ENV['AWS_SECRET_ACCESS_KEY'] || aws_secret_access_key
95
+ capazon.describe_instances({:AWS_ACCESS_KEY_ID => access_key_id, :AWS_SECRET_ACCESS_KEY => secret_access_key}).each do |instance|
96
+ puts instance.join("\t")
97
+ end
98
+ end
99
+
100
+ desc <<-DESC
101
+ Describes AMIs you have privilege to execute.
102
+ Requires Amazon authorization credentials:
103
+ AWS_ACCESS_KEY_ID, AWS_KEYPAIR_NAME
104
+ DESC
105
+ task :describe_images do
106
+ access_key_id = ENV['AWS_ACCESS_KEY_ID'] || aws_access_key_id
107
+ secret_access_key = ENV['AWS_SECRET_ACCESS_KEY'] || aws_secret_access_key
108
+ capazon.describe_images({:AWS_ACCESS_KEY_ID => access_key_id, :AWS_SECRET_ACCESS_KEY => secret_access_key}).each do |image|
109
+ puts image.join("\t")
110
+ end
111
+ end
112
+ end