Capistrano で Ruby と chef のインストールを自動化

アプリサーバーで使うパッケージのセットアップを chef-solo で自動化できたけど、Ruby と chef をインストールする作業は手作業のまま。この部分も自動化したい。

そこで Capistrano を使って Ruby と chef をインストールするスクリプトを書いてみた。

# coding: utf-8
set :application, "<app name>"
set :user, "<username>"
set :port, 10022
set :ruby_version, "1.9.3-p194"

role :app, "<host name>"

default_run_options[:pty] = true

desc "git tasks"
namespace :git do
  desc "install git"
  task :install, :roles => :app do
    sudo "yum install -y git"
  end
end

desc "rbenv tasks"
namespace :rbenv do
  desc "delete old rbenv"
  task :cleanup, :roles => :app do
    run "rm ~/.bash_profile"
    run "rm -rf ~/.rbenv"
  end

  desc "checkout newest rbenv"
  task :checkout, :roles => :app do
    run "git clone https://github.com/sstephenson/rbenv.git ~/.rbenv"
  end

  desc "configure shell"
  task :config, :roles => :app do
    run "echo 'export PATH=$HOME/.rbenv/bin:$PATH' >> ~/.bash_profile"
    run "echo 'eval \"$(rbenv init -)\"' >> ~/.bash_profile"
    run "source ~/.bash_profile"
  end

  desc "install rbenv"
  task :install, :roles => :app do
    cleanup
    checkout
    config
  end
end

desc "ruby-build tasks"
namespace :ruby_build do
  desc "delete old ruby-build"
  task :cleanup, :roles => :app do
    run "rm -rf ~/.rbenv/plugins/ruby-build"
  end

  desc "checkout newest ruby-build"
  task :checkout, :roles => :app do
    run "git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build"
  end

  desc "install ruby-build"
  task :install, :roles => :app do
    cleanup
    checkout
  end
end

desc "ruby tasks"
namespace :ruby do
  desc "install required packages to build ruby"
  task :prepare, :roles => :app do
    sudo "yum install -y " + %w[
      gcc-c++
      zlib-devel
      httpd-devel
      openssl-devel
      curl-devel
      ncurses-devel
      gdbm-devel
      readline-devel
      sqlite-devel
    ].join(" ")
  end

  desc "build ruby"
  task :build, :roles => :app do
    run "rbenv install #{ruby_version}"
    run "rbenv global #{ruby_version}"
  end

  desc "install ruby"
  task :install, :roles => :app do
    prepare
    build
  end
end

desc "chef tasks"
namespace :chef do
  desc "install chef-solo"
  task :install, :roles => :app do
    run "gem install chef --no-rdoc --no-ri"
    run "rbenv rehash"
  end

  desc "checkout newest chef-repo"
  task :repo, :roles => :app do
    run "rm -rf chef-repo"
    run "git clone https://bitbucket.org/<username>/chef-repo.git"
  end

  desc "execute chef-solo"
  task :solo, :roles => :app do
    sudo "env PATH=$PATH chef-solo -c ~/chef-repo/.chef/solo.rb -j ~/chef-repo/.chef/chef.json"
  end
end

desc "setup application server"
task :setup, :roles => :app do
  git.install
  rbenv.install
  ruby_build.install
  ruby.install
  chef.install

  chef.repo
  chef.solo
end

Ruby は rbenv + ruby-build を使ってインストールする。rbenv と ruby-build のインストールするために、 git を最初にインストールするようにした。

この Capfile を

cap setup

で実行すると、Ruby と chef がインストールされ、chef-solo が実行される。サーバーのセットアップ作業の大部分がコマンド1つで済むようになった。

あと残すのは、ユーザー追加や SSH の設定だけど、この部分はどうしようかな。何とかして自動化できないか考えてみよう。