Chefやcookbookについては過去のエントリで書きましたが、最近opsworksを使う機会があったので、その辺について書いてみようと。
opsworksはAWSサービスでchefベースのサーバ構成ツール。
opsworksが提供しているcookbookも使えるし、そのcookbookの一部をカスタマイズしたり、自分で作ったオリジナルのcookbookも登録して実行できる。
opsworksのコンソールから実行すればrecipeの実行はできるが、カスタマイズしたり新規で作ったcookbookを試す為に、ec2のインスタンスをポコポコ立ち上げるのも多少お金がかかるし、落とし忘れたら大きめの請求が来て悲しい気持ちになるので、ローカルで試せるものはなるべくローカルで試してみたい!
ということで、ローカルでrecipeを実行する為の、環境づくりや方法について説明していきます。
recipeを実行する先は自分のPCではなく、今流行(流行りに乗るのがだいぶ遅いけど)のVagrantを使います。
(Vagrantについては詳しく説明しているサイトが他にもいっぱいあるので、詳しくはそちらを参照して下さい)
以下の説明はMac向けの説明となります。
VirtualBoxのインストール
VirtualBoxを以下のサイトからダウンロードして、インストールします。
https://www.virtualbox.org/wiki/Downloads
Vagrantのインストール
Vagrantを以下のサイトからダウンロードして、インストールします。
http://www.vagrantup.com/downloads.html
どちらもインストーラーなので、簡単ですね。
Vagrantで仮想マシンを作る
ここからはターミナルを使って作業していきます。
どこか好きな所にディレクトリを作ってその中で作業します
$ mkdir ~/Documents/Vagrant $ cd ~/Documents/Vagrant
今回はubuntuのイメージを使って作業するので、ubuntuのboxを作成します。
こちらのサイトに色々なイメージが公開されているので、使いたいものを選びます。
(VirtualBox用を使うこと)
$ vagrant box add ubuntu12_04 http://cloud-images.ubuntu.com/vagrant/precise/current/precise-server-cloudimg-amd64-vagrant-disk1.box
VagrantFileを作ります
$ mkdir ubuntu $ cd ubuntu $ vagrant init ubuntu12_04
起動してみます
$ vagrant up Bringing machine 'default' up with 'virtualbox' provider... [default] Importing base box 'ubuntu12_04'... [default] Matching MAC address for NAT networking... [default] Setting the name of the VM... [default] Clearing any previously set forwarded ports... [default] Clearing any previously set network interfaces... [default] Preparing network interfaces based on configuration... [default] Forwarding ports... [default] -- 22 => 2222 (adapter 1) [default] Booting VM... [default] Waiting for machine to boot. This may take a few minutes... [default] Machine booted and ready! [default] The guest additions on this VM do not match the installed version of VirtualBox! In most cases this is fine, but in rare cases it can prevent things such as shared folders from working properly. If you see shared folder errors, please make sure the guest additions within the virtual machine match the version of VirtualBox you have installed on your host and reload your VM. Guest Additions Version: 4.1.12 VirtualBox Version: 4.3 [default] Mounting shared folders... [default] -- /vagrant
起動しました。
通常は、vagrant ssh で仮想マシンに入れますが、後でrecipeを実行するときに不便なので、ssh hogehoge で入れるように設定します。
以下のコマンドsshのconfigに記載する情報を表示します
$ vagrant ssh-config Host default HostName 127.0.0.1 User vagrant Port 2222 UserKnownHostsFile /dev/null StrictHostKeyChecking no PasswordAuthentication no IdentityFile /Users/hogehoge/.vagrant.d/insecure_private_key IdentitiesOnly yes LogLevel FATAL
表示された内容を~/.ssh/config に追記します
$ vi ~/.ssh/config Host vagrant-ubuntu HostName 127.0.0.1 User vagrant Port 2222 UserKnownHostsFile /dev/null StrictHostKeyChecking no PasswordAuthentication no IdentityFile /Users/hogehoge/.vagrant.d/insecure_private_key IdentitiesOnly yes LogLevel FATAL
入れるか試します
$ ssh vagrant-ubuntu Welcome to Ubuntu 12.04.4 LTS (GNU/Linux 3.2.0-59-generic x86_64) * Documentation: https://help.ubuntu.com/ System information as of Sat Feb 22 00:24:13 UTC 2014 System load: 0.0 Processes: 64 Usage of /: 2.7% of 39.37GB Users logged in: 0 Memory usage: 10% IP address for eth0: 10.0.2.15 Swap usage: 0% Graph this data and manage this system at: https://landscape.canonical.com/ Get cloud support with Ubuntu Advantage Cloud Guest: http://www.ubuntu.com/business/services/cloud 0 packages can be updated. 0 updates are security updates. vagrant@vagrant-ubuntu-precise-64:~$
入れました!
仮想マシンの準備ができたので、仮想サーバから抜けて、先ほどのディレクトリ(~/Documents/Vagrant/ubuntu)に戻ります。
chef-soloのセットアップ
Macの方にknife-soloが必要なので、gemで入れます。
今回試したrubyの環境は、以下のとおりです
$ ruby -v ruby 2.0.0p247 (2013-06-27 revision 41674) [universal.x86_64-darwin13] $ gem -v 2.0.3
knife-soloをインストール
$ sudo gem install knife-solo
バージョンを確認すると
$ knife -v Chef: 11.10.4
chef-repoを作る
cookbookなどを含めるディレクトリをknifeコマンドで作ります
$ knife solo init opsworks-test WARNING: No knife configuration file found Creating kitchen... Creating knife.rb in kitchen... Creating cupboards...
作成されたディレクトリに移動します
$ cd opsworks-test
ディレクトリ内に作られたファイルとかは以下の様な感じ
opsworks-test/ .chef .gitignore cookbooks data_bags environments nodes roles site-cookbooks
cookbooksディレクトリは、opsworksのcookbookを置くので、一旦削除してgithub上のリポジトリをcookbooksとしてcloneします。
$ rm -rf cookbooks $ git clone https://github.com/aws/opsworks-cookbooks.git cookbooks
一回、opsworksで用意されているcookbookを試してみます。
cookbookを実行するためには、対象の仮想マシンにchef-soloが入っている必要があります。
仮想マシンに入ってインストールしてもいいですが、以下のコマンドで必要な物をインストールすることが出来ます。
$ knife solo prepare vagrant-ubuntu
セットアップが完了すると、nodes/vagrant-ubuntu.json がMac上に作られます。
ファイルの中身は、
{"run_list":[]}
となっているので、run_listに実行するrecipeを書きます。
(run_listにカンマ区切りで書けば複数のrecipeを実行することが出来ます)
$ vi nodes/vagrant-ubuntu.json
run_listにnginxを追加しました
{ "run_list":[ "nginx" ] }
recipeを実行します
$ knife solo cook vagrant-ubuntu
ちゃんとnginxがインストールされたか見てみます。
$ ssh vagrant-ubuntu $ ps aux | grep nginx root 3456 0.0 0.2 62876 1336 ? Ss 02:11 0:00 nginx: master process /usr/sbin/nginx www-data 3457 0.0 0.3 63212 1912 ? S 02:11 0:00 nginx: worker process www-data 3458 0.0 0.3 63212 1912 ? S 02:11 0:00 nginx: worker process www-data 3459 0.0 0.3 63212 1912 ? S 02:11 0:00 nginx: worker process www-data 3460 0.0 0.3 63212 1912 ? S 02:11 0:00 nginx: worker process www-data 3461 0.0 0.3 63212 1912 ? S 02:11 0:00 nginx: worker process www-data 3462 0.0 0.3 63212 1912 ? S 02:11 0:00 nginx: worker process www-data 3463 0.0 0.3 63212 1912 ? S 02:11 0:00 nginx: worker process www-data 3464 0.0 0.3 63212 1912 ? S 02:11 0:00 nginx: worker process www-data 3465 0.0 0.3 63212 1912 ? S 02:11 0:00 nginx: worker process www-data 3466 0.0 0.3 63212 1912 ? S 02:11 0:00 nginx: worker process vagrant 3654 0.0 0.1 8108 928 pts/0 S+ 02:12 0:00 grep --color=auto nginx
ちゃんと入ってました。
次は自分で作ったrecipeを実行できるようにします。
カスタムcookbookの実行
カスタムのcookbookは、site-cookbooksに配置します。
opsworksのコンソールでgitのリポジトリを指定している場合は、そのリポジトリをsite-cookbooksにcloneします。
例)
$ rm -rf site-cookbooks $ git clone <カスタムリポジトリを指定> site-cookbooks
今回は、サンプルとしてnginxに以下の変更を加えます。
- worker processを2つにする
- access_logのフォーマットをltsvに変更
カスタムcookbookを置くディレクトリを作って、opsworksのcookbookからnginxのテンプレートをコピーします
$ mkdir -p site-cookbooks/nginx/templates/default $ cp cookbooks/nginx/templates/default/nginx.conf.erb site-cookbooks/nginx/templates/default/nginx.conf.erb $ cp cookbooks/nginx/templates/default/default-site.erb site-cookbooks/nginx/templates/default/default-site.erb
nginx.conf.erbを編集します
$ vi site-cookbooks/nginx/templates/default/nginx.conf.erb 〜〜〜 http { 〜〜〜 access_log <%= node[:nginx][:log_dir] %>/access.log; log_format ltsv 'time:$time_local\t' 'host:$remote_addr\t' 'request:$request\t' 'status:$status\t' 'size:$body_bytes_sent\t' 'referer:$http_referer\t' 'ua:$http_user_agent\t' 'reqtime:$request_time\t' 'upsttime:$upstream_response_time';
default-site.erbを編集します
$ vi site-cookbooks/nginx/templates/default/default-site.erb server { listen 80; server_name 127.0.0.1; access_log <%= node[:nginx][:log_dir] %>/localhost.access.log ltsv; location / { root /var/www/nginx-default; index index.html index.htm; } }
recipeやtemplateで使われているattributeを上書く場合は、先ほどのnodes/vagrant-ubuntu.json に書きます。
$ vi nodes/vagrant-ubuntu.json { "run_list":[ "nginx" ], "nginx":{ "worker_processes": 2 } }
実行します
$ knife solo cook vagrant-ubuntu
ちゃんと反映されたか確認します。
$ ssh vagrant-ubuntu $ sudo service nginx restart $ ps aux | grep nginx root 5197 0.0 0.2 62876 1216 ? Ss 02:45 0:00 nginx: master process /usr/sbin/nginx www-data 5198 0.0 0.3 63212 1916 ? S 02:45 0:00 nginx: worker process www-data 5199 0.0 0.3 63212 1916 ? S 02:45 0:00 nginx: worker process vagrant 5201 0.0 0.1 8108 932 pts/0 S+ 02:45 0:00 grep --color=auto nginx
worker processが2つになりました。
次にテンプレートが反映されたか確認するので、デフォルトのindex.htmlを用意します
$ sudo mkdir -p /var/www/nginx-default $ sudo touch /var/www/nginx-default/index.html $ curl -I http://localhost/ HTTP/1.1 200 OK Server: nginx/1.1.19 Date: Sat, 22 Feb 2014 02:52:36 GMT Content-Type: text/html Content-Length: 0 Last-Modified: Sat, 22 Feb 2014 02:51:03 GMT Connection: keep-alive Accept-Ranges: bytes
ログを見ると
$ cat /var/log/nginx/localhost.access.log time:22/Feb/2014:02:52:36 +0000 host:127.0.0.1 request:HEAD / HTTP/1.1 status:200 size:0 referer:- ua:curl/7.22.0 (x86_64-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3 reqtime:0.000 upsttime:-
ちゃんと、ltsv形式になっています。
これで、opsworksのcookbookとカスタムcookbookを組み合わせたrecipeの実行がローカルでも出来るようになりました!
もう、EC2の料金を気にしなくても、recipeのテストが出来ますね。
仮想マシンなので、何度繰返してもvagrant destroyしてから、vagrant up すれば、いつでもまっさらな環境でテストできるのがいいですね。
次は、jenkinsと組み合わせてrecipeのテストにチャレンジしようと思います。