40歳からのキャリアチェンジ

20代はエンジニア・PM、30代はWeb系エンジニア向けのキャリアアドバイザー。40代の今はフリーランスで開発含めて色々やってます。技術ネタとしてはRuby/RailsとJavaScript関連あたり

VagrantとChefな環境でカスタムレシピの適用にハマる

先日、Chefの環境構築を終わらせたので、パーフェクトRuby on Rails見ながら、ChefのレシピをVagrant上の仮想マシンに適用させる作業をしていきました。

途中までは問題なく出来た

ひとまず書籍を読み進めながら、まずは基本的なレシピだけを適用させる手順を試すことにしました。

P.282からP.290までの内容を読み進めつつ、仕事上必要になりそうなものを追加でインストールしてひとまず以下の様なファイルを作りました

Vagrantfile

VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|

  config.vm.box = "."
  config.vm.box = 'rails'
  config.ssh.forward_agent = true
  config.vm.network :forwarded_port, guest: 80, host:8080
  config.vm.synced_folder "src", "/vagrant_data"
  config.vm.provision :chef_solo do |chef|
    chef.cookbooks_path =["./cookbooks","./site-cookbooks"]
    chef.add_recipe 'build-essential'
    chef.add_recipe 'git'
    chef.add_recipe 'database'
    chef.add_recipe 'nodejs'
    chef.add_recipe 'xml'
    chef.add_recipe 'ruby_build'
    chef.add_recipe 'rbenv::system'
    chef.add_recipe 'nginx'
    chef.add_recipe 'imagemagick'
    chef.add_recipe 'libqt4'

    chef.json = {
      "rbenv" => {
        "global"    => "2.1.2",
        "rubies"    => [ "2.1.2"],
        "gems"      => {
          "2.1.2"   => [{'name' => 'bundler'}]
        }
      }
    }

  end
end

Berksfile

source "https://api.berkshelf.com"


cookbook 'build-essential'
cookbook 'git'
cookbook 'nodejs'
cookbook 'database'
cookbook 'xml'
cookbook 'ruby_build'
cookbook 'rbenv', :git => 'git://github.com/fnichol/chef-rbenv.git'
cookbook 'nginx'
cookbook 'imagemagick'
cookbook 'libqt4'

ハマった状況&解決方法

P.291のカスタムレシピを作るの所を試していたのですが、何度やってもsite-cookbooks以下のレシピを参照してくれない状況でした・・

自分の環境は

  • Mac OS X 10.9.3
  • Vagrant 1.6.3
  • chef 11.12.8
  • knife-solo 0.4.2
  • berkshelf 3.1.3

という感じです。

berkshelfがChefのcookbookとその依存関係を管理するツールっていうのをQiitaの投稿みて初めて知りました。あと、使ってるchefとかknife-soloのバージョンをどうやって調べるのか何気にわからなかったけど、

bundle show

で確認できるんですね・・・なんか使ってるツールが増えてて、それぞれの理解が浅いからこういう所でも手間取る。

先に解決した方法を書く

試行錯誤の上、昨夜やっと解決したので、それまでの経緯を時系列にまとめておこうと思いますが、もしかしたら、こういう情報を探し求めてる人がいるかもしれないので、先に結論書いておくとBerksfileに以下を追記したら、意図した通りに、site-cookbooks/rails_book_cookbook/recipes以下に生成したファイルを参照してくれるようになりました

cookbook "rails_book_cookbook", path: "./site-cookbooks/rails_book_cookbook"

なお、書籍の手順に従って作業してるので、カスタムレシピをまとめたクックブックを作るために

bundle exec knife cookbook create -o site-cookbooks rails_book_cookbook

として作業を進めています

以下は解決に至った経緯を思い出せる範囲でまとめを。

.chef/knife.rbを生成してみた

knife solo cook でsite-cookbooks下のcookbookを認識しない場合の対処法を参考にして

bundle exec knife solo init .

として、現在作成中のプロジェクト直下に.chef/knife.rbを生成して以下の様なディレクトリ構造&knife.rbを作ったのですがうまくいかず

.
├── .chef
│   └── knife.rb
├── Berksfile
├── Berksfile.lock
├── Vagrantfile
├── cookbooks
├── data_bags
├── environments
├── nodes
├── roles
├── site-cookbooks
│   └── rails_book_cookbook
│       ├── CHANGELOG.md
│       ├── README.md
│       ├── attributes
│       ├── definitions
│       ├── files
│       │   └── default
│       ├── libraries
│       ├── metadata.rb
│       ├── providers
│       ├── recipes
│       │   ├── default.rb
│       │   ├── git.rb
│       │   ├── keys.rb
│       │   └── ops_user.rb
│       ├── resources
│       └── templates
│           └── default
└── src

site-cookbooksではなくcookbooks配下にカスタムレシピを配置する

ダメ元で、

.
├── .chef
│   └── knife.rb
├── Berksfile
├── Berksfile.lock
├── Vagrantfile
├── cookbooks
│   ├── keys.rb
│   └── ops_user.rb

みたいな感じで実行したのですがこれもダメでした・・・

解決方法につながるヒント

どうやって辿り着いたか全く覚えてないけど、Vagrant + Chef solo + Berkshelfのセットアップ用ひな形までというページを見てたら

Berksfileを作成。

$ cd ..

$ vim Berksfile

site :opscode

cookbook "mysettings", path: "site-cookbooks/mysettings"

という記述がありました。

Berksfileにクックブックのパスを指定すればもしかしたら、うまくいくのかなと思って

source "https://api.berkshelf.com"

# 途中省略

cookbook "rails_book_cookbook", path: "./site-cookbooks/rails_book_cookbook"

として、Vagrantfileに

VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|

  config.vm.box = "."
  # 途中省略

    chef.add_recipe 'rails_book_cookbook::ops_user'
    chef.add_recipe 'rails_book_cookbook::keys'

としてみたところ、ようやく意図したようにレシピが適用されました。

それぞれのツールが何なのかイマイチわかってないところが多いのですが、ブログにまとめる作業を通じてちょっとづつそれぞれが何なのか少しは理解ができてきたかなぁと思ってます