AWS EC2上のRHEL5.5で、Chef Solo環境を構築する（for Mac）


以前書いた「[Vagrantで AWS EC2インスタンス（RHEL5.5）を作成する](http://qiita.com/Humangas/items/2997cc6701aa90687c04)」の手順の後に、そのEC2インスタンス（RHEL5.5）をノード（料理されるサーバ）として、Chef Solo環境を作るための手順です。


# ゴール
Mac（Chefで言うWORKSTATION）→ AWS EC2（RHEL5.5）（Chefで言うNODES）のChef Solo環境を構築します。

この順番でやれば、AWS EC2インスタンス（RHEL5.5）に、Chef Solo環境をMacで構築出来ます。
最後に、簡単なレシピを流すところまで本記事でやります。

1. [MacでRuby開発環境設定：デフォの1.8.7→1.9.3にする＆rbenvも](http://qiita.com/Humangas/items/2ea1d55e41f934a40d8f)
1. [Vagrantで AWS EC2インスタンス（RHEL5.5）を作成する](http://qiita.com/Humangas/items/2997cc6701aa90687c04)
1. 本記事


ついでですが、その後に、コレもやればEC2インスタンスのスナップショットも自動で取れるようになります。
1. [AWS EC2上に作成したRHELのスナップショットをRubyで取得するまでの手順](http://qiita.com/Humangas/items/af10dc0b6c1fcabea3db)


***
# 今回の環境
## 作業前
* OS: Mac OSX 10.8.4
* Ruby: 1.9.3p448

## 作業後（※差異部のみ記載）
* chef: 11.6.0
* knife-solo: 0.3.0


***
# 前提条件
一応、タイトルにはAWSとか書いてますが、この記事の本質としてはChef Solo環境構築なのであんま関係ないです。読み替えもあまりないでしょう。
ただ、他にもそういうノリも含めて、この記事に依存したソフトウェア部分が登場するので、一応書いておきます。

* Rubyをインストール済みであること。
* rbenvで、Rubyインストールしている。
  * → rbenv を使ってないなら、rbenvのところを無視すればイケると思います。
* 操作対象のEC2インスタンス（RHEL5.5）をVagrantで作成してます。
  * → `vagrant ssh`でログインしてるとこを読み替えればイケるはずです。
* 作業対象ノード：RHEL5.5
  * → 一部、RHEL特有の問題（サーバ証明書古い）がありますが、それ以外はLinuxだとだいたいイケると思います。


***
# 構築手順：概要
1. Chef インストール
1. knife-solo インストール
1. knife 設定
1. kitchen（＝リポジトリ）作成 
1. cookbook を作成する
1. NODES（料理されるサーバ）に、Chef をインストールする
1. [host-name].json ファイルに、実行したいcookbookを指定
1. レシピを作成
1. サーバを料理する（knife solo cook）


# 構築手順：詳細
## Chef インストール
`gem install chef`で、Chef をインストールする。

```
$ gem install chef --no-ri --no-rdoc
$ gem list --local chef

*** LOCAL GEMS ***

chef (11.6.0)
```

* ※ "--no-ri --no-rdoc" を付けてドキュメントをインストールしないようにする。
* → ドキュメントインストールすると、インストール自体に時間がかかるので。
* 【参考情報】：[RubyGemsでgemのインストール時に--no-ri --no-rdocをデフォルトにする](http://blog.ruedap.com/2011/05/14/ruby-gem-install-no-ri-no-rdoc-gemrc)


## knife-solo インストール
`gem install knife-solo`で、knife-solo をインストールする。

knife-soloは、knifeのプラグインです。
→ 導入することで、以下のknife のサブコマンドが使えるようになる。

* `knife solo init DIRECTORY`
  * 新規キッチン（リポジトリ）を作成する → これが無いと始まらない
* `knife solo prepare [USER@]HOSTNAME [JSON] (options)`
  * 料理対象ノードに、Chef をインストールする
* `knife solo cook [USER@]HOSTNAME [JSON] (options)`
  * キッチンを料理対象ノードにアップロードし、料理（chef-soloを実行）する
* `knife solo bootstrap [USER@]HOSTNAME [JSON] (options)`
  * prepare + cook を一度に行う
* `knife solo clean [USER@]HOSTNAME`
  * 料理対象ノードから、キッチンを削除する

```
$ gem install knife-solo --no-ri --no-rdoc
$ gem list --local knife-solo

*** LOCAL GEMS ***

knife-solo (0.3.0)
```


## chef コマンド群を反映させる
`rbenv rehash`で、インストールしたコマンドを使えるようにする。

rbenv でgem インストールした場合は、インストール後、`rbenv rehash`コマンドを発行し、コマンドファイルが格納してある`$HOME/.rvm/shims` 配下を更新する必要がある。

```
$ rbenv rehash
$ ls -la $HOME/.rbenv/shims | egrep "chef|knife"
-rwxr-xr-x  10 user-name  staff  415  8 15 02:44 chef-apply
-rwxr-xr-x  10 user-name  staff  415  8 15 02:44 chef-client
-rwxr-xr-x  10 user-name  staff  415  8 15 02:44 chef-service-manager
-rwxr-xr-x  10 user-name  staff  415  8 15 02:44 chef-shell
-rwxr-xr-x  10 user-name  staff  415  8 15 02:44 chef-solo
-rwxr-xr-x  10 user-name  staff  415  8 15 02:44 knife
```


## knife 設定
`knife configure`で、ナイフを使えるようにする。  
色々聞かれるが、全てデフォルトでOK（後で手動で修正）

```
$ knife configure
```

上記コマンド実行後、ナイフ設定が`~/chef-repo/.chef/knife.rb`に出力される。  

* ※ knife-solo 0.2.0 までは、solo.rb ファイルだったが、knife-solo 0.3.0 からは、.chef/knife.rb になっている。

このままでも動作するが、`cook`した時にWARNING が表示されるため、明示的に以下のフルパスを設定する。

* cookbook_path
* role_path
* data_bag_path

```
$ vi $HOME/chef-repo/.chef/knife.rb

log_level                :info
log_location             STDOUT
node_name                'user-name'
client_key               'Users/user-name/chef-repo/.chef/user-name.pem'
validation_client_name   'chef-validator'
validation_key           '/etc/chef-server/chef-validator.pem'
chef_server_url          'https://computer-name.local:443'
syntax_check_cache_path  '/Users/user-name/chef-repo/.chef/syntax_check_cache'
cookbook_path [ '/Users/user-name/chef-repo/site-cookbooks', '/Users/user-name/chef-repo/cookbooks' ]
data_bag_path            '/Users/user-name/workspace/chef-repo/data_bags'
role_path                '/Users/user-name/workspace/chef-repo/roles'
```


## kitchen（＝リポジトリ）作成
`knife solo init [chef-repo-name]`で、キッチンを作成する。

キッチン > クックブック > レシピ という内包関係になる。
その大元のリポジトリを`knife`コマンドで作成する。  

まず、リポジトリを作成したいディレクトリまで移動してから、リポジトリ作成コマンドを発行する。

```
$ cd $HOME
$ knife solo init chef-repo
$ tree chef-repo
chef-repo
├── cookbooks
├── data_bags
├── nodes
├── roles
└── site-cookbooks
```

※ tree コマンドは標準でMac に入っていない。
→ Homebrew が既に入っているなら、`$ brew install tree` でインストール出来る。


## cookbook を作成する
`knife cookbook`で、クックブックのひな形を作成する。

```
$ cd $HOME/chef-repo
$ knife cookbook create test-cookbook-o site-cookbooks/
$ tree site-cookbooks/
site-cookbooks/
└── test-cookbook
    ├── CHANGELOG.md
    ├── README.md
    ├── attributes
    ├── definitions
    ├── files
    │   └── default
    ├── libraries
    ├── metadata.rb
    ├── providers
    ├── recipes
    │   └── default.rb
    ├── resources
    └── templates
        └── default
```

## NODES（料理されるサーバ）に、Chef をインストールする
`knife solo prepare`で、料理対象ノードにChef をインストールする。  
インストール作業であるため、一度だけ実行すればそれでOK。

```
$ knife solo prepare root@ec2-xxx-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com -i ~/aws-key.pam 
```

### ※ SSLサーバ証明書エラー対応
※ ここで、SSLサーバ証明書エラーが出たら、以下の記事で解決できます。
Amazon Linuxだとエラー無かったですが、この手順のままRHEL5.5でやるとエラーは絶対でます。
→ [RHEL5.5サーバに対して、Chef Solo環境を作る時のSSLサーバ証明書エラーを回避するための対処法]
(http://qiita.com/Humangas/items/5d476955ce6cccadd83c)


## [host-name].json ファイルに、実行したいcookbookを指定
インストール完了後、nodes ディレクトリに[host-name].json ファイルが作成される。
そのJSONファイルの`run_list`に、実行したいクックブックを指定する（複数指定可能）。  

```
$ vi $HOME/chef-repo/nodes/[host-name].json
```

``` json
 {
    "run_list":[
      "test-cookbook"
    ]
 }
```

## レシピを作成
レシピを作成する（例：Hello Chef! というログを出力する）。

```
$ vi $HOME/chef-repo/site-cookbooks/test-cookbook/recipes/default.rb
```

``` ruby
log "Hello Chef!"
```


## サーバを料理する（knife solo cook）
作成したレシピを料理対象サーバに送りつけて料理する。  
実行後、ログに`* log[Hello Chef!] action write`と表示されており、レシピ通り動作していることが分かる。

```
$ knife solo cook ec2-user@ec2-xxx-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com -i ~/aws-key/aws-key.pem 

unning Chef on ec2-xxx-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com...
Checking Chef version...
Uploading the kitchen...
Generating solo config...
Running Chef...
Starting Chef Client, version 11.6.0
Compiling Cookbooks...
Converging 1 resources
Recipe: test-cookbook::default
  * log[Hello Chef!] action write

Chef Client finished, 1 resources updated
```

ここまでで一応終わりですが、以下のTipsも知っておくと便利です。


***
# 【Tips】コマンド打つ時、長いホスト名と秘密鍵指定が面倒なので簡略化定義する
`knife solo`コマンドなどを発行する際、ホスト名や秘密鍵（-iで指定）をいちいち指定するのは面倒なので、ssh 設定を行う。  
※ ~/.ssh/config が存在しなければ作成する。

```
$ vi ~/.ssh/config

Host amazon-linux
  HostName      ec2-xxx-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com
  IdentityFile  ~/aws-key.pem
  User          ec2-user
```

この設定後は、`knife solo cook amazon-linux`とコマンド発行すれば、前述同様のレシピをサーバに対して適用できる。