test-kitchenでインフラのTDDに挑戦[Rails/nginx/MySQL/rbenv]


これまでVagrantやChefをつかってインフラのコード化を勉強してきましたが、今回はさらに一歩進めてServerspecを使ったインフラのテストと、『test-kitchen』を使ったTDDにチャレンしてみました!

慣れてくるとtest-kitchenのコマンドで設定をやり直し => インフラのテストがソースコードを書くような感覚で、インフラを構築できるのがすごく心地良かったです。

ようやくですが、localのvagrantと『AWS EC2』、『Digital Ocean』に対応しました。コマンドひとつでChefを適用したり、Serverspecでリモートの環境をテストできます!

(05-02 08:35) Rubyサーバ・デプロイまでのチェックリストを追加


🍮 今回のソースコード

Vagrant/Digital Ocean/AWS EC2上にnginx/MySQL/rbenv/Ruby 2.1.0/Ubuntu 12.04のお馴染みのサーバ構成の構築/テストを行うtest-kitchenのソースコードをGitHubに公開しました。また、Vagrant x CentOS 6.5 /nginx/MySQL/rbenv/Ruby 2.1.0も作成しました。

morizyun/test-kitchen-rails

手っ取り早くVagrantでRailsサーバを立ち上げたり、Serverspecでテストしてみたい方はぜひ使ってみてください! Pull Requestも大歓迎です^^

🐞 環境準備

Vagrant

Vagrant 公式サイト

パッケージをDLしてインストール。

vagrantをインストールしたら、boxでChefを使えるようにするためのプラグインをインストール。

vagrant plugin install vagrant-omnibus

VirtualBox

VirtualBox 公式サイト

パッケージをDLしてインストール。

🗻 簡単なtest-kitchen環境の作り方

Cookbookの作成

berks cookbook test-kitchen && cd test-kitchen

Gemfileのセットアップ

次にvim Gemfileでセットアップ。

source 'https://rubygems.org'
gem 'berkshelf'
gem 'foodcritic'
gem 'rubocop'
gem 'busser'
gem 'serverspec'
gem 'dotenv'
# test-kitchen
gem 'test-kitchen'
gem 'kitchen-vagrant'
gem 'kitchen-digitalocean'
gem 'kitchen-ec2'

完了したらBundlerでgemを導入。

bundle install --binstubs=bin

vim bin/kitchenでdotenvを読み込むように設定を追記。

require 'dotenv'
Dotenv.load

この設定は本来は良くないと思います。bundle installのたびに設定を描き直さないといけないので、もっといい方法があればぜひ教えてください!

busserプラグインの設定

次にプラグインの設定。

busser plugin install serverspec

Berksfileのセットアップ

vim BerksfileでBerkshelfの設定。

(まだ試行錯誤中ですので、最新はGitHubをご参照ください)

site :opscode
metadata
cookbook "apt",
git: "https://github.com/opscode-cookbooks/apt.git"
cookbook "build-essential",
git: "https://github.com/opscode-cookbooks/build-essential.git"
cookbook "git",
git: "https://github.com/opscode-cookbooks/git.git"
cookbook "nginx",
git: "https://github.com/opscode-cookbooks/nginx.git"
cookbook "vim",
git: "https://github.com/opscode-cookbooks/vim.git"
cookbook "mysql",
git: "https://github.com/myplanetdigital-experimental/chef-mysql.git"
cookbook 'rbenv',
git: "https://github.com/fnichol/chef-rbenv.git"
cookbook 'database',
git: "https://github.com/opscode-cookbooks/database.git"
cookbook 'base', path: 'site-cookbooks/base'

設定画完了したら、Berkshelfの設定を反映。

bundle exec berks vendor cookbooks

.kitchen.ymlの設定

vim .kitchen.ymlでtest-kitchen用の設定。

---
provisioner:
name: chef_solo
driver_config:
require_chef_omnibus: true
platforms:
- name: va-ubuntu-12.04
driver:
name: vagrant
network:
- ["private_network", {ip: "192.168.33.33"}]
synced_folders:
- ["vagrant", "/usr/share/nginx", "create: true, type: :nfs"]
provider: virtualbox
driver_config:
box: opscode-ubuntu-12.04
box_url: https://opscode-vm.s3.amazonaws.com/vagrant/opscode_ubuntu-12.04_provisionerless.box
customize:
memory: 1024
cpuexecutioncap: 100
- name: va-centos-6.5
driver:
name: vagrant
network:
- ["private_network", {ip: "192.168.33.32"}]
synced_folders:
- ["vagrant", "/usr/share/nginx", "create: true, type: :nfs"]
driver_config:
box: opscode-centos-6.5
box_url: http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_centos-6.5_chef-provisionerless.box
suites:
- name: rails
run_list:
- recipe[base::prepare]
- recipe[build-essential]
- recipe[git]
- recipe[vim]
- recipe[nginx]
- recipe[mysql::server]
- recipe[mysql::client]
- recipe[ruby_build]
- recipe[rbenv::system]
- recipe[base]
- recipe[base::rails]
attributes:
git:
version: 1.9.1
nginx:
application_name: 'sample'
mysql:
server_debian_password: "passw0rd"
server_root_password: "passw0rd"
server_repl_password: "passw0rd"
rbenv:
rubies: ['2.1.0']
global: '2.1.0'
gems:
'2.1.0':
- name: 'bundler'
options: '--no-ri --no-rdoc'
- name: 'gem'
options: '--no-ri --no-rdoc'
- name: 'rails'
options: '--no-ri --no-rdoc'
- name: 'rake'
options: '--no-ri --no-rdoc'
- name: 'therubyracer'
options: '--no-ri --no-rdoc'

👽 Vagrant/Ubuntu編

まずはvagrantでローカルにUbuntuを立ち上げます。

セットアップ

vagrantのセットアップを行います。

kitchen setup rails-va-ubuntu-1204

servespecテスト

Serverspecで立ち上げたvagrantのテストを行います。

kitchen verify rails-va-ubuntu-1204
# 次のように出れば成功
# Finished in seconds
# 15 examples, 0 failures
# Finished verifying <rails-va-ubuntu-1204>
# -----> Kitchen is finished

🏀 Vagrant/CentOS編

まずはvagrantでローカルにCentOSを立ち上げます。

セットアップ

vagrantのセットアップを行います。

kitchen setup rails-va-centos-65

servespecテスト

Serverspecで立ち上げたvagrantのテストを行います。

kitchen verify rails-va-centos-65
# 次のように出れば成功
# Finished in seconds
# 15 examples, 0 failures
# Finished verifying <rails-va-ubuntu-1204>
# -----> Kitchen is finished

🍄 Digital Ocean編

次は『Digital Ocean』に鯖を立ち上げます。

下準備

以下、『Digital Ocean』での作業。

1) Digital Oceanでユーザー登録
2) ユーザー画面内の左メニュー「Billing」からPayPalで$5を支払い
3) ユーザー画面内の左メニュー「API」で"Client ID"と"API Key"を作成
4) ユーザー画面内の左メニュー「SSH Keys」でSSHキーを登録

下準備で取得した”Client ID”と”API Key”を元にSSH Key IDを取得。

wget -q -O- https://api.digitalocean.com/ssh_keys/?client_id=[Client ID]&api_key=[API Key]

登録した情報を。envに登録

取得した情報をvim .envで登録。DIGITALOCEAN_SSH_KEY_PATHにはDigital Oceanに登録したSSHキーの秘密鍵へのパスを設定。

DIGITALOCEAN_CLIENT_ID="1234"
DIGITALOCEAN_API_KEY="5678"
SSH_KEY_IDS="1234, 5678"
DIGITALOCEAN_SSH_KEY_PATH="~/.ssh/id_rsa"

.kitchen.ymlを設定

platforms:
- name: do-ubuntu-12.04
driver:
name: digitalocean
ssh_key: <%= ENV['DIGITALOCEAN_SSH_KEY_PATH'] %>
driver_config:
image_id: 3101045
region: San Francisco 1
flavor: 512MB
private_networking: false

セットアップ

Digital Oceanのインスタンスのセットアップを行います。

kitchen setup rails-do-ubuntu-1204

Digital Oceanのユーザー画面内の左メニュー「Droplets」で立ち上がっているインスタンスを確認できます。

スクリーンショット_2014-04-12_12_38_11

servespecテスト

Serverspecで立ち上げたvagrantのテストを行います。

kitchen verify rails-do-ubuntu-1204
# 次のように出れば成功
# Finished in seconds
# 15 examples, 0 failures
# Finished verifying <rails-do-ubuntu-1204>
# -----> Kitchen is finished

🎳 AWS EC2編

次は『AWS EC2』に鯖を立ち上げます。

下準備

以下、『AWS EC2』での作業。

1) AWS EC2でユーザー登録
2) EC2 => 自分が作成するリージョン(Tokyo)でセキュリティグループを作成
3) EC2 => Key Pairで鍵を作成(もしくはImportして登録)
4) 右上のメニュー「Security Credential」=> Access Keyを作成

登録した情報を。envに登録

取得した情報をvim .envで登録。DIGITALOCEAN_SSH_KEY_PATHにはDigital Oceanに登録したSSHキーの秘密鍵へのパスを設定。

AWS_ACCESS_KEY_ID="xxxx"
AWS_FLAVOR_ID="m1.small"
AWS_IMAGE_ID="ami-f397eef2"
AWS_SECRET_ACCESS_KEY="xxxx"
AWS_SECURITY_GROUP_ID="sg-xxxxx"
AWS_SSH_KEY="~/.ssh/aws.pem"
AWS_SSH_KEY_ID="xxxx"

.kitchen.ymlを設定

platforms:
- name: ec2-ubuntu-12.04
driver:
name: ec2
region: ap-northeast-1
availability_zone: ap-northeast-1c
flavor_id: <%= ENV['AWS_FLAVOR_ID'] %>
image_id: <%= ENV['AWS_IMAGE_ID'] %>
aws_ssh_key_id: <%= ENV['AWS_SSH_KEY_ID'] %>
aws_access_key_id: <%= ENV['AWS_ACCESS_KEY_ID'] %>
ssh_key: <%= ENV['AWS_SSH_KEY'] %>
aws_secret_access_key: <%= ENV['AWS_SECRET_ACCESS_KEY'] %>
username: ubuntu
security_group_ids: ["<%= ENV['AWS_SECURITY_GROUP_ID'] %>"]
port: 22
ebs_optimized: false

セットアップ

EC2のインスタンスのセットアップを行います。

kitchen setup rails-ec2-ubuntu-1204

AWSマネジメントコンソール => EC2画面で立ち上がっているインスタンスを確認できます。

スクリーンショット_2014-04-12_15_01_08

servespecテスト

Serverspecで立ち上げたvagrantのテストを行います。

kitchen verify rails-ec2-ubuntu-1204
# 次のように出れば成功
# Finished in seconds
# 15 examples, 0 failures
# Finished verifying <rails-do-ubuntu-1204>
# -----> Kitchen is finished

🐠 サーバのセットアップ完了 => Railsアプリケーションデプロイまでの手順

(1) test-kitchenの実行 => テスト実行

(2) Elastic Block Storeを設定

(3) 鯖側にdeploy用のキーを作成 => 公開鍵をGitHubに登録

(4) MySQLのユーザー作成
GRANT ALL PRIVILEGES ON DB_NAME.* TO USER_NAME@localhost IDENTIFIED BY ‘PASSWORD';
FLUSH PRIVILEGES;

(5) ローカルでCapistranoを使ったデプロイ
cap production deploy:starting
cap production deploy:check
cap production deploy # dbがないのでコケる

(6) 鯖のreleaseフォルダで、bundle exec Rake RAILS_ENV=production db:create

(7)cap production deploy

初回デプロイ時にDBがながときに先にDBを作成する方法は、もっといい方法があるはずなのでご存じの方がいれば、コメントをいただければ幸いです!

Capistrano 3系でRails4.1のデプロイ

Capistrano 3の設定はこちらがお勧め。

🎃 次のステップ

残念ながら今回は挫折しましたが、Dokkuをまる2日位ためしてみました。まだまだ実用レベルとは言いづらいですが、可能性をすごく感じるプロダクトです! 今回は調査していた中で見付け足サイトをメモがてら書いておきます。

🍣 ChefでDocker&Dokkuをインストール

fgrehm/chef-dokku - GitHub

bflad/chef-docker - GitHub

progrium/dokku - GitHub

rlister/chef-dokku-simple - GitHub

hughfletcher/dokku-mysql-plugin - GitHub

🐡 参考リンク

Chef で Elasticsearch クラスタを EC2 上に作る

こちらのブログでtest-kitchenの使い方を知ることができました。多謝です!

dotenvを利用して環境ごとでVagrantfileの設定値を変更してみる

test-kitchen/kitchen-digitalocean

🚜 変更来歴

(04/12 12:45) Digital OceanとAWS EC2を適用

(04/14 23:35) Docker & Dokkuに関するメモ書きを追記

(04/23 22:50) CentOS 6.5 x Vagrantを追加、バグフィックス

(04/25 23:00) ちょこちょこミスがあった点を修正

(05-02 08:35) Rubyサーバ・デプロイまでのチェックリストを追加

🖥 VULTRおすすめ

VULTR」はVPSサーバのサービスです。日本にリージョンがあり、最安は512MBで2.5ドル/月($0.004/時間)で借りることができます。4GBメモリでも月20ドルです。 最近はVULTRのヘビーユーザーになので、「ここ」から会員登録してもらえるとサービス開発が捗ります!

📚 おすすめの書籍