Chefで各種アプリケーションの設定をしてvagrant upだけで開発環境が動かせるようにする


vagrantとchefを駆使すればコマンド一つでウェブサイトにアクセスできるようになります。
が、各種アプリケーションのインストールはBerkshelf使って`cookbook php`みたいに書けば簡単に行けるのですが、細かい設定をしようとするといろいろ面倒だったので、その辺りのよくある手順です。

今回作成したcookbookは一応下記にあります。
https://github.com/ykyk1218/setup-cookbooks

# 冪等性とは
「べきとうせい」と読みます。
これは何回実行しても同じ結果になる、という意味でChefはこの冪等性が重要な概念になってます。

なので、Chefのコマンドを使わずに自分でスクリプトを書く時も、この冪等性を意識しないといけないのです。

# ゲストOSにインストールするもの
* PHP
* Apache
* PostgreSQL

# ホストOSに必要なもの
* Vagrant 1.4.1
* Berkshelf 3.1.5
* Chef 11.14.2


# Apacheの設定
設定したドメインでアクセスできるようにバーチャルホストの設定をします。
実際やることとしては、テンプレートファイルを用意してChef側で、そのテンプレートファイルを指定の場所にコピーするようにします。

## Apacheのセットアップ用cookbookの用意
ホストOS側で実行
site-cookbooksディレクトリ以下にsetup-apacheのcookbookが作成される。

```
$ knife cookbook create setup-apache -o site-cookbooks
```

## バーチャルホスト設定が書かれた設定ファイルを用意

site-cookbooks/setup-apache/templates/default以下に拡張子を.erbにして配置
例えば下記の様なファイルをwww.example.com.conf.erbとして配置しておく。

```www.example.com.conf.erb
<Directory /var/www/vhosts/www.example.com/htdocs>
    Options FollowSymLinks
    AllowOverride All
</Directory>


<VirtualHost *:80>
    ServerAdmin webmaster@example.com
    DocumentRoot /var/www/vhosts/www.example.com/htdocs
    ServerName local.example.com
    ErrorLog "|/usr/sbin/rotatelogs /var/log/httpd/www.example.com/error_log.%Y%m%d 86400"
    CustomLog "|/usr/sbin/rotatelogs /var/log/httpd/www.example.com/access_log.%Y%m%d 86400" common
</VirtualHost>

<VirtualHost *:443>
    ServerAdmin webmaster@example.com
    DocumentRoot /var/www/vhosts/www.example.com/htdocs
    ServerName local.example.com
    ErrorLog "|/usr/sbin/rotatelogs /var/log/httpd/www.example.com/logs/ssl_error_log.%Y%m%d 86400"
    CustomLog "|/usr/sbin/rotatelogs /var/log/httpd/www.example.com/logs/ssl_access_log.%Y%m%d 86400" common
    SSLEngine on
    SSLCertificateFile /etc/httpd/ssl/server.crt
    SSLCertificateKeyFile /etc/httpd/ssl/server.key
</VirtualHost>
```

## Apacheのセットアップ用レシピを用意

### レシピファイルを開く

```
$ vi site-cookbooks/setup-apache/recipes/default.rb
```

### レシピの編集

```default.rb

#いろいろ設定が終わったあとにapacheサービスを立ち上げる
service "httpd" do
  action [:start, :enable]
  supports :restart => true, :reload => true
end

#テンプレートをコピー
template "www.example.com.conf" do
        path "/etc/httpd/sites-enabled/www.example.com.conf"
        owner "root"
        group "root"
        mode 0644
        notifies :reload, 'service[httpd]'
end

#SSL用の証明書とか
#開発環境用なのでオレオレ証明書で十分
template "server.crt" do
	path "/etc/httpd/ssl/server.crt"
	owner "root"
	group "root"
	mode 0644
end

template "server.key" do
	path "/etc/httpd/ssl/server.key"
	owner "root"
	group "root"
	mode 0644
end


#apahceのログを出力するディレクトリを作成
directory "/var/log/httpd/www.example.com" do
  owner "root"
  group "root"
  recursive true
  mode 0777
  action :create
end

```

一応
http://qiita.com/yando/items/728d84590a509439a04b

こんな自称もあるようですが、ログディレクトリなんであまり気にせず作成します。



# PHPの設定
php.iniの設定をします。
といっても上記と一緒でテンプレートファイルを用意してコピーでok

## PHPのセットアップ用cookbookの用意

```
$ knife cookbook create setup-php -o site-cookbooks
```

## php.iniを用意
site-cookbooks/setup-php/templates/default以下にphp.ini.erbを用意。
開発用なのでdisplay_errorsをOnにしたりとか。

## phpのセットアップ用レシピの用意

```
default.rbtemplate "php.ini" do
        path "/etc/php.ini"
        owner "root"
        group "root"
        mode 0644
end
```

# PostgreSQLの設定

## PostgreSQLのセットアップ用cookbookの用意

```
$ knife cookbook create setup-postgresql -o site-cookbooks
```

## PostgreSQLのセットアップ用レシピの用意
opscodeにdatabaseというcookbookがあって、それを使えばデータベースの作成等がすんなりできそうだったのですが、使い方よくわからなかったので自前で作りました(^^;


```default.rb
bash 'create_database' do
        user "postgres"
        code <<-EOH
                initdb -D /var/lig/pgsql9/data
                create role example_role
                create user example_user
                createdb example_dev
        EOH
        not_if "psql -U postgres -c \"select * from pg_database\" | grep -q example_dev", :user=>"postgres"
end


bash 'import_data' do
        user "postgres"
        code "psql example_dev < /vagrant/example_dev.dump"
        only_if "psql -U postgres -c \"select * from pg_database\" | grep -q example_dev", :user=>"postgres"
end
```

create_databaseの方はnot_ifを使ってデータベースがなければ実行。
import_dataの方はonly_ifを使ってデータベースがあれば実行、として冪等性を確保してます。

not_if、only_ifの最後に`:user=>"postgres"`とあるのですが、どうもここで指定しないとpostgresユーザーとして実行してくれないみたい。

example_dev.dumpはこのサイト用のスキーマ情報とかデータが入ったdumpファイルです。


# Vagrantfileに作成したcookbookを追記
作成したcookbookをchefのrunlistに追加しましょう。

```Vagrantfile
config.vm.provision :chef_solo do |chef|
・・・・
	chef.cookbooks_path = "site-cookbooks/"
	chef.run_list = [
		.....,
		"recipe[setup-php]",
		"recipe[setup-apache]",
		"recipe[setup-postgresql]"
	]
・・・・
end
```

# タイムゾーン設定とか

後はbootstrap.shを用意してvagrant upした時にサーバの細かい設定も変更するようにします。

```bootstrap.sh
#iptableは必要ないので止める
sudo /etc/init.d/iptables stop

#タイムゾーンの変更
sudo cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
```

Vagrantfileでbootstrap.shを読み込むようにしておく。

```Vagrantfile
config.vm.provision :shell,path:"bootstrap.sh"
```