Chef-Zero/Solo と SoftLayer CUI の実行環境の作成

#[SoftLayerクッキングLABO] (http://qiita.com/MahoTakara/items/464da29ccf932698b753)

Chefは Ruby で書かれていて、slcli コマンドは Python で書かれています。 これらプログラム言語に関わる問題回避のために、Ruby や Python のバージョンを変えたい場合があります。しかし、これらのプログラム言語のバージョンは、Linux ディストリビューション によって決まっているため簡単ではありません。インターネットからソースコードを入手して、コンパイルして /usr/local/ 以下にインストールするのは、とても手間がかかります。

この対策として、Python や Ruby の複数のバージョンをインストールしておき、サーバー全体ではなく、ログインユーザーの範囲限定で、ruby や python のバージョンを変更して利用する便利なツールを利用します。ここでは、pyenv 環境下のPython と rbenv環境下のRuby で、slcli コマンド、Chefを利用する方法について書きます。



# Chef のレシピを開発する仮想サーバーの準備

この仮想サーバーは、自分のパソコンのVirtualBoxでも良いですし、SoftLayerの仮想サーバーのどちらでも良いです。
自分のパソコンのなかに、vagrant と VirtualBox の環境を構築していれば、SoftLayerの仮想サーバーを新たに立てるより安価で良いかもしれません。　ここでは、SoftLayerにレシピ開発用の仮想サーバーを立てることを前提に進めていきます。 

Chef-Solo/ Chef-Zero を利用する最小環境として、以下のサーバーを準備します。

>CPU: 1コア
RAM: 2ギガバイト
OS: Ubuntu 14.04 64bit
ディスク: 25GB

RAMが 1ギガバイトの場合、Chef のインストールの際に、メモリが不足して途中でインストールが止まった様になるので、導入時だけ 2ギガバイトにしておく必要があります。 導入が終わったら 1ギガに減らしても、動作する様です。

既に slcli コマンドの実行環境を作っていれば、以下のシェルを実行するだけなので、便利です。

```
#!/bin/bash
slcli vs create \
--hostname ChefWs --domain softlayer.com \
--datacenter tok02 \
--cpu 1 --memory 2 \
--os UBUNTU_LATEST_64 \
--billing hourly \
--public \
--postinstall https://raw.githubusercontent.com/takara9/ProvisioningScript/master/ubuntu_basic_config \
--key 355919 \
--network 100
```

ここで、postinstall は、初回起動時に一回だけ実行されるスクリプトで、GitHubから取得して実行する様にしています。https://github.com/takara9/ProvisioningScript に設定内容を公開していますので、参考にして専用のプロビジョニング・スクリプトの開発をお勧めします。

それから key は、ssh のログイン用鍵のID番号です。 以下のコマンドで、カスタマーポータルのラベル名とID番号の対比を得る事ができます。

```
$ slcli sshkey list
```

このプロビジョニング・スクリプトは、インターネットからのアクセスを OS ファイアウォールによってブロックする様になっているので、カスタマー・ポータルから 「Support」 -> 「SSL VPN Login」に進んで VPN接続を行なってから、プラベート・アドレスに対して sshでログインが出来る様になります。 


# 作業用ユーザーの作成

SoftLayerでは、初期状態ではrootユーザーしかないので、作業用のユーザーをつくります。ここでは、Chefを利用してサーバーの設定を自動化するテーマで進めたいので、chefというユーザーを作ります。 

```
root@ChefWs:~# adduser chef
ユーザー `chef' を追加しています...
新しいグループ `chef' (1000) を追加しています...
新しいユーザー `chef' (1000) をグループ `chef' に追加しています...
ホームディレクトリ `/home/chef' を作成しています...
`/etc/skel' からファイルをコピーしています...
新しい UNIX パスワードを入力してください: 
新しい UNIX パスワードを再入力してください: 
passwd: password updated successfully
Changing the user information for chef
Enter the new value, or press ENTER for the default
	Full Name []: chef
	Room Number []: 
	Work Phone []: 
	Home Phone []: 
	Other []: 
以上で正しいですか? [Y/n] Y
```
rootのログイン鍵をコピーして、chefユーザーも同じ鍵でログインできる様にしておきます。

```
root@ChefWs:~# cp -r .ssh /home/chef/
root@ChefWs:~# chown -R chef:chef /home/chef/.ssh/
```
それから、/etc/sudoers に chef を追加しておきます。

```lang:/etc/sudoers
chef    ALL=(ALL) NOPASSWD: ALL
```


# SoftLayer CUI 環境作成

SoftLayer の コマンドライン・ユーザー・インタフェースは slcli は、Python のバージョンによってワーニングが出るので、pyenv を利用して、Linuxディストリビューションの Python のバージョンに関係無く、必要なバージョンを選択できる様にします。それから、コマンドの実行例は、Ubuntu 14.04 を利用して進めていきます。

## pyenv の導入と設定

詳しい導入方法と設定の解説は、https://github.com/yyuu/pyenv にありますので、参考に導入していきます。　注意点としては、rootではなくchefユーザーでインストールを実行します。 

```
$ git clone https://github.com/yyuu/pyenv.git ~/.pyenv
$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
$ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(pyenv init -)"' >> ~/.bash_profile
```

ログアウトして再ログインして、以下のコマンドで確認すると、Linux Distribution のPython しか入っていないことが判ります。

```
chef@ChefWs:~$ pyenv versions
* system (set by /home/chef/.pyenv/version)
```
Python を導入する前に、gcc と zlib がビルドに必要なので、ここは root でインストールします。

```
root@ChefWs:~$ sudo apt-get install git gcc make openssl libssl-dev libbz2-dev libreadline-dev libsqlite3-dev
```
次は Python の slcli コマンドで ワーニングで出ないバージョンをインストールします。

```
chef@ChefWs:~$ pyenv install 2.7.10
```
確認として以下のコマンドの結果から、導入されているものの、選択されていない事が判ります。

```
chef@ChefWs:~$ pyenv versions
* system (set by /home/chef/.pyenv/version)
  2.7.10
```
今回導入したバージョンを選択して、再確認します。　

```
chef@ChefWs:~$ pyenv global 2.7.10
chef@ChefWs:~$ pyenv versions
  system
* 2.7.10 (set by /home/chef/.pyenv/version)
```
もう一回、念押しの確認

```
chef@ChefWs:~$ python --version
Python 2.7.10
```
これで Python の作成が完了しました。


## pipを利用して slcli をインストール
以下のコマンドで、slcliコマンドの導入が完了です。

```
chef@ChefWs:~$ pip install softlayer
Collecting softlayer
  Downloading SoftLayer-4.1.1-py2.py3-none-any.whl (248kB)
    100% |████████████████████████████████| 249kB 1.3MB/s 
Collecting prompt-toolkit (from softlayer)
  Downloading prompt_toolkit-0.52-py2-none-any.whl (188kB)
    100% |████████████████████████████████| 188kB 1.7MB/s 
Collecting click>=5 (from softlayer)
  Downloading click-5.1-py2.py3-none-any.whl (65kB)
    100% |████████████████████████████████| 65kB 3.9MB/s 
Collecting six>=1.7.0 (from softlayer)
  Downloading six-1.9.0-py2.py3-none-any.whl
Collecting prettytable>=0.7.0 (from softlayer)
  Downloading prettytable-0.7.2.tar.bz2
Collecting requests>=2.7.0 (from softlayer)
  Downloading requests-2.7.0-py2.py3-none-any.whl (470kB)
    100% |████████████████████████████████| 471kB 756kB/s 
Collecting pygments (from prompt-toolkit->softlayer)
  Downloading Pygments-2.0.2-py2-none-any.whl (672kB)
    100% |████████████████████████████████| 675kB 554kB/s 
Collecting wcwidth (from prompt-toolkit->softlayer)
  Downloading wcwidth-0.1.5-py2.py3-none-any.whl
Installing collected packages: six, pygments, wcwidth, prompt-toolkit, click, prettytable, requests, softlayer
  Running setup.py install for prettytable
Successfully installed click-5.1 prettytable-0.7.2 prompt-toolkit-0.52 pygments-2.0.2 requests-2.7.0 six-1.9.0 softlayer-4.1.1 wcwidth-0.1.5
```


## ユーザーIDとAPIキーの取得とセット

以下のコマンドで、ユーザー名とAPIキーをセットします。 このユーザー名とAPIキーは、「Account」->「Users」で目的のユーザーIDの場所で、「API Key」 列の View をクリックすると表示されるので、コピペしてインプットします。

```
chef@ChefWs:~$ slcli config setup
Username []: *********
API Key or Password []: 
Endpoint (public|private|custom) [public]: 
Timeout [0]: 
:..............:..................................................................:
:         Name : Value                                                            :
:..............:..................................................................:
:     Username : *********                                                        :
:      API Key : **************************************************************** :
: Endpoint URL : https://api.softlayer.com/xmlrpc/v3.1/                           :
:      Timeout : not set                                                          :
:..............:..................................................................:
Are you sure you want to write settings to "/home/chef/.softlayer"? [Y/n]: Y
Configuration Updated Successfully
```

動作確認のために、次のコマンドを実行して、エラーが出なければ完了です。

```
chef@ChefWs:~$ slcli summary
```

# Ruby の バージョン管理環境のインストール

rbenv と rvm とあるのですが、馴染みのある好きな方で良いと思います。　ここでは、pyenv を入れたので、rbenv を導入したいと思います。少し導入方法が面倒なところが難点ですが、インストールの手順は、このURL https://github.com/sstephenson/rbenv に従います。

```
chef@ChefWs:~$ git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
Cloning into '/home/chef/.rbenv'...
remote: Counting objects: 2079, done.
remote: Total 2079 (delta 0), reused 0 (delta 0), pack-reused 2079
Receiving objects: 100% (2079/2079), 353.65 KiB | 237.00 KiB/s, done.
Resolving deltas: 100% (1267/1267), done.
Checking connectivity... done.
```
以下のコマンドを実行してシェルの設定を追加します。

```
chef@ChefWs:~$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
chef@ChefWs:~$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
```

ログアウトして再ログインして、環境が正しく設定されたか確認します。 type rbenv で以下の表示が出れば環境整備完了です。

```
chef@ChefWs:~$ ログアウト
Connection to 10.132.253.38 closed.
imac:~ maho$ ssh chef@10.132.253.38 -i key/takara3
Welcome to Ubuntu 14.04.2 LTS (GNU/Linux 3.13.0-55-generic x86_64)

 * Documentation:  https://help.ubuntu.com/
Last login: Wed Sep 30 17:37:00 2015 from 10.2.224.229
chef@ChefWs:~$ type rbenv
rbenv は関数です
rbenv () 
{ 
    local command;
    command="$1";
    if [ "$#" -gt 0 ]; then
        shift;
    fi;
    case "$command" in 
        rehash | shell)
            eval "`rbenv "sh-$command" "$@"`"
        ;;
        *)
            command rbenv "$command" "$@"
        ;;
    esac
}
```
GitHUBから ruby-build を取得します。

```
chef@ChefWs:~$ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
-- 途中省略 --
Checking connectivity... done.
```
Rubyをビルドするためのパッケージが入っている必要があるので、以下を実行します。

```
chef@ChefWs:~$ sudo apt-get install -y libssl-dev libreadline-dev zlib1g-dev
```
以下のコマンドでダウロードとビルドが実行されます。　1コアで2ギガメモリだと、少し時間がかかります。

```
chef@ChefWs:~$ rbenv install 2.2.3
-- 途中省略 --
Installed ruby-2.2.3 to /home/chef/.rbenv/versions/2.2.3
```
確認にとして、以下を実行します。　この状態では選択されていません。

```
chef@ChefWs:~$ rbenv versions
  2.2.3
```
Ruby 2.2.3 を選択して、使える様にするには、以下のコマンドを実行します。

```
chef@ChefWs:~$ rbenv global 2.2.3
chef@ChefWs:~$ ruby -v
ruby 2.2.3p173 (2015-08-18 revision 51636) [x86_64-linux]
```

# Chef Solo / Zero のインストール

Soloは無くなるんじゃないのと思っておられる方は、次のリンクが参考になります。( http://www.sawanoboly.net/blog/2014/11/25/chef-solo-zero-knife-solo-zero ) 超要約すると、「無くならない」という事です。

Chefをビルドするために、以下のモジュールを追加します。

```
chef@ChefWs:~/chef-repo$ sudo apt-get install g++ autoconf
```
Chefのリポジトリを作成します。

```
chef@ChefWs:~$ pwd
/home/chef
chef@ChefWs:~$ mkdir chef-repo
chef@ChefWs:~$ cd chef-repo/
```
Gemfile を利用するための bunlderをインストールします。

```
chef@ChefWs:~/chef-repo$ gem install bundler
-- 途中省略 --
1 gem installed
```
以下のコマンドで、リポジトリのフォルダーに  Gemfile のひな形を作成します。

```
chef@ChefWs:~/chef-repo$ bundle init
Writing new Gemfile to /home/chef/chef-repo/Gemfile
```
エディタで編集して、インストールするモジュールを追加します。

```lang:/home/chef/chef-repo/Gemfile
# A sample Gemfile
source "https://rubygems.org"

gem 'chef'
gem 'knife-zero'
gem 'knife-solo'
gem 'berkshelf'
gem 'knife-softlayer'
```

Chefの必要なモジュール一式を導入します。

```
chef@ChefWs:~/chef-repo$ bundle install
Fetching gem metadata from https://rubygems.org/.........
Fetching version metadata from https://rubygems.org/...
Fetching dependency metadata from https://rubygems.org/..
Resolving dependencies.................
Using rake 10.4.2
-- 途中省略 --
Using bundler 1.10.6
Bundle complete! 5 Gemfile dependencies, 96 gems now installed.
Use `bundle show [gemname]` to see where a bundled gem is installed.
Post-install message from knife-solo:
Thanks for installing knife-solo!

If you run into any issues please let us know at:
  https://github.com/matschaffer/knife-solo/issues

If you are upgrading knife-solo please uninstall any old versions by
running `gem clean knife-solo` to avoid any errors.

See http://bit.ly/CHEF-3255 for more information on the knife bug
that causes this.
```
現在のリポジトリの中は、次の様な状態となっています。

```
chef@ChefWs:~/chef-repo$ pwd
/home/chef/chef-repo
chef@ChefWs:~/chef-repo$ ls -la
合計 20
drwxrwxr-x 2 chef chef 4096  9月 30 18:48 .
drwxr-xr-x 8 chef chef 4096  9月 30 18:22 ..
-rw-r--r-- 1 chef chef  133  9月 30 18:22 Gemfile
-rw-rw-r-- 1 chef chef 6402  9月 30 18:48 Gemfile.lock
```

# まとめ
SoftLayerでサーバー構築を自動化するための、Chef の レシピ開発環境を作りました。 pyenv と rbenv を利用する事で Linux ディストリビューションの Python や　Ruby のバージョンに縛りから自由になります。 次回以降で具体的なレシピの開発に進んでいきます。