tl;dr
複数台の EC2 インスタンスに全く同じ作業をやりたくて, みんな大好き Capistrano 3 をセットアップしてみましたのでメモします. 個人的に Capistrano 2 しか使ったことなかったので, だいぶん戸惑いながらもやりたいことは一応出来ました.
俺はこうした
deploy.rb
インフラ関連の作業だと, サーバーにログインして何らかのコマンドを実行することが多いので, 放っておいても execute
メソッドが呼ばれまくる以下のような deploy.rb となりました. やりたいことは実にシンプルで, S3 バケット上にアップされている手製の RPM パッケージをサーバー上にダウンロード. ダウンロードした RPM パッケージを yum localinstall
だけです.
lock "~> 3.11.0" namespace 'ec2' do desc 'List files.' task :ls do on roles(:all) do execute "ls" end end desc 'Get packages.' task :get do on roles(:all) do execute "[ ! -d 'rpms' ] && mkdir rpms || echo 'skip'" execute "aws s3 sync s3://some.packages.your.domain/RPMS/ ./rpms/ --region=ap-northeast-1" end end desc 'Install packages.' task :install, :version do |task, args| on roles(:all) do within "/home/ec2-user/rpms" do execute :sudo, :yum, 'localinstall', '-y', "*#{args[:version]}*" end end end desc 'List up services.' task :services do on roles(:all) do execute :sudo, :chkconfig, '--list' end end desc 'Get service status.' task :status, :service do |task, args| on roles(:all) do execute :sudo, :service, args[:service], 'status' end end desc 'Restart service.' task :restart, :service do |task, args| on roles(:all) do execute :sudo, :service, args[:service], 'restart' end end end
Capistrano 2 の時代は, 以下の用に run
メソッドの後に普通にコマンドをべた書きしていました.
namespace :sample do task :taaaaask do run 'echo "Hello Servers!!"' end end
最新の Capistrano だと, execute
メソッドに続いて, コマンドは symbol で書く必要がありました. (最新でなくても, Capistrano 3 になった時点でこのような書き方になっていたのかもしれません)
namespace :sample do task :taaaaask do run :echo, 'Hello Servers!!' end end
更に, sudo
を絡めたい場合, 以下のように書けば動きました.
desc 'Restart service.' task :restart, :service do |task, args| on roles(:all) do execute :sudo, :service, args[:service], 'restart' end end end
上記のタスクは引数に指定したサービスを再起動するタスクです. 以下のように実行します.
bundle exec cap production restart[oreno-service]
tips
デフォルトタスクの無効化
cap -T
でずらずらーっと出力されるデフォルトタスクを無効 (タスク一覧から非表示) にしたいです.
$ bundle exec cap -T cap deploy # Deploy a new release cap deploy:check # Check required files and directories exist cap deploy:check:directories # Check shared and release directories exist cap deploy:check:linked_dirs # Check directories to be linked exist in shared cap deploy:check:linked_files # Check files to be linked exist in shared cap deploy:check:make_linked_dirs # Check directories of files to be linked exist in shared cap deploy:cleanup # Clean up old releases cap deploy:cleanup_rollback # Remove and archive rolled-back release cap deploy:finished # Finished cap deploy:finishing # Finish the deployment, clean up server(s) cap deploy:finishing_rollback # Finish the rollback, clean up server(s) cap deploy:log_revision # Log details of the deploy cap deploy:published # Published cap deploy:publishing # Publish the release cap deploy:revert_release # Revert to previous release timestamp cap deploy:reverted # Reverted cap deploy:reverting # Revert server(s) to previous release cap deploy:rollback # Rollback to previous release cap deploy:set_current_revision # Place a REVISION file with the current revision SHA in the current release path cap deploy:started # Started cap deploy:starting # Start a deployment, make sure server(s) ready cap deploy:symlink:linked_dirs # Symlink linked directories cap deploy:symlink:linked_files # Symlink linked files cap deploy:symlink:release # Symlink release to current cap deploy:symlink:shared # Symlink files and directories from shared to release cap deploy:updated # Updated cap deploy:updating # Update server(s) by setting up a new release cap doctor # Display a Capistrano troubleshooting report (all doctor: tasks) cap doctor:environment # Display Ruby environment details cap doctor:gems # Display Capistrano gem versions cap doctor:servers # Display the effective servers configuration cap doctor:variables # Display the values of all Capistrano variables cap ec2:get # Get packages cap ec2:install[version] # Install packages cap ec2:ls # List files cap ec2:restart[service] # Restart service cap ec2:services # List up services cap ec2:status[service] # Get service status cap git:check # Check that the repository is reachable cap git:clone # Clone the repo to the cache cap git:create_release # Copy repo to releases cap git:set_current_revision # Determine the revision that will be deployed cap git:update # Update the repo mirror to reflect the origin state cap git:wrapper # Upload the git wrapper script, this script guarantees that we can script git without getting an interactive prompt cap install # Install Capistrano, cap install STAGES=staging,production
必要なタスクだけを一覧に表示させたいので, 以下のように対象のタスクを .clear
メソッドでクリアします.
Rake::Task['deploy:check'].clear ... Rake::Task['git:wrapper'].clear Rake::Task['install'].clear
上記のように, 無効にしたいタスクをズラーっと記述したファイル (今回は disable_task.rb を用意) で, deploy.rb から require_relative
した. 以下のような感じになります.
require_relative 'disable_task' lock "~> 3.11.0" namespace 'ec2-monitor' do desc 'List files.' task :ls do on roles(:all) do execute "ls" end end ... end
以下のようにデフォルトのタスクを消し去ることが出来ました.
$ bundle exec cap -T cap ec2:get # Get packages cap ec2:install[version] # Install packages cap ec2:ls # List files cap ec2:restart[service] # Restart service cap ec2:services # List up services cap ec2:status[service] # Get service status
以上
- 一度に複数のサーバーを設定変更して, それが上手く動いた場合, なんだか偉くなった気持ちになるのは何なんでしょうか