はじめに
下記の記事で Ruby を取り巻く基本的な言葉について整理した。
本稿はそれに続き、メインとなる Itamae と Serverspec を使用した自動構成管理の導入に関する環境構築の手順について記載する。
前提条件
本稿の作成にあたり、下記の作業環境および構築環境を前提とする。
作業環境
本記事の作成にあたり使用した作業環境は下記の通り。
項目 | 内容 | バージョン |
---|---|---|
OS | macOS | Sierra 10.12.3 |
VM | VirtualBox | 5.1.14 r112924 |
その他 | Vagrant | 1.8.7 |
構築環境
本記事が構築対象とするシステムの主要なソフトの構成は下記の通り。
項目 | 内容 | バージョン | ホスト A | ホスト B |
---|---|---|---|---|
OS | bento/centos-6.8 | - | ○ | ○ |
S/W | rbenv | 1.1.0-2-g4f8925a | ○ | - |
S/W | ruby-build | - | ○ | - |
S/W | Bundler | version 1.14.6 | ○ | - |
S/W | Itamae | v1.9.10 | ○ | - |
S/W | Serverspec | 2.38.0 | ○ | - |
Vagrant の Box の構成は下記の通り。
# config.vm.box = "bento/centos-6.8"
config.vm.define "host" do |node|
node.vm.box = "bento/centos-6.8"
node.vm.hostname = "host"
node.vm.network :private_network, ip: "192.168.33.10"
end
config.vm.define "web" do |node|
node.vm.box = "bento/centos-6.8"
node.vm.hostname = "web"
node.vm.network :private_network, ip: "192.168.33.11"
end
構築手順
1. Rubyの導入
rbenvを使用したRubyのインストール手順の概要は下記の通り。
- Rubyのビルド環境(gccなど)をインストール
- rbenv + rbenv-build をインストール
- .bash_profile にPATHを通して設定を適用
- Ruby のバージョン一覧の確認とインストール
- rbenv global で環境全体に設定を適用
本手順に関する詳細なコマンドについては下記が詳しい。
2. Bundler
インストール
// Bundleをインストール
$ gem install bundler
// bundler のバージョンを確認
$ bundler -v
Bundler version 1.14.6
使用方法
bundler の基本的な使用方法は下記の通り。
- Gemfile を作成する
- 使用したい gem を Gemfile に記述する
- Gemfile にリスト化したgemを一括インストール
- インストールしたgemをプログラムソース上でロード
- bundle exec を最初につけてコマンドを実行する
コマンド例を下記に記す。
// 1. Gemfile を作成する
$ bundle init
// 2. Gemfile に使用したいgemを記述する
$ vim Gemfile
// 3. Gemfile にリスト化したgemを一括インストール
$ bundle install --path vendor/bundle
// 4. bundle exec を最初につけてコマンドを実行する(下記は一例)
$ bundle exec ruby foo.rb
3. Itamae と Serverspec
ディレクトリ構成
それぞれにベストプラクティスとなるディレクトリ構成がある。
Itamae
.
├── cookbooks
│ └── nginx
│ ├── default.rb
│ ├── files
│ │ └── etc
│ │ └── nginx
│ │ └── conf.d
│ │ └── static.conf
│ └── templates
│ └── etc
│ └── nginx
│ └── conf.d
│ └── dynamic.conf
└── roles
└── web.rb
Best Practice · itamae-kitchen/itamae Wiki · GitHub
Serverspec
.
├── Rakefile
├── spec
│ ├── ap
│ │ ├── mysqlclient_spec.rb
│ │ ├── nodejs_spec.rb
│ │ ├── rvm_spec.rb
│ │ └── sqlite_spec.rb
│ ├── base
│ │ ├── build-essential_spec.rb
│ │ └── git_spec.rb
│ ├── db
│ │ └── mysql_spec.rb
│ └── spec_helper.rb
[ ap / base/ db ] はホスト名。
[Serverspec]Serverspecのテストケースをロール単位で管理する - 城陽人の本棚
インストール
前述の情報を参考に、実際に Itamae と Serverspec をインストールする。
// 任意のプロジェクトフォルダを作成する
$ mkdir ~/sample && cd $_
// --------------------------
// Itamae のインストール
// --------------------------
$ mkdir ~/sample/itamae && cd $_
// Gemfileを作成する
$ bundle init
// Gemfileを編集する。(ヒアドキュメントを使用)
$ cat << EOS > Gemfile
source "https://rubygems.org"
gem 'itamae'
gem 'thor', "0.19.1"
gem 'rake'
EOS
// Gemfile にリスト化したgemを一括インストール
$ bundle install --path vendor/bundle
// --------------------------
// Serverspec のインストール
// --------------------------
$ mkdir ~/sample/serverspec && cd $_
// Gemfileを作成する
$ bundle init
// Gemfileを編集する (ヒアドキュメントを使用)
$ cat << EOS > Gemfile
source "https://rubygems.org"
gem 'serverspec'
gem 'rake'
EOS
// Gemfile にリスト化したgemを一括インストール
$ bundle install --path vendor/bundle
Itamaeのインストール確認とディレクトリ準備
Itamaeが正常にインストール出来たかどうか確認し、ベストプラクティスに沿ったディレクトリを用意する。
// Itamaeのインストール確認
$ cd ~/sample/itamae
$ bundle exec itamae help
$ mkdir cookbooks
$ mkdir roles
Serverspecの初期化
serverspec-init コマンドで構築対象のシステムに関する情報を入力し、初期化操作を行う。
ここではリモートLinuxへsshで接続する設定を行う。
(Exec(Local)については文献が少なく使用方法を把握しきれていない。。)
// Serverspecの初期化
$ cd ~/sample/serverspec
$ bundle exec serverspec-init
Select OS type:
1) UN*X
2) Windows
Select number: 1
Select a backend type:
1) SSH
2) Exec (local)
Select number: 1
Vagrant instance y/n: n
Input target host name: web
+ spec/
+ spec/web/
+ spec/web/sample_spec.rb
+ spec/spec_helper.rb
+ Rakefile
+ .rspec
ディレクトリ構成
結果、作成されたディレクトリ構成(略)は下記の通り。
$ cd ~/sample
$ tree . -L 2
.
├── itamae
│ ├── Gemfile
│ ├── Gemfile.lock
│ ├── cookbooks
│ ├── roles
│ └── vendor
└── serverspec
├── Gemfile
├── Gemfile.lock
├── Rakefile
├── spec
└── vendor
動作確認
これで Itamae と Serverspec がインストール出来たので、試しにリモートホストにhttpdをインストールしてみる。
まずはコマンドを楽にするためにsshの設定を行う。
(本題とは少し異なるのでさらっと流す。)
// Vagrant の他方のインスタンスへの接続設定
$ cat << EOS > ~/.ssh/config
Host web
HostName 192.168.33.11
EOS
$ chmod 600 ~/.ssh/config
$ ssh-keygen -t rsa
$ ssh-copy-id web
$ ssh web
$ exit
下記でItamaeとServerspecの初歩的な使用をしてみる。
// --------------------------
// Itamae / レシピ作成
// --------------------------
// Itamae のレシピを作成
$ echo "package 'httpd'" > ~/sample/itamae/cookbooks/recipe.rb
// --------------------------
// Serverspec / テストを作成
// --------------------------
// Serverspecのファイルを作成
$ cat << EOS > ~/sample/serverspec/spec/web/httpd_spec.rb
require 'spec_helper'
describe package('httpd') do
it { should be_installed }
end
EOS
// --------------------------
// Itamae / レシピの正常性確認
// --------------------------
// Itamae のドライラン
$ cd ~/sample/itamae
$ bundle exec itamae ssh -h web cookbooks/recipe.rb -n
INFO : Starting Itamae...
INFO : Recipe: /home/vagrant/sample/cookbooks/recipe.rb
INFO : package[httpd] installed will change from 'false' to 'true'
// --------------------------
// Serverspec / エラーパターンの動作確認
// --------------------------
// Serverspecのエラーパターン
$ cd ~/sample/serverspec
$ rm spec/web/sample_spec.rb
$ bundle exec rake spec
/home/vagrant/.rbenv/versions/2.2.6/bin/ruby -I/home/vagrant/sample/vendor/bundle/ruby/2.2.0/gems/rspec-core-3.5.4/lib:/home/vagrant/sample/vendor/bundle/ruby/2.2.0/gems/rspec-support-3.5.0/lib /home/vagrant/sample/vendor/bundle/ruby/2.2.0/gems/rspec-core-3.5.4/exe/rspec --pattern spec/web/\*_spec.rb
Package "httpd"
should be installed (FAILED - 1)
Package "httpd"
should be installed (FAILED - 2)
Service "httpd"
should be enabled (FAILED - 3)
should be running (FAILED - 4)
Port "80"
should be listening (FAILED - 5)
Failures:
1) Package "httpd" should be installed
On host `web'
Failure/Error: it { should be_installed }
expected Package "httpd" to be installed
sudo -p 'Password: ' /bin/sh -c rpm\ -q\ httpd
package httpd is not installed
# ./spec/web/httpd_spec.rb:8:in `block (2 levels) in <top (required)>'
2) Package "httpd" should be installed
On host `web'
Failure/Error: it { should be_installed }
expected Package "httpd" to be installed
sudo -p 'Password: ' /bin/sh -c rpm\ -q\ httpd
package httpd is not installed
# ./spec/web/sample_spec.rb:4:in `block (2 levels) in <top (required)>'
3) Service "httpd" should be enabled
On host `web'
Failure/Error: it { should be_enabled }
expected Service "httpd" to be enabled
sudo -p 'Password: ' /bin/sh -c chkconfig\ --list\ httpd\ \|\ grep\ 3:on
# ./spec/web/sample_spec.rb:12:in `block (2 levels) in <top (required)>'
4) Service "httpd" should be running
On host `web'
Failure/Error: it { should be_running }
expected Service "httpd" to be running
sudo -p 'Password: ' /bin/sh -c ps\ aux\ \|\ grep\ -w\ --\ httpd\ \|\ grep\ -qv\ grep
# ./spec/web/sample_spec.rb:13:in `block (2 levels) in <top (required)>'
5) Port "80" should be listening
On host `web'
Failure/Error: it { should be_listening }
expected Port "80" to be listening
sudo -p 'Password: ' /bin/sh -c netstat\ -tunl\ \|\ grep\ --\ :80\\\
# ./spec/web/sample_spec.rb:27:in `block (2 levels) in <top (required)>'
Finished in 0.37589 seconds (files took 0.73406 seconds to load)
5 examples, 5 failures
Failed examples:
rspec ./spec/web/httpd_spec.rb:8 # Package "httpd" should be installed
rspec ./spec/web/sample_spec.rb:4 # Package "httpd" should be installed
rspec ./spec/web/sample_spec.rb:12 # Service "httpd" should be enabled
rspec ./spec/web/sample_spec.rb:13 # Service "httpd" should be running
rspec ./spec/web/sample_spec.rb:27 # Port "80" should be listening
/home/vagrant/.rbenv/versions/2.2.6/bin/ruby -I/home/vagrant/sample/vendor/bundle/ruby/2.2.0/gems/rspec-core-3.5.4/lib:/home/vagrant/sample/vendor/bundle/ruby/2.2.0/gems/rspec-support-3.5.0/lib /home/vagrant/sample/vendor/bundle/ruby/2.2.0/gems/rspec-core-3.5.4/exe/rspec --pattern spec/web/\*_spec.rb failed
// --------------------------
// Itamae / httpdのインストール
// --------------------------
// Itamae を使用して自動構築
$ cd ~/sample/itamae
$ bundle exec itamae ssh -h web cookbooks/recipe.rb
INFO : Starting Itamae...
INFO : Recipe: /home/vagrant/sample/cookbooks/recipe.rb
INFO : package[httpd] installed will change from 'false' to 'true'
// --------------------------
// Serverspec / 正常パターンの動作確認
// --------------------------
// Serverspecを使用して自動テスト
$ cd ~/sample/serverspec
$ bundle exec rake spec
/home/vagrant/.rbenv/versions/2.2.6/bin/ruby -I/home/vagrant/sample/serverspec/vendor/bundle/ruby/2.2.0/gems/rspec-core-3.5.4/lib:/home/vagrant/sample/serverspec/vendor/bundle/ruby/2.2.0/gems/rspec-support-3.5.0/lib /home/vagrant/sample/serverspec/vendor/bundle/ruby/2.2.0/gems/rspec-core-3.5.4/exe/rspec --pattern spec/web/\*_spec.rb
Package "httpd"
should be installed
Finished in 0.52577 seconds (files took 0.30729 seconds to load)
1 example, 0 failures
以上の手順で Itame と Serverspec を使用する準備が出来た。
あとはベスト・プラクティスに沿った構成を意識しながら、 Serverspecで期待構成の記載 ⇢ Itamaeで自動構成 を繰り返してインフラのTDDを実行していくことが出来る。
rbenv-build に関する日本語文献が少なくなかなか理解しきれていない。
- GitHub : rbenv-build
ruby-build is an rbenv plugin that provides an rbenv install command to compile and install different versions of Ruby on UNIX-like systems.
You can also use ruby-build without rbenv in environments where you need precise control over Ruby version installation.
引用 : ruby-build - GitHub