SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

近未来の技術トレンドを先取り! 「Tech-Sketch」出張所

構成管理ツール「Chef」の一歩進んだ使い方 ―独自のResourceを定義する―

近未来の技術トレンドを先取り! 「Tech-Sketch」出張所 第12回

rbenvをインストールするRecipeの作成

 まずは、install_rbenv.rbのRecipeを作成していきます。rbenvのインストール手順は大まかに以下のようになります(詳細についてはrbenvのgithubの公式ページを参照してください)。

  1. Rubyのインストールにあたってビルドに必要な依存パッケージをインストールする
  2. rbenvとrubyインストール用のプラグインをインストールする
  3. rbenv用の環境変数を設定する

 この流れに沿って、rbenvをインストールするRecipeを作成します。まずは、attributeにrbenvのインストール先ディレクトリとrbenvを使ってインストールするRubyのバージョンを定義します。

attributes/default.rb
default[:rbenv][:install_rbenv][:dir] = '/opt/rbenv'  # rbenvのインストール先
default[:rbenv][:install_ruby][:version] = '2.1.1'    # rbenvを使ってインストールするRubyのバージョン

 続いて、rbenv自体をインストールするRecipeを作成します。

recipes/install_rbenv.rb
# attributes定義より、rbenvをインストールするディレクトリ情報を取得します
install_dir = node[:rbenv][:install_rbenv][:dir]

# 1. packageリソースを使ってRubyのビルドに必要なパッケージをインストールします
%w( gcc-c++ glibc-headers openssl-devel readline readline-devel zlib zlib-devel ).each do |pkg|
  package pkg do
    action :install
  end
end

# 2-1. gitリソースを使ってrbenv本体をインストール先ディレクトリに配置します
git 'install rbenv' do
  user 'root'
  destination install_dir
  repository 'https://github.com/sstephenson/rbenv.git'
  not_if "ls #{install_dir}"
end

# directoryリソースを使ってrbenvのプラグインインストール用のディレクトリを作成します
directory "#{install_dir}/plugins" do
  owner 'root'
  group 'root'
  mode 0644
  action :create
end

# 2-2. gitリソースを使ってrbenvのプライグインをインストールします
git 'install ruby-build' do
  user 'root'
  destination "#{install_dir}/plugins/ruby-build"
  repository "https://github.com/sstephenson/ruby-build.git"
  action :checkout
  not_if "ls #{install_dir}/plugins/ruby-build"
end

# 3. bashリソースを使ってrbenv用の環境変数設定スクリプトを配置します
env_file = '/etc/profile.d/rbenv.sh'
bash 'set rbenv environment' do
  user 'root'
  code <<-EOH
  echo 'export RBENV_ROOT="#{install_dir}"' >> #{env_file}
  echo 'export PATH="$RBENV_ROOT/bin:$PATH"' >> #{env_file}
  echo 'eval "$(rbenv init -)"' >> #{env_file}
  EOH
  not_if "ls #{env_file}"
end

 最後に、Rubyをインストールしてバージョンを切り替えるRecipeを作成します。

recipes/install_ruby.rb
# attributes定義より、インストールするRubyのバージョン情報を取得します
install_version = node[:rbenv][:install_ruby][:version]
install_dir = node[:rbenv][:install_rbenv][:dir]
rbenv_path = "RBENV_ROOT=#{install_dir} #{install_dir}/bin"

# rbenvを使ってRubyのインストールを実行します
bash 'install ruby' do
  user 'root'
  code <<-EOH
  #{rbenv_path}/rbenv install #{install_version}
  #{rbenv_path}/rbenv rehash
  #{rbenv_path}/rbenv global #{install_version}
  EOH
  only_if do
    `#{rbenv_path}/rbenv install -l | grep -wc #{install_version}`.to_i > 0 &&
    `#{rbenv_path}/rbenv versions | grep -wc #{install_version}`.to_i == 0
  end
end

# インストールしたRubyを有効にします
bash 'switch ruby version' do
  user 'root'
  code <<-EOH
  #{rbenv_path}/rbenv rehash
  #{rbenv_path}/rbenv global #{install_version}
  EOH
  only_if "#{rbenv_path}/rbenv versions | grep -w #{install_version}"
end

 Recipeの作成後、chef-soloを実行する際に必要な設定ファイルであるrunlistと設定ファイルを作成します。runlistには実行対象のRecipeと実行順序を定義します。ここではrunlistのファイル名はnode.json、設定ファイルはsolo.rbとしてchef-soloを実行します(chef-soloの実行はRubyのコンパイルに少し時間がかかります)。

 まずrbenvをインストールして、次にrbenvを使ってRubyをインストールするようにrunlistとchef-soloを実行するための定義ファイルを作成します。

node.json
{
  "run_list": [
    "recipe[rbenv::install_rbenv]",
    "recipe[rbenv::install_ruby]"
  ]
}
solo.rb(環境に合わせて適宜修正してください)
cookbook_path ['/home/tis/chef-repo/cookbooks']  # 実行するCookbookの在処を定義します
log_level :info
chef-soloの実行
$ chef-solo -c solo.rb -j node.json
...chef-soloの実行...
...Chef Run complete in ~のメッセージを確認する...
$ ruby -v
ruby 2.1.1p76 (2014-02-24 revision 45161) [x86_64-linux]

 これで、Chefを使ってrbenvをインストールすることができました。しかし、ここではいくつかの問題があります。

  • Recipe内に大量のexecuteやbashリソースを使っているため、Recipeを見た際に何をやりたいかが把握しづらい
  • Rubyビルド用の依存パッケージのインストールがRedHat系Linuxでしか動かない

 このようにRecipeに書くコード量が多くなり、見通しが悪くなってしまった場合には、独自のResourceを定義して使用すると、executeやbashなどのResourceをRecipe内で使うのを防ぎ、Recipeをすっきりさせることが可能です。また、外部Resource化してRecipeの整理を行うと、Recipe内で実施すべきことを明確にできます。

 今回の場合は、インストールのRecipeでRubyビルド用パッケージのインストールとrbenvのインストールが混在しているため、これらを分割します。分割の方針としては、Rubyビルド用パッケージのインストールはRecipeに残し、rbenvのインストールやRubyのビルドは外部Resource定義に移動させます。

次のページ
独自のResourceを定義する

この記事は参考になりましたか?

近未来の技術トレンドを先取り! 「Tech-Sketch」出張所連載記事一覧

もっと読む

この記事の著者

秋穂 賢(TIS株式会社)(アキホ スグル)

TIS株式会社 戦略技術センター所属。TIS入社後の4年間、メインフレームを用いた大規模基幹システムのシステム管理や運用業務に従事。その後OSSの世界に飛び込み、推奨OSSミドルウェアスタック「ISHIGAKI Template」の開発やデザイン指向クラウドオーケストレーションソフトウェア「CloudConductor」の開発を経て、現在はOSSサポートビジネス立ち上げに携わっている。また、OSSの活動の一環でJobSchedulerと出会い、日本JobSchedulerユーザ会でも活動をしている。TISでは技術情報をブログ「Tech-Sketch」にて発信中。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/7767 2014/05/23 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー