Chefを使うのに必要な環境が一気に整う「ChefDK」レビュー
ある日何気なく最新版のvagrant-berkshelf(4.0.4)を入れたところ、
It appears that you are not using the ChefDK. Please note that Vagrant Berkshelf works best when used with the ChefDK, and other installation methods are not officially supported. Please download and install the latest version of the ChefDK from: https://downloads.getchef.com/chef-dk and follow the installation instructions. Do not forget to add the ChefDK to your PATH.
というメッセージが表示されて vagrant up ができなくなってしまいました。メッセージを読むに、どうやらChefDKを使うようにと指示されています。
このChefDKについては存在は知っていて興味もあったのですが、実際に触れたことはなかったので、これを機に試してみることにしました。
ChefDK(Chef Development Kit)とは
ChefDKとはChefおよびポピュラーな関連ツール一式を簡単にインストールできるようにパッケージングしたソフトウェアになります。加えて新たなコマンドである chef
コマンドが含まれていて、ジェネレータとともにChefのワークフローを簡素化する狙いを担うとされています。
執筆時点でMac OSX、RHEL、Windows、Ubuntu、Debianに対応したパッケージが用意されており、[公式サイトのダウンロードページttps://downloads.getchef.com/chef-dk/)よりダウンロード&インストールできます。
最新バージョンである0.6.2では以下のものが含まれています。
chef
コマンド- Berkshelf 3.0
- Test Kitchen
- ChefSpec
- FoodCritic
- 既存のChefツール全て(Chef Client, Knife, Ohai and Chef Zero)
Chefの実行に必要なRubyやgemなども組み込まれており、従来とは違ってRubyのインストールやgemの準備を気にかける必要はありません。初めてChefを使う人にとってはぐっと導入が簡単になるので、大きな意味をもってくるでしょう。
なおバージョン番号から見るにChefDK自体はまだ正式リリースではないようなので、今後挙動や構成が変わる可能性もあるのでご注意ください。しかしインストールされるツールは chef
コマンドを除き今まで通りにgemで入れるのと変わりませんので、ChefDKによって入るknife
やchef-solo
などの従来のコマンドは問題なく動作すると考えていいでしょう。
ChefDKのインストール
今回はMac OSXで試します。まず公式サイトのダウンロードページよりMac OSX版をダウンロードしてインストールします。
パッケージからアプリをインストールするだけなので特に説明するようなことはありません。
インストールが完了すると /opt/chefdk 以下にもろもろのファイルが展開され、/usr/bin/ 以下にもシンボリックリンクが作成されています。
まっさらな環境であればこれで問題なくChefDKによるChefが動くようになっていたはずです。
しかしすでにRubyを導入済みの環境では話はそう簡単ではありませんでした。開発者であればrvmやrbenvを使っていることが多いので、その際には以下を参考にしてください。
既存のRuby環境との衝突
インストール後にvagrant upしてみると同じエラーメッセージが表示され、相変わらずうまく動きません。
berksコマンドの場所を確認してみると
$ which berks /Users/moongift/.rbenv/shims/berks
どうもrbenvでいれた既存のRubyのBerkshelfを使用しているようです。
ちなみに/usr/bin/berksを確認してみると以下のようにChefDKのものを指しています。
$ ls -l /usr/bin/berks lrwxr-xr-x 1 root wheel 21 11 25 13:47 /usr/bin/berks -> /opt/chefdk/bin/berks
この時の解決法として、3つのパターンで考えてみたいと思います。
解決策1 ChefDKのパスを優先
ChefDKのパスを優先することでChefDKで入れた方のberksコマンドが有効になります。
chef shell-init
を使うと、パス設定のコマンドが表示されるので、これを実行するか.bashrcや.zshrcに追加すればOKです。
$ chef shell-init zsh export PATH=/Users/moongift/.rbenv/bin:/Users/moongift/bin:/usr/local/bin:/usr/local/sbin:/opt/local/bin:/opt/local/sbin:/Users/moongift/.rbenv/shims:/Users/moongift/.rbenv/bin:/usr/bin:/bin:/usr/sbin:/sbin export GEM_ROOT="/opt/chefdk/embedded/lib/ruby/gems/2.1.0" export GEM_HOME=/Users/moongift/.chefdk/gem/ruby/2.1.0 export GEM_PATH=/Users/moongift/.chefdk/gem/ruby/2.1.0:/opt/chefdk/embedded/lib/ruby/gems/2.1.0
ですがこの設定を行うとChefDKで入れたツール一式は使えるようになりますが、逆に既存のRuby環境に影響が出てしまいます。Ruby製のツールを使っていたりRubyで開発している場合、この設定を適用することは難しいでしょう。
解決策2 既存のchefやberkshelfを削除
rbenvで入れているすべてのバージョンのRubyでBerkshelfのgemをアンインストールします。
そして以下のファイルは消えないので手動で消します。
$ rm /Users/moongift/.rbenv/shims/berks
この方法でもChefDKで入れたberksコマンドを有効にすることができます。
しかしこの方法ではインストール済みのRubyのバージョンが多い場合には大変な作業になりますし、何かの拍子(よく使うbundle install
など)でBerkshelfが入ってしまうと問題が再発します。そのため、あまり筋が良い解決法とは言えないでしょう。
解決策3 chef exec
を使う
chef exec
を使うことで解決策1で試したchef shell-init
で表示される環境変数を適用した状態でコマンドを実行できます。
$ chef exec which berks /opt/chefdk/bin/berks
しっかりとChefDKのberksを指し示していますね。試しにirbでchef exec
した時の環境変数を確認してみます。
$ chef exec irb irb(main):002:0> ENV["PATH"] => "PATH=/Users/moongift/.rbenv/bin:/Users/moongift/bin:/usr/local/bin:/usr/local/sbin:/opt/local/bin:/opt/local/sbin:/Users/moongift/.rbenv/shims:/Users/moongift/.rbenv/bin:/usr/bin:/bin:/usr/sbin:/sbin" irb(main):003:0> ENV["GEM_HOME"] => "/Users/moongift/.chefdk/gem/ruby/2.1.0" irb(main):004:0> ENV["GEM_ROOT"] => "\"/opt/chefdk/embedded/lib/ruby/gems/2.1.0\"" irb(main):005:0> ENV["GEM_PATH"] => "/Users/moongift/.chefdk/gem/ruby/2.1.0:/opt/chefdk/embedded/lib/ruby/gems/2.1.0"
どうやらこの解決策が最もスマートに思えます。そもそもの問題だった vagrant up
についても、
$ chef exec vagrant up
これで解決できます。これでこれまで通り仮想マシンが起動します。
ChefDKの環境にgemを入れる
実際に運用するとなると、Knifeのプラグインなどを入れるためにChefDKの環境にgemを使ったライブラリのインストールが必要になります。それには chef gem
を使います。
$ chef gem install knife-zero
または chef exec
を使う要領で
$ chef exec gem install knife-zero
でもOKです。ただせっかく用意されていますので chef gem
を使った方が良さそうです。
終わりに
今回はvagrant-berkshelfをきっかけにChefDKを軽く試してみました。
Chefを使っていると必要な他のgemとの依存関係の衝突やビルドエラーなどで悩むことがままありますが、ChefDKを使えば全部詰め合わせたChefが簡単に手に入るので、そうした煩わしさから解放されそうです。
chef
コマンドによる新たなワークフローの示唆に加え、vagrant-berkshelfのようにChefDKを前提とする周辺ツールが出てきていることもあり、今後はChefを使う上で欠かせないツールになるのではないでしょうか。