capazon 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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