Deploying apps stored in Git to Rightscale – easy peasy (Git archive to S3, nothing but net)
Since I started using Rightscale for all my application needs I've found that I don't need things like Capistrano, Chef, or WarningShot. Rightscale has a really cool feature called "Rightscripts" that let you apply little snippets to a server at boot time, any time or decommission time.
Using Rightscripts (which I'm going to start sharing on my blog soon) I can apply a bunch of snippets to a server instance, and it essentially does all the 'dependency' resolution that people put together with things like those mentioned above.
I have a script called "deploy_vokle" which gets a tarball, unpacks it, does testing on it then boots up the server if the test pass. The one thing I was missing was how to get my code from git to my servers without my servers having a github account. Solution - Git archive the revision I want to release, send it to S3 and let my new servers pick it up at boot-time. First install the AWS gem.
1 2 3 4 | # First you need aws rubygem. gem install aws-s3 export AS3_ACCESS_KEY=YOUR_KEY_HERE export AS3_SECRET_KEY=YOUR_SECRET_HERE |
Then, put this script in a file called s3packager.rb and make it executable:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | require 'rubygems' require 'aws/s3' AWS::S3::Base.establish_connection!( :access_key_id => ENV['AS3_ACCESS_KEY'], :secret_access_key => ENV['AS3_SECRET_KEY'] ) def git_archive(revision='HEAD', filename = nil, format='tar') filename ||= revision if format == 'tar' filename = "#{filename}.tar.gz" else filename = "#{filename}.zip" end `git archive --format=#{format} #{revision} | gzip > #{filename}` if $? == 0 filename else return false end end def s3put(filename, opts={}) deploy_label = filename backup_label = "#{$REVISION}-#{filename}" file_ref = File.read File.expand_path(filename) # Push the package twice, once with the revision in the name, and once as the intended package # acts as a sort of back up of what has been pushed... [deploy_label, backup_label].each do |file_label| begin puts "Putting to S3: #{file_label}" AWS::S3::S3Object.store( file_label, file_ref, $BUCKET_NAME, :content_type => (file_label =~ /\.tar\.gz$/i ? 'application/x-gzip' : 'application/x-zip'), :access => :private ) rescue Exception => ex puts ex.message return false end end return true end def s3get(filename) local_filename = File.expand_path(filename) File.open(local_filename, 'w') do |new_file| AWS::S3::S3Object.stream(filename,$BUCKET_NAME) do |chunk| new_file.write chunk end end return File.exist?(filename) end if ARGV.index('-h') || ARGV.empty? puts "============================================================================" puts "Packages a git revision w/o git data to Amazon S3" puts "package.rb --bucket [BUCKET_NAME] --revision [REVISION|HEAD] --FILENAME [production|experimental|USER_DEF]" puts "To see revisions do 'git log'" puts "============================================================================" exit(0) end $REVISION = ARGV[ARGV.index('--revision') + 1] rescue nil $OUT_NAME = ARGV[ARGV.index('--filename') + 1] rescue nil $BUCKET_NAME = ARGV[ARGV.index('--bucket') + 1] rescue nil begin AWS::S3::Bucket.find $BUCKET_NAME rescue Exception => ex puts "Could not fetch bucket #{$BUCKET_NAME}, did you set $AS3_ACCESS_KEY & $AS3_SECRET_KEY?" exit(1) end if $REVISION.nil? puts "--revision is required" exit 3 end arch_file = git_archive($REVISION, $OUT_NAME) if arch_file && s3put(arch_file) puts "SUCCESS" else puts "FAILED" end # First |
Make it executable!
1 | chmod +x s3packager.rb |
Wanna use it? When ever you want to release something from git:
1 | s3packager.rb --revision YOUR_GIT_LOG_REVISION_ID --bucket YOUR_AMAZON_BUCKET --filename THE_NAME_OF_THE_FILE_YOUR_SERVER_IS_LOOKING_FOR |
If you need help:
1 | s3packager.rb -h |
Yay, your up in the clouds. Congrats.