AWS OpsWorksで使うCustom Cookbookをローカルでデバッグしてみる

最近社内ではAWS関連の仕事をかなり担当するようになりました.
@h3_potetoです.

現在,インターファームのサービスをAWSで動かすときは,ほぼOpsWorksを使っています.
OpsWorksは,cookbookというレシピによってサーバーを起動します.
これが,AWSがデフォルトで用意しているcookbook.
https://github.com/aws/opsworks-cookbooks

OpsWorksというのは,ここに記述されているレシピを実行しながらインスタンスを起動してくれます.

しかし,サービスによってはサーバー側にいろいろ設定したい場合がありますよね.
そういうときには,このデフォルトのcookbookに加えて,オリジナルのcookbookを導入することができます.

それがCustom Cookbook.


これを用意するためには,もちろんこちら側でChefのレシピを書く必要があります.



これのデバッグがしたい

OpsWorksのサーバーで動かす前提のcookbookなので,Chefを書いてもなかなかデバッグが難しい.
もちろん,サーバーを起動して,インスタンスssh接続し,レシピを書き換えながら,レシピを実行してみれば確認はできる.

だけれど,これはデバッグ方法としてはちょっと手間が多すぎるじゃないですか.

できればローカルで実行したい,というのは誰もが思うところ.

というわけでやってみました.


なにはともあれ,vagrantを入れる

使うのは,vagrant
ここにchefを流し込んでうまくいくかを試します.


vagrantのセットアップについては,この辺(Vagrant セットアップ (Mac) - Qiita)を参考にしましょう.

OSは適当にOpsWorksで使うOSに合わせたものを用意しておいてください.

ただし,vagrantsshのconfigに書いておいて,そっちから入れるようにしておいたほうが便利です.

$ vagrant ssh-config

Host default
  HostName 127.0.0.1
  User vagrant
  Port 2222
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile /Users/user_name/.vagrant.d/insecure_private_key
  IdentitiesOnly yes
  LogLevel FATAL

これでssh接続に必要な情報が出てくるので,それを~/.ssh/configに記述してやります.

Host vagrant-ubuntu
  HostName 127.0.0.1
  User vagrant
  Port 2222
  IdentityFile /Users/user_name/.vagrant.d/insecure_private_key


あとは,

$ ssh vagrant-ubuntu

でログインできるようになりました.


ホストOSのMac側にknife-soloを入れます

※以下の作業はホスト側のOSですべて行います.

rubyは必要なので,適当に用意しておいてください.

gemは最新の方が何かといいとは思いますので,gemのアップデートをかけます.
この辺,rbenvを使っている方は適宜,合わせてアップデートしてやってください.

$ gem update --system


では,knife-soloを入れます.

$ sudo gem install knife-solo

これで終わりです.


実際にchefを入れて動かす

※以下の作業はホスト側のOSで行います.

まず,cookbook用のディレクトリを作ります.
vagrant内に作る必要があるので,Vagrantfileが存在するディレクトリ以下で作業をしてください.

$ cd ~/Vagrant/Ubuntu
$ knife solo init opsworks

~/Vagrant/Ubuntu以下にopsworksというディレクトリができました.


このディレクトリは

.chef
.gitignore
cookbooks
data_bags
environments
nodes
roles
site-cookbooks

こんな感じに初期化されています.



cookbooksディレクトリが,デフォルトのcookbookを入れる場所です.
今回の例で言うと,

https://github.com/aws/opsworks-cookbooks

こいつが本来入る場所です.

なので,cloneしてきてあげましょう.
デフォルトのままでいいです.



試し方は割と簡単.

まず,初回は仮想のOSにchef-soloを入れてやる必要があります.

$ cd ~/Vagrant/Ubuntu/opsworks
$ knife solo prepare vagrant-ubuntu

コレで入る.


あとは,

$ cd ~/Vagrant/Ubuntu/opsworks
$ knife solo cook vagrant-ubuntu

コレで動きます.
※必ずknife solo initで作成したディレクトリの直下に移動してから行ってください.以下で話すnodes/のディレクトリがないと実行できません.

でもどれが動くのか?
実行するレシピの設定は,nodes/vagrant-ubuntu.jsonのrun_listに書きます.これはprepareした時点で用意されます.



ちなみに,普段OpsWorksではLayerのオプションに実行するレシピが記述されていますよね.
OpsWorksだとデフォルトでいくつものレシピが実行されると思います.

こういう実行するレシピの設定も……nodes/vagrant-ubuntu.jsonに書けば実行されます.

また,普段custom jsonの内容も同じくnodes/vagrant-ubuntu.jsonに書きます.

{
  "custom_env": {
    "account_id": "hogehoge",
    "password": "hogehoge"
  },
  "run_list": [
    "opsworks::setup",
    "opsworks::install"
  ]
}

こんな感じです.
この辺は自分がデバッグしたいものに合わせます.


自分のcustom cookbookを入れる


custom cookbookはsite-cookbook/以下のフォルダに配置します.

ここにChefを書いていきましょう.
あとは,このレシピをrun_listに記述すればいいですね.




これで自分のcustom cookbookをvagrant内で実行することができます.



[番外編]sandboxを使う

chefを流す……ということは,vagrantの仮想OSにいろいろなものをインストールするというレシピも含まれます.
そういうもののデバッグをしていると,どうしてもchefでインストールしたものを,クリーンしたいときが出tてきますよね.
もちろん,そういうレシピを書いておけばいいのだけれど,めんどくさいです…….

そんなときに便利なのがsandbox.

これは,vagrantの仮想OSの状態をcommitしておき,そこまでrollbackできるというすぐれものツール
これがあれば,とりあえずvagrantの初回起動時にcommitしておけば,空っぽの状態のOSを復元することができる.


vagrantでこれを使うには,saharaというやつが非常に便利です.

インストール方法は以下.

$ git clone https://github.com/ryuzee/sahara.git
$ cd sahara
$ bundle install
$ vagrant plugin install sahara


sandboxモードを開始する

$ vagrant sandbox on

あとは,commitしてrollback.

$ vagrant sandbox commit
$ vagrant sandbox rollback

vagrantのセットアップが終わった段階でcommitしておき,あとはchefを実行するたびにrollbackしてやれば,毎回クリーンな状態からすべてのchefの実行を試すことができます.




参考:
Vagrant セットアップ (Mac) - Qiita
Vagrant + chef-soloでopsworksのrecipeをローカルで試す - sparkgeneのブログ
saharaでVagrantの状態管理 - Qiita