ほげほげEC2インスタンスをVagrant&Berkshelf&Chefで構築する

#ゴール
ここでは例としてシンプルにnginxが動くEC2インスタンス構築を目指す。

#Vagrant実行環境セットアップ
[INSTALLING VAGRANT](http://docs.vagrantup.com/v2/installation/index.html)

##インストール
* 環境
 * CentOS release 6.4 (Final)
 * Linux 2.6.32-358.11.1.el6.i686

```bash:
$ sudo yum groupinstall "Development Tools"
$ sudo yum install libxml2-devel libxslt-devel
$ sudo rpm -ivh http://files.vagrantup.com/packages/7e400d00a3c5a0fdf2809c8b5001a035415a607b/vagrant_1.2.2_x86_64.rpm
```

##プラグインインストール
* [vagrant-aws](https://github.com/mitchellh/vagrant-aws)
 * VagrantでAWS EC2を管理・コントロールするために導入
* [vagrant-omnibus](https://github.com/schisamo/vagrant-omnibus)
 * Chefをインストールするために導入
 * その他、[CloudInit](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AESDG-chapter-instancedata.html)や[Shell Provisioner](http://docs.vagrantup.com/v2/provisioning/shell.html)を使うという手もある
* [vagrant-berkshelf](https://github.com/riotgames/vagrant-berkshelf)
 * Vagrantで、Cookbookの管理・依存解決をしてくれるツール[Berkshelf](http://berkshelf.com/)を使うために導入

```bash:
$ vagrant plugin install vagrant-aws
$ vagrant plugin install vagrant-omnibus
$ vagrant plugin install vagrant-berkshelf
```

##Box追加
AWS EC2用にダミーのBoxを追加する

```bash:
$ vagrant box add dummy https://github.com/mitchellh/vagrant-aws/raw/master/dummy.box
```

#Cookbook準備

##Berkshelfインストール
```bash:
$ gem install berkshelf
```

##雛形生成
berksコマンドを使って雛形を生成する。

```bash:
$ gem install berkshelf
$ berks init
      create  Berksfile
      create  Thorfile
      create  .gitignore
         run  git init from "."
      create  Gemfile
      create  Vagrantfile
Successfully initialized
```

##Berksfile編集
cookbook'nginx'を追加する。

```bash:
echo "cookbook 'nginx'" >> Berksfile 
```

#Vegrantfile編集

```rb:Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|

  config.vm.hostname = "test-berkshelf"
  config.vm.box      = "dummy"

  config.ssh.username         = "ec2-user"
  config.ssh.private_key_path = ENV["SSH_PRIVATE_KEY_PATH"]
  config.ssh.max_tries        = 40
  config.ssh.timeout          = 120

  config.vm.provider :aws do |aws, override|
    aws.access_key_id     = ENV["AWS_ACCESS_KEY_ID"]
    aws.secret_access_key = ENV["AWS_SECRET_ACCESS_KEY"]
    aws.region            = "ap-northeast-1"
    aws.instance_type     = "t1.micro"
    aws.ami               = "ami-39b23d38"
    aws.keypair_name      = ENV["AWS_KEYPAIR_NAME"]
    aws.security_groups   = ["sandbox"]
    aws.tags = {
      'Name' => 'sandbox',
    }
    aws.user_data = <<-USER_DATA
#!/bin/bash
echo 'Defaults:root !requiretty\nDefaults:ec2-user !requiretty' > /etc/sudoers.d/999-vagrant-cloud-init-requiretty
chmod 440 /etc/sudoers.d/999-vagrant-cloud-init-requiretty
    USER_DATA
  end

  config.omnibus.chef_version = :latest

  config.berkshelf.berksfile_path = "./Berksfile"
  config.berkshelf.enabled        = true

  config.vm.provision :chef_solo do |chef|
    chef.run_list = [
      "recipe[nginx]"
    ]
  end
end
```

#Vagrant実行
```bash:
$ vagrant up --provider=aws
Bringing machine 'default' up with 'aws' provider...
[Berkshelf] This version of the Berkshelf plugin has not been fully tested on this version of Vagrant.
[Berkshelf] You should check for a newer version of vagrant-berkshelf.
[Berkshelf] If you encounter any errors with this version, please report them at https://github.com/RiotGames/vagrant-berkshelf/issues
[Berkshelf] You can also join the discussion in #berkshelf on Freenode.
[Berkshelf] Updating Vagrant's berkshelf: '/home/vagrant/.berkshelf/default/vagrant/berkshelf-20130623-5880-pd1dya-default'
[Berkshelf] Using nginx (1.7.0)
[Berkshelf] Using build-essential (1.4.0)
[Berkshelf] Using yum (2.3.0)
[Berkshelf] Using apt (2.0.0)
[Berkshelf] Using runit (1.1.6)
[Berkshelf] Using ohai (1.1.10)
[default] Warning! The AWS provider doesn't support any of the Vagrant
high-level network configurations (`config.vm.network`). They
will be silently ignored.
[default] Launching an instance with the following settings...
[default]  -- Type: t1.micro
[default]  -- AMI: ami-39b23d38
[default]  -- Region: ap-northeast-1
[default]  -- Keypair: vagrant
[default]  -- Security Groups: ["sandbox"]
[default] Waiting for instance to become "ready"...
[default] Waiting for SSH to become available...
[default] Machine is booted and ready for use!
[default] Rsyncing folder: /home/vagrant/vagrant/sandbox/ => /vagrant
The following SSH command responded with a non-zero exit status.
Vagrant assumes that this means the command failed!

mkdir -p '/vagrant'
```
CloudInitを使ってrequirettyの解決をしているが、CloudInit実行完了を待たないため失敗しているらしい。成功するときもある。
requiretty解決済みのAMIを事前作成してそれを使えばよさそうだが、provision再実行で解決するので保留。

```bash:
$ vagrant provision
[Berkshelf] This version of the Berkshelf plugin has not been fully tested on this version of Vagrant.
[Berkshelf] You should check for a newer version of vagrant-berkshelf.
[Berkshelf] If you encounter any errors with this version, please report them at https://github.com/RiotGames/vagrant-berkshelf/issues
[Berkshelf] You can also join the discussion in #berkshelf on Freenode.
[Berkshelf] Updating Vagrant's berkshelf: '/home/vagrant/.berkshelf/default/vagrant/berkshelf-20130623-5880-pd1dya-default'
[Berkshelf] Using nginx (1.7.0)
[Berkshelf] Using build-essential (1.4.0)
[Berkshelf] Using yum (2.3.0)
[Berkshelf] Using apt (2.0.0)
[Berkshelf] Using runit (1.1.6)
[Berkshelf] Using ohai (1.1.10)
[default] Rsyncing folder: /home/vagrant/vagrant/sandbox/ => /vagrant
[default] Rsyncing folder: /home/vagrant/.berkshelf/default/vagrant/berkshelf-20130623-5880-pd1dya-default/ => /tmp/vagrant-chef-1/chef-solo-1/cookbooks
[default] Installing Chef 11.4.4 Omnibus package...
[default] Running provisioner: chef_solo...
Generating chef JSON and uploading...
Running chef-solo...
[2013-06-23T08:10:37+00:00] INFO: *** Chef 11.4.4 ***
[2013-06-23T08:10:39+00:00] INFO: Setting the run_list to ["recipe[nginx]"] from JSON
[2013-06-23T08:10:39+00:00] INFO: Run List is [recipe[nginx]]
[2013-06-23T08:10:39+00:00] INFO: Run List expands to [nginx]
[2013-06-23T08:10:39+00:00] INFO: Starting Chef Run for ip-10-132-203-202.ap-northeast-1.compute.internal
（略）
[2013-06-23T08:11:04+00:00] INFO: service[nginx] started
[2013-06-23T08:11:04+00:00] INFO: template[nginx.conf] sending reload action to service[nginx] (delayed)
[2013-06-23T08:11:04+00:00] INFO: Processing service[nginx] action reload (nginx::default line 49)
[2013-06-23T08:11:05+00:00] INFO: service[nginx] reloaded
[2013-06-23T08:11:05+00:00] INFO: Chef Run complete in 25.103777793 seconds
[2013-06-23T08:11:05+00:00] INFO: Running report handlers
[2013-06-23T08:11:05+00:00] INFO: Report handlers complete
```

##確認
```bash:
$ vagrant ssh
$ sudo /etc/init.d/nginx status
nginx (pid  2140) を実行中...
```