Chef + Vagrant でローカル環境にWEBアプリを自動構築してみた（DBなし編）

# はじめに

[前回](http://qiita.com/tsuyopooon/items/d90679d9f8b5ccfcfde5) に引き続き、ローカルテスト環境の構築を目指して頑張っていきます。

自作 recipe を作成するためにいろいろ調べていると、 cookbooks がサードパーティ、site-cookbooks は自作 recipe 用のディレクトリとして推奨されているので、今回はそれに従って作成していきたいと思います。

```bash
$ cd test_centos64
```

Vagrantfile の cookbooks_path に site-cookbooks を追加します。

```vim:Vagrantfile
・・・
  config.vm.provision "chef_zero" do |chef|
    chef.cookbooks_path = ["./chef-repo/cookbooks", "./chef-repo/site-cookbooks"]
    ・・・
  end
・・・
```

# cookbookの作成

## Git

特別に自作 recipe でやりたい事はないので、サードパーティの cookbook を利用します。

Berksfile ファイルに追記します。

```vim:chef-repo/Berksfile
source "https://supermarket.chef.io"

cookbook 'timezone-ii', git: "https://github.com/L2G/timezone-ii.git"
# gitを追加
cookbook 'git'
```

インストール。

```bash
$ pushd chef-repo/; berks vendor cookbooks; popd;
$ tree chef-repo/cookbooks/git
chef-repo/cookbooks/git
├── CHANGELOG.md
├── README.md
├── attributes
│   └── default.rb
├── libraries
│   └── matchers.rb
├── metadata.json
├── providers
│   └── config.rb
├── recipes
│   ├── default.rb
│   ├── server.rb
│   ├── source.rb
│   └── windows.rb
├── resources
│   └── config.rb
└── templates
    └── default
        ├── git-xinetd.d.erb
        ├── sv-git-daemon-log-run.erb
        └── sv-git-daemon-run.erb
```

run_list に追加。

```vim:chef-repo/roles/common.json
{
  "name": "common",
  "chef_type": "role",
  "json_class": "Chef::Role",
  "default_attributes": {
    "tz": "Asia/Tokyo"
  },
  "run_list": [
    "recipe[timezone-ii::rhel]",
    "recipe[git]"
  ]
}
```

## iptables

今回はローカル環境での構築が目的なので、手を抜いてファイアーウォールは切りたいと思います。

これについても、サードパーティの cookbook を利用します。

Berksfile ファイルに追記します。

```vim:chef-repo/Berksfile
source "https://supermarket.chef.io"

cookbook 'timezone-ii', git: "https://github.com/L2G/timezone-ii.git"
cookbook 'git'
# iptablesを追加
cookbook 'iptables'
```

インストール。

```bash
$ pushd chef-repo/; berks vendor cookbooks; popd;
$ tree chef-repo/cookbooks/iptables
chef-repo/cookbooks/iptables
├── Berksfile
├── CHANGELOG.md
├── CONTRIBUTING
├── LICENSE
├── README.md
├── metadata.json
├── providers
│   └── rule.rb
├── recipes
│   ├── default.rb
│   └── disabled.rb
├── resources
│   └── rule.rb
└── templates
    └── default
        ├── iptables_load.erb
        └── rebuild-iptables.erb
```

run_list に追加。

```vim:chef-repo/roles/common.json
{
  "name": "common",
  "chef_type": "role",
  "json_class": "Chef::Role",
  "default_attributes": {
    "tz": "Asia/Tokyo"
  },
  "run_list": [
    "recipe[timezone-ii::rhel]",
    "recipe[git]",
    "recipe[iptables::disabled]"
  ]
}
```

## Apache

テスト環境ということもあり、のちのちカスタマイズできた方がいいんじゃないかなということで、自作 recipe にします。

なにわともあれ、template を作成します。

```bash
$ pushd chef-repo/; knife cookbook create apache2 -o site-cookbooks; popd;
$ tree chef-repo/site-cookbooks/apache2/
chef-repo/site-cookbooks/apache2/
├── CHANGELOG.md
├── README.md
├── attributes
│   └── default.rb
├── definitions
├── files
│   └── default
├── libraries
├── metadata.rb
├── providers
├── recipes
│   └── default.rb
├── resources
└── templates
    └── default
        └── virtualhost.conf.erb
```

続いて、recipe を作成していきます。

virtualhost用 の conf のテンプレートを用意。

```ruby:chef-repo/site-cookbooks/apache2/templates/default/virtualhost.conf.erb
NameVirtualHost *:80
Include conf.d/virtualhost/*.conf
```

recipe の作成。

```ruby:chef-repo/site-cookbooks/apache2/recipes/default.rb
# インストール
package "httpd" do
  action :install
end

# virtualhostディレクトリ作成
directory "/etc/httpd/conf.d/virtualhost" do
  owner "root"
  group "root"
  mode 0755
  action :create
end

# conf の配置
template "virtualhost.conf" do
  path "/etc/httpd/conf.d/virtualhost.conf"
  source "virtualhost.conf.erb"
  mode 0644
end

# 起動と自動起動の設定
#  sudo service httpd start
#  sudo chkconfig on
service "httpd" do
  action [:start, :enable]
end
```

run_list に追加。

```vim:chef-repo/roles/webserver.json
{
  "name": "webserver",
  "chef_type": "role",
  "json_class": "Chef::Role",
  "run_list": [
    "recipe[apache2]"
  ]
}
```

## PHP

template を作成。

```bash
$ pushd chef-repo/; knife cookbook create php -o site-cookbooks; popd;
```

続いて、recipe を作成していきます。

デフォルトのタイムゾーンを「Asia/Tokyo」に設定します。

まず、attribute を作成。

```ruby:chef-repo/site-cookbooks/php/attributes/default.rb
default["php"]["timezone"] = "Asia/Tokyo"
```

次に、PHP の TimeZone のテンプレートを用意。

```ruby:chef-repo/site-cookbooks/php/templates/default/timezone.ini.erb
date.timezone = "<%= node[:php][:timezone] %>"
```

最後に recipe の作成。

```ruby:chef-repo/site-cookbooks/php/recipes/default.rb

# インストール

package "php" do
  action :install
end

package "php-devel" do
  action :install
end

package "php-mysql" do
  action :install
end

package "php-mbstring" do
  action :install
end

package "php-gd" do
  action :install
end


# ini の配置
template "timezone.ini" do
  path "/etc/php.d/timezone.ini"
  source "timezone.ini.erb"
  mode 0644
  notifies :restart, 'service[httpd]'
end
```

run_list に追加。

```vim:chef-repo/roles/webserver.json
{
  "name": "webserver",
  "chef_type": "role",
  "json_class": "Chef::Role",
  "default_attributes": {
    "php": {
      "timezone": "Asia/Tokyo"
    }
  },
  "run_list": [
    "recipe[apache2]",
    "recipe[php]"
  ]
}
```

## Application

template を作成。

```bash
$ pushd chef-repo/; knife cookbook create app -o site-cookbooks; popd;
```

続いて、recipe を作成していきます。

まず、attribute を作成。

```ruby:chef-repo/site-cookbooks/app/attributes/default.rb
default["app"]["name"] = "hoge.com"
default["apache"]["domain_name"] = "local.hoge.com"
default["apache"]["document_root"] = "/www/hoge.com"
```

次に、virtualhost の conf のテンプレートを用意。

```vim:chef-repo/site-cookbooks/app/templates/default/virtualhost.conf.erb

NameVirtualHost *:80

<VirtualHost *:80>
    ServerName   <%= node[:apache][:domain_name] %>
    DocumentRoot <%= node[:apache][:document_root] %>/htdocs
    ErrorLog     <%= node[:apache][:document_root] %>/logs/error_log
    CustomLog    <%= node[:apache][:document_root] %>/logs/access_log combined
    CustomLog    <%= node[:apache][:document_root] %>/logs/deflate_log deflate
    DirectoryIndex index.php index.html
 
    <Directory "<%= node[:apache][:document_root] %>/htdocs">
        AllowOverride All
        Options ExecCGI FollowSymlinks MultiViews
        Order allow,deny
        Allow from all
    </Directory> 
</VirtualHost>
```

テスト用の html も用意。

```vim:chef-repo/site-cookbooks/app/files/default/test_index.html
<!DOCTYPE html>
<html lang="ja">
<head>
</head>
<body>
Hello!!
</body>
</html>
```

最後に recipe の作成。

```ruby:chef-repo/site-cookbooks/app/recipes/default.rb

# アプリ用ディレクトリ作成
directory "#{node[:apache][:document_root]}/htdocs" do
  mode '0755'
  owner 'vagrant'
  group 'vagrant'
  recursive true
  action :create
end

directory "#{node[:apache][:document_root]}/logs" do
  mode '0755'
  owner 'vagrant'
  group 'vagrant'
  recursive true
  action :create
end

# テスト用アプリの配置
cookbook_file "#{node[:apache][:document_root]}/htdocs/index.html" do
  source "test_index.html"
  mode '0755'
  owner 'vagrant'
  group 'vagrant'
end

# conf の配置
template "#{node[:app][:name]}.conf" do
  path "/etc/httpd/conf.d/virtualhost/#{node[:app][:name]}.conf"
  source "virtualhost.conf.erb"
  mode '0644'
  notifies :restart, 'service[httpd]'
end
```

run_list に追加します。

```vim:chef-repo/roles/webserver.json
{
  "name": "webserver",
  "chef_type": "role",
  "json_class": "Chef::Role",
  "default_attributes": {
    "php": {
      "timezone": "Asia/Tokyo"
    }
  },
  "run_list": [
    "recipe[apache2]",
    "recipe[php]",
    "recipe[app]"
  ]
}
```

# 動作確認

provisioners を実行

```bash
$ rm .vagrant/machines/default/virtualbox/synced_folders
$ vagrant reload --provision
```

ローカルの hosts ファイルに下記を追加します。

```vim:/etc/hosts
192.168.33.20  local.hoge.com
```

`http://local.hoge.com/`にアクセス。

無事に「Hello!!」の文字が表示されました。

---

今回、 app の cookbook の中にアプリのデプロイ（今回は index.html の配置）も含めたのですが、これを chef で管理するべきかについては、要検討なのかなと思いました。

アプリケーションのデプロイツールも用いるのであれば、そちらで管理するべきな気もしますし。

その辺りについては、DB構築もからめつつ、今後考えていきたいと思います。