Vagrant 環境で chef-solo を使って git をインストールしてみる


以下の続きだけれども、最初からやりたい症候群のため、また box の取得から

- [Vagrant の provisioning を使って、ruby をコードからインストールしてみる - Qiita](http://qiita.com/kasei-san/items/f06b689a02672f153632)

## vagrant 初回処理

```
$ vagrant init
```

```txt:Vagrantfile
config.vm.box = "chef/centos-6.5"
```

特にURLを指定しなくても、vagrant 側で、[Vagrant Cloud](https://vagrantcloud.com/) から探して、vagrant box add してくれるっぽい

```
$ vagrant up
```

## vagrant-vbox-snapshot を使う

vagrant のスナップショットをとってくれる
cook に失敗しても、vagrant destory して作りなおしたりしなくて良いので、便利

```
$ vagrant plugin install vagrant-vbox-snapshot
```

### スナップショット作成

```
$ vagrant snapshot take init ← "init" がスナップショット名 
Taking snapshot init
```

### スナップショット一覧

```
$ vagrant snapshot list
Listing snapshots for 'default':
   Name: init (UUID: ef144906-56a9-4c83-a09e-61f5b6f90e26) *
```

それ以外のコマンドについては後述


## bundler

```
$ bundle init
```

```rb:Gemfile
source "https://rubygems.org"

gem 'rake'
gem 'knife-solo'
gem 'serverspec'
```

```
$ bundle install --path vendor/gems
```

## knife solo をサーバにインストール


### サーバにホスト名でログインできるようにする

vagrant ssh-config で、vagrant サーバにログインするための ssh-config を教えてもらえる

```
$ vagrant ssh-config
Host default
  HostName 127.0.0.1
  User vagrant
  Port 2201
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile /Users/kasei_san/.vagrant.d/insecure_private_key
  IdentitiesOnly yes
  LogLevel FATAL

$ vagrant ssh-config >> ~/.ssh/config
```

Host 名は複数環境がある場合、変えたほうが良い

### knife solo のインストール

```
$ bundle exec knife solo prepare default
```

### スナップショットを作成

```
$ vagrant snapshot take add_kinfe_solo

$ vagrant snapshot list
Listing snapshots for 'default':
   Name: init (UUID: ef144906-56a9-4c83-a09e-61f5b6f90e26)
      Name: add_kinfe_solo (UUID: b86f606c-9ed8-4161-9e0a-9190d71dc0e6) *
```

## serverspec 初期化

```
bundle exec serverspec-init
echo "--color" >> .rspec
```

### テスト実行

```
bundle exec rake spec
```

サンプルテストがこけることを確認

* 参考 → [Vagrant 環境で serverspec のサンプルテストが実行されるまでの流れをメモ - Qiita](http://qiita.com/kasei-san/items/429b40679c63b14d8caf)


## git をサーバにインストール

### serverspec 実装

```spec/default/git_spec.rb
require 'spec_helper'

describe package('git') do
  it { should be_installed }
end
```

サンプルのテストは削除

### テスト実行

```
$ bundle exec rake spec

/Users/kasei_san/.rbenv/versions/2.1.0/bin/ruby -S rspec spec/default/git_spec.rb
F

Failures:

  1) Package "git" should be installed
     Failure/Error: it { should be_installed }
       sudo rpm -q git
       パッケージ git はインストールされていません。

       expected Package "git" to be installed
     # ./spec/default/git_spec.rb:4:in `block (2 levels) in <top (required)>'

Finished in 4.9 seconds
1 example, 1 failure

Failed examples:

rspec ./spec/default/git_spec.rb:4 # Package "git" should be installed
/Users/kasei_san/.rbenv/versions/2.1.0/bin/ruby -S rspec spec/default/git_spec.rb failed
```

こける


### cookbook 生成

knife cookbook create 〜 で、cookbook が生成される

```
$ mkdir cookbooks
$ bundle exec knife cookbook create git -o cookbooks
```

cookbooks ディレクトリに、git の cookbook が生成される

```
$ tree cookbooks/
cookbooks/
└── git
    ├── CHANGELOG.md
    ├── README.md
    ├── attributes
    ├── definitions
    ├── files
    │   └── default
    ├── libraries
    ├── metadata.rb
    ├── providers
    ├── recipes
    │   └── default.rb
    ├── resources
    └── templates
        └── default
```

### recipe を書く

package 〜 install で、プラットフォームに合わせて、パッケージをインストールしてくれる

- yum とか apt とか

```cookbooks/git/recipes/default.rb
#
# Cookbook Name:: git
# Recipe:: default
#
# Copyright 2014, YOUR_COMPANY_NAME
#
# All rights reserved - Do Not Redistribute
#

package 'git' do
  action :install
end
```

nodes/default.json サーバ default で実行される レシピ を書く

```nodes/default.json
{
  "run_list":[
    "recipe[git]"
  ]
}
```

### cook 実行

```
$ bundle exec knife solo cook default

...

Starting Chef Client, version 11.12.2
Compiling Cookbooks...
Converging 1 resources
Recipe: git::default
  * package[git] action install
    - install version 1.7.1-3.el6_4.1 of package git

...
```

無事インストールされた

### テスト再実行

```
$ bundle exec rake spec
/Users/kasei_san/.rbenv/versions/2.1.0/bin/ruby -S rspec spec/default/git_spec.rb
.

Finished in 5.22 seconds
1 example, 0 failures

```

### スナップショット作成

```
$ vagrant snapshot take add_git
$ vagrant snapshot list
vagrant snapshot list
Listing snapshots for 'default':
   Name: init (UUID: ef144906-56a9-4c83-a09e-61f5b6f90e26)
      Name: add_kinfe_solo (UUID: b86f606c-9ed8-4161-9e0a-9190d71dc0e6)
         Name: add_git (UUID: bba37259-54bc-4a0f-b6b4-81aa0283eda1) *
```

無事、gitがインストールされたことを確認できた


## (おまけ)スナップショットの移動

### vagrant snapshot go

add_kinfe_solo に移動したい場合

```
$ vagrant snapshot list
Listing snapshots for 'default':
   Name: init (UUID: ef144906-56a9-4c83-a09e-61f5b6f90e26)
      Name: add_kinfe_solo (UUID: b86f606c-9ed8-4161-9e0a-9190d71dc0e6)
         Name: add_git (UUID: bba37259-54bc-4a0f-b6b4-81aa0283eda1) *


$ vagrant snapshot go add_kinfe_solo

$ vagrant snapshot list
Listing snapshots for 'default':
   Name: init (UUID: ef144906-56a9-4c83-a09e-61f5b6f90e26)
      Name: add_kinfe_solo (UUID: b86f606c-9ed8-4161-9e0a-9190d71dc0e6) *
         Name: add_git (UUID: bba37259-54bc-4a0f-b6b4-81aa0283eda1)
```

### vagrant snapshot back

最新のスナップショットに戻す
なにかやらかした場合に使う

## 用語

本家用語集

- [Glossary - Chef - Chef Open Source Wiki](https://wiki.opscode.com/display/chef/Glossary)

### node 
Chef で管理されるサーバ

### Recipe
Chef によって環境設定するための、カプセル化されたリソース。Ruby の DSL で書かれた設定ファイル

### Cookbook
サーバに設定をするためのコードのパッケージ
Cookbook の中に1〜複数の Recipe がある

## 参考

- [All about Chef ... — Chef Docs](http://docs.opscode.com/)
- [Amazon.co.jp： 入門Chef Solo - Infrastructure as Code eBook: 伊藤直也: Kindleストア](http://www.amazon.co.jp/dp/B00BSPH158)
- [knife-soloによるChefの実行 - Qiita](http://qiita.com/kidachi_/items/b222fb2892e6108c46d5)