ChefでNginxをインストールするときにハマった


ローカル開発環境をつくろうとしてタイトルどおりうまくいかなくてあれやこれやしたことをメモ。。。

Vagrant + Chef + CentOS6.6 で作成

NginxをインストールするためにCookbookを作成します。

```bash:console
$ bundle exec knife cookbook create nginx -o ./site-cookbooks
```

[Chef実践入門](http://www.amazon.co.jp/Chef%E5%AE%9F%E8%B7%B5%E5%85%A5%E9%96%80-~%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AB%E3%82%88%E3%82%8B%E3%82%A4%E3%83%B3%E3%83%95%E3%83%A9%E6%A7%8B%E6%88%90%E3%81%AE%E8%87%AA%E5%8B%95%E5%8C%96-WEB-PRESS-plus/dp/477416500X)を参考にレシピを書いてみます（templateもあわせて用意）

```ruby:./site-cookbooks/nginx/recipes/default.rb
include_recipe "yum-epel"

package "nginx" do
  action :install
end

service "nginx" do
  action    [ :enable, :start ]
  supports  :status => true, :restart => true, :reload => true
end

template 'nginx.conf' do
  path      '/etc/nginx/nginx.conf'
  source    "nginx.conf.erb"
  owner     'root'
  group     'root'
  mode      0644
  notifies  :reload, "service[nginx]"
end

```

berksコマンドを実行します。
yum, yum-epelはコミュニティCookbookを使用。

```ruby:Berksfile
source "https://supermarket.getchef.com"

cookbook "yum"
cookbook "yum-epel"
cookbook "nginx", path: "./site-cookbooks/nginx"
```

```bash:console
$ bundle exec berks vendor ./cookbooks
```

Vagrantfileの方はこんな感じ

```ruby:Vagrantfile
…
  # vagrant-omnibusの有効化
  config.omnibus.chef_version = :latest

  config.vm.provision :chef_solo do |chef|
    chef.log_level = :debug
    chef.cookbooks_path = ["./cookbooks", "./site-cookbooks"]
    chef.json = {
      nginx: {
        port: 80
      }
    }
    chef.run_list = %w[
      recipe[yum]
      recipe[yum-epel]
      recipe[nginx]
    ]

  end

```

Provisionしてみる

```bash:console
$ vagrant up --provision
```

エラーが出てる。。。

```bash:console
…
==> default: [2015-06-16T14:55:35+00:00] INFO: Starting Chef Run for localhost
==> default: [2015-06-16T14:55:35+00:00] INFO: Running start handlers
==> default: [2015-06-16T14:55:35+00:00] INFO: Start handlers complete.
==> default: [2015-06-16T14:55:35+00:00] ERROR: Running exception handlers
==> default: [2015-06-16T14:55:35+00:00] ERROR: Exception handlers complete
==> default: [2015-06-16T14:55:35+00:00] FATAL: Stacktrace dumped to /var/chef/cache/chef-stacktrace.out
==> default: [2015-06-16T14:55:35+00:00] ERROR: Cookbook yum-epel not found. If you're loading yum-epel from another cookbook, make sure you configure the dependency in your metadata
==> default: [2015-06-16T14:55:35+00:00] FATAL: Chef::Exceptions::ChildConvergeError: Chef run process exited unsuccessfully (exit code 1)
Chef never successfully completed! Any errors should be visible in the
output above. Please fix your recipes so that they properly complete.
```

依存関係を定義しろと言われているようなのでmetadata.rbにyum-epelへの依存関係を追加します。

```ruby:./site-cookbooks/nginx/metadata.rb
name             'nginx'
maintainer       'YOUR_COMPANY_NAME'
maintainer_email 'YOUR_EMAIL'
license          'All rights reserved'
description      'Installs/Configures nginx'
long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
version          '0.1.0'
depends          'yum-epel'	#追加
```

再度berksコマンドの実行してからprovisionします。

```bash:console
$ bundle exec berks vendor ./cookbooks
$ vagrant provision
```

まだエラーが出ているけど内容は変わったみたいです。

```bash:console
…
==> default: [2015-06-20T01:23:18+00:00] ERROR: yum_package[nginx] (nginx::default line 21) had an error: Chef::Exceptions::Exec: yum -d0 -e0 -y install nginx-0.8.55-6.el5 returned 1:
==> default: STDOUT:  You could try using --skip-broken to work around the problem
==> default:  You could try running: rpm -Va --nofiles --nodigest
==> default: 
==> default: STDERR: Error: Package: nginx-0.8.55-6.el5.x86_64 (epel)
==> default:            Requires: perl(:MODULE_COMPAT_5.8.8)
==> default: Error: Package: geoipupdate-2.2.1-2.el5.x86_64 (epel)
==> default:            Requires: libcurl.so.3()(64bit)
==> default: [2015-06-20T01:23:18+00:00] FATAL: Chef::Exceptions::ChildConvergeError: Chef run process exited unsuccessfully (exit code 1)
Chef never successfully completed! Any errors should be visible in the
output above. Please fix your recipes so that they properly complete.
```

どうやらNginxのバージョンが0.8とか言ってて古い様子。。。
```vagrant ssh``` ゲストOSに入って一応yum-epelがあるか見てみるとあるっぽいので試しに```sudo yum install Nginx``` をしてみるとさっき出たエラーと同じようなものが出ました。いろいろ探してみるとyumにNginxのリポジトリを追加する必要があるみたいです。

[Nginxのwiki](http://wiki.nginx.org/)にインストール方法について丁寧に書かれていたので、それにしたがってrepoファイルを作成して配置してから同じように```sudo yum install Nginx```を実行してみるとうまくver.1.8がインストールできました。

repoファイルを用意すればうまくいくっぽいので、repoファイルのひな形をtemplatesに作成し、そのファイルを所定の位置に配置するようにレシピを修正します。

```ruby:./site-cookbooks/nginx/templates/default/nginx.repo.erb
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/6/$basearch/
gpgcheck=0
enabled=1
```

```ruby:./site-cookbooks/nginx/recipes/default.rb
include_recipe "yum-epel"

# yumにNginxのリポジトリを追加
template 'nginx.repo' do
  path    '/etc/yum.repos.d/nginx.repo'
  source  'nginx.repo.erb'
  mode    0644
  user    'root'
  group   'root'
end

package "nginx" do
  action :install
end

service "nginx" do
  action    [ :enable, :start ]
  supports  :status => true, :restart => true, :reload => true
end

template 'nginx.conf' do
  path      '/etc/nginx/nginx.conf'
  source    "nginx.conf.erb"
  owner     'root'
  group     'root'
  mode      0644
  notifies  :reload, "service[nginx]"
end

```

一応一旦仮想環境を削除してからやり直してみます。こういうことが気軽にできるのがChefの良い所ですね。

```bash:console
$ vagrant destory
$ bundle exec berks vendor ./cookbooks
$ vagrant up --provision
```

今度はうまくいったみたいです。