ChefでCentOS 6.7 + nginxを設置する。- カスタムクックブック


## 関連記事

* [Chefを使ってより効率的にサーバを管理しよう。まずは用語から](http://qiita.com/park-jh/items/9e2e358d2e82a7736cf7)
* [Berkshelfを使って外部クックブックをノードに適用する。](http://qiita.com/park-jh/items/751464a4cc6d8abcd6fd)
* [クックブックを作成してノードに適用する。- その１](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を設置する。- カスタムクックブック
* [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)

## クックブック

* 雛形生成

```sh
% bin/knife cookbook create nginx -o site-cookbooks
```

* 外部クックブックとカスタムクックブックが同じ名前で一緒に存在する場合、カスタムクックブックが優先される。

```sh
% cat .chef/knife.rb
cookbook_path    ["cookbooks", "site-cookbooks"]
node_path        "nodes"
role_path        "roles"
environment_path "environments"
data_bag_path    "data_bags"
# verbosity        :debug

knife[:berkshelf_path] = "cookbooks"
Chef::Config[:ssl_verify_mode] = :verify_peer if defined? ::Chef
```

## 属性（attribute）

* ハードコーディングすべきでない内容をattributeに記述する。
* バージョン番号、ディレクトリ名、ポート番号、ユーザ名、メモリやディスクの容量など
* [site-cookbooks/nginx/attributes/default.rb](https://github.com/devtopia/chef/blob/master/site-cookbooks/nginx/attributes/default.rb)

## レシピ

* 外部クックブックは各moduleをレシピで提供している。
* 提供されていない場合は新しいレシピを作成しなければならない。
* 最初はクックブックをオーバーライドすることを考えていたが、cookbooksの配下にあるレシピを直接修正しないとできないみたい。
* 外部クックブックを参考してtarballでインストールするカスタムクックブックを生成した。

```ruby
nginx_url = node['nginx']['url']
nginx_filename = "nginx-#{node['nginx']['ver']}.tar.gz"
src_filepath  = "#{Chef::Config['file_cache_path'] || '/tmp'}/#{nginx_filename}"

%w(pcre pcre-devel).each do |pkg|
  package pkg do
    action :install
  end
end

remote_file nginx_url do
  source nginx_url
  path src_filepath
  backup false
end

user node['nginx']['user'] do
  comment "create user of nginx"
  system true
  shell '/bin/false'
end

directory "/var/log/nginx" do
  owner 'root'
  group 'root'
  mode '0644'
  action :create
end

directory "#{node['nginx']['dir']}" do
  owner 'root'
  group 'root'
  mode '0755'
  action :create
end

cookbook_file "#{node['nginx']['dir']}/mime.types" do
  source 'mime.types'
  owner 'root'
  group 'root'
  mode '0644'
  notifies :reload, 'service[nginx]'
end

cookbook_file "#{node['nginx']['dir']}/authorized_ip" do
  source 'authorized_ip'
  owner 'root'
  group 'root'
  mode '0644'
  notifies :reload, 'service[nginx]'
end

template '/etc/sysconfig/nginx' do
  source 'nginx.sysconfig.erb'
  owner 'root'
  group 'root'
  mode '0644'
end

%w(/etc/init.d/nginx /etc/rc.d/init.d/nginx).each do |src|
  template src do
    source 'nginx.init.erb'
    owner 'root'
    group 'root'
    mode '0755'
  end
end

%w(sites-available sites-enabled).each do |dir|
  directory "#{node['nginx']['dir']}/#{dir}" do
    owner 'root'
    group 'root'
    mode '0755'
    action :create
  end
end

bash "install nginx" do
  cwd File.dirname(src_filepath)
  code <<-EOH
    tar zxf #{nginx_filename} -C #{File.dirname(src_filepath)}
    cd #{File.dirname(src_filepath)}/#{File.basename(nginx_filename, ".tar.gz")}
    ./configure #{configure_flags.join(' ')}
    make
    make install
  EOH

  notifies :restart, 'service[nginx]'
end

execute 'add to the list using the chkconfig command' do
  command 'chkconfig --add nginx && chkconfig nginx on'
  not_if 'chkconfig --list nginx'
end

template "#{node['nginx']['dir']}/nginx.conf" do
  source 'nginx.conf.erb'
  owner 'root'
  group 'root'
  mode '0644'
  notifies :reload, 'service[nginx]'
end

%w(default nginx_status).each do |site|
  template "#{node['nginx']['dir']}/sites-available/#{site}" do
    source "#{site}.erb"
    owner 'root'
    group 'root'
    mode '0644'
  end
end

%w(default nginx_status).each do |site|
  link "#{node['nginx']['dir']}/sites-enabled/#{site}" do
    to "#{node['nginx']['dir']}/sites-available/#{site}"
    notifies :reload, 'service[nginx]'
  end
end

service 'nginx' do
  action [:enable, :start]
end
```

## テンプレート

* [site-cookbooks/nginx/templates/default/default.erb](https://github.com/devtopia/chef/blob/master/site-cookbooks/nginx/templates/default/default.erb)
* [site-cookbooks/nginx/templates/default/nginx_status.erb](https://github.com/devtopia/chef/blob/master/site-cookbooks/nginx/templates/default/nginx_status.erb)
* [site-cookbooks/nginx/templates/default/nginx.conf.erb](https://github.com/devtopia/chef/blob/master/site-cookbooks/nginx/templates/default/nginx.conf.erb)
* [site-cookbooks/nginx/templates/default/nginx.init.erb](https://github.com/devtopia/chef/blob/master/site-cookbooks/nginx/templates/default/nginx.init.erb)
* [site-cookbooks/nginx/templates/default/nginx.sysconfig.erb](https://github.com/devtopia/chef/blob/master/site-cookbooks/nginx/templates/default/nginx.sysconfig.erb)

## 終了ステータスとは

* コマンド終了のとき、終了ステータスと呼ばれるコマンドの成否を表す数値が$?に自動で保持される。
* コマンド成功のときは０、失敗のときは１（０以外）が設定される。

## 終了ステータスの確認

* nginxがserviceとして登録されているのか確認したい。
* chkconfig --listで確認するとserviceに登録されているdaemonのリストが表示される。
* ここで表示されている場合はserviceで登録されていると見なす。
* serviceに登録されている場合

```sh
$ chkconfig --list nginx
nginx          	0:off	1:off	2:on	3:on	4:on	5:on	6:off
$ echo $?
0
```

* serviceで登録されていない場合

```sh
$ chkconfig --list nginx
error reading information on service nginx: No such file or directory
$ echo $?
1
```

* not_ifではブロックの場合、真偽で判断する。文字列の場合はコマンドの成功（0）や失敗（0以外）で判断する。

## 参考

* https://www.nginx.com/resources/wiki/start/topics/examples/initscripts/
* https://docs.chef.io/resource_template.html
* http://shellscript.sunone.me/exit_status.html