Berkshelfを使って外部クックブックをノードに適用する。


## 関連記事

* [Chefを使ってより効率的にサーバを管理しよう。まずは用語から](http://qiita.com/park-jh/items/9e2e358d2e82a7736cf7)
* Berkshelfを使って外部クックブックをノードに適用する。
* [クックブックを作成してノードに適用する。- その１](http://qiita.com/park-jh/items/8d641809850b5930d39c)
* [クックブックを作成してノードに適用する。- その２](http://qiita.com/park-jh/items/88237342cfd202e6893f)
* [ChefでCentOS 6.7 + rbenv + ruby 2.3.0の環境を構築する。](http://qiita.com/park-jh/items/f249a18793899f2eb4bf)
* [ChefでCentOS 6.7 + Vim 7.4 + luaを設置する。](http://qiita.com/park-jh/items/371d179d5e71618a1f14)
* [ChefでVimプラグインマネージャーNeoBundleを設置する。](http://qiita.com/park-jh/items/ec09e40f9b4aaf9fedfd)
* [Chefのレシピをデバッグしてみよう。](http://qiita.com/park-jh/items/96a076e167327a6a5a39)
* [ChefでCentOS 6.7 + nginxを設置する。- 外部クックブック](http://qiita.com/park-jh/items/3013c49494e524fced31)
* [ChefでCentOS 6.7 + nginxを設置する。- カスタムクックブック](http://qiita.com/park-jh/items/43451cea21ee1724c24b)
* [ChefでCentOS 6.7 + nodejs + npmを設置する。](http://qiita.com/park-jh/items/96089e7e1c97b0fe3a6c)
* [ChefでVimプラグインマネージャーvim-plugを設置する。](http://qiita.com/park-jh/items/ba27ad412ce9926fd94d)
* [ohaiのカスタムプラグインを作ってみよう。](http://qiita.com/park-jh/items/34be55abb7c63b36cddb)
* [Chef SoloからChef Zeroへ](http://qiita.com/park-jh/items/44c249c9de768c53b423)
* [Chefでnginx + php(php-fpm) + mariadb + wordpressを設置する。](http://qiita.com/park-jh/items/7515e47dddc38257a454)

## クックブックの生成

* クックブックを作成する方法には二つがある。
* 直接クックブックを作成するか誰かが提供する外部のクックブックを取得して利用するかだ。
* まずは外部のクックブックを取得して利用する方法について調べてみよう。

## ChefのSupermarket

* https://supermarket.chef.io/
* rubygems.orgから色んなgemのダウンロードができるのと同じくsupermarket.chef.ioでも色んなクックブックを提供している。
* 外部から提供されるクックブックはcookbooksというディレクトリに、直接作成するクックブックはsite-cookbooksというディレクトリに保持するのがルールだ。

## Berkshelfを用いた外部クックブックの適用

### クックブックを検索する。

* ChefのSupermarketでも検索ができるが、ここではknifeを使って検索してみよう。
* yumリポジトリであるepelを設置したい。
* yumというキーワードで検索するとyumが含まれた色んなクックブックが表示される。

```sh
  % bin/knife cookbook site search yum

  ... snip ...

  yum-epel:
  cookbook:             https://supermarket.chef.io/api/v1/cookbooks/yum-epel
  cookbook_description: Installs and configures the EPEL Yum repository
  cookbook_maintainer:  chef
  cookbook_name:        yum-epel

  ... snip ...
```

### クックブックの詳細を確認する。

* knifeを使えばクックブックの詳細も確認できる。
* epelというyumリポジトリの設置と設定を行うクックブックで、トータルで2700万を超えるダウンロード数を記録している。
* アップデートも2015年11月に行っている。（記事の作成日時は2016年2月）

```sh
  % bin/knife cookbook site show yum-epel

  average_rating:
  category:           Other
  created_at:         2013-12-13T20:15:48.000Z
  deprecated:         false
  description:        Installs and configures the EPEL Yum repository
  external_url:       https://github.com/chef-cookbooks/yum-epel
  foodcritic_failure: false
  issues_url:         https://github.com/chef-cookbooks/yum-epel/issues
  latest_version:     https://supermarket.chef.io/api/v1/cookbooks/yum-epel/versions/0.6.5
  maintainer:         chef
  metrics:
    downloads:
      total:    27101079
      versions:
        0.1.4: 1252114

  ... snip ...

        0.6.5: 2453344
    followers: 61
  name:               yum-epel
  source_url:         https://github.com/chef-cookbooks/yum-epel
  up_for_adoption:
  updated_at:         2015-11-23T19:45:00.706Z

  ... snip ...
```

### クックブックを取得する。

* Berksfileを開きyum-epelというクックブックを追加する。

```sh
  % vi Berksfile
  source "https://api.berkshelf.com"

  cookbook 'yum-epel'
```

* クックブックを取得する。
* cookbooksというディレクトリが生成されてその中に取得したクックブックが保持される。

```sh
  % bin/berks vendor cookbooks
```

* 取得されたクックブックを確認する。

```sh
  % cd cookbooks
  % tree . -L 2
  .
  ├── yum
  │   ├── CHANGELOG.md
  │   ├── CONTRIBUTING.md
  │   ├── MAINTAINERS.md
  │   ├── README.md
  │   ├── attributes
  │   ├── libraries
  │   ├── metadata.json
  │   ├── providers
  │   ├── recipes
  │   ├── resources
  │   └── templates
  └── yum-epel
      ├── CHANGELOG.md
      ├── CONTRIBUTING.md
      ├── MAINTAINERS.md
      ├── README.md
      ├── attributes
      ├── metadata.json
      └── recipes

  10 directories, 10 files
```

### クックブックをノードに適用する。

* ノードに適用するためにrun_listに取得したクックブックのレシピを追加する。

```sh
  % vi nodes/dev.json

  {
    "run_list": [
      "recipe[yum-epel]"
    ],
    "automatic": {
      "ipaddress": "dev"
    }
  }  
```

* knifeを使ってrun_listにクックブックのレシピを追加するのもできる。直接編集することよりこっちの方法を推奨する。
* chef-solo環境では -z オプション（又は--local-mode）を付ける。

```sh
  # レシピを追加する。
  % bin/knife node run_list add dev 'recipe[mariadb]' -z
  dev:
    run_list:
      recipe[yum-epel]
      recipe[mariadb]

  # 追加されたレシピを確認する。
  % cat nodes/dev.json
  {
    "name": "dev",
    "automatic": {
      "ipaddress": "dev"
    },
    "run_list": [
      "recipe[yum-epel]",
      "recipe[mariadb]"
    ]
  }

  # レシピを削除する。
  % bin/knife node run_list remove dev 'recipe[mariadb]' -z
```

* ノードにクックブックのレシピを適用する。

```sh
  % bin/knife solo cook dev
```

## knife-soloについて

* knifeは元々chefのサーバ・クライアント環境で使うツールである。
* knife-soloはchef-solo環境をリモートで操作できるようにknifeのコマンドを拡張したサブコマンドである。
* 実際soloコマンドはただこれしかない。

```sh
  ** SOLO COMMANDS **
  knife solo bootstrap [USER@]HOSTNAME [JSON] (options)
  knife solo clean [USER@]HOSTNAME
  knife solo cook [USER@]HOSTNAME [JSONFILE] (options)
  knife solo init DIRECTORY
  knife solo prepare [USER@]HOSTNAME [JSON] (options)
```

* 先ほどのknifeをコマンドを使ってrun_listにレシピを追加するとき-z オプションを付けたが付けないとエラーが発生する。

```sh
  % bin/knife node run_list add dev 'recipe[mariadb]'
  WARN: Failed to read the private key /etc/chef/client.pem: #<Errno::ENOENT: No such file or directory @ rb_sysopen - /etc/chef/client.pem>
  ERROR: Your private key could not be loaded from /etc/chef/client.pem
  Check your configuration file and ensure that your private key is readable
```

* knifeをchef-solo環境で使う場合はローカルモードで使いなさいというオプションを付けばよい。
* knife-soloコマンドはchef-solo環境のノードをリモートで操作するためのコマンドしか持ってない。

## 参考

* Chef実践入門