1年くらいchefを使ってサーバ構築をしていたのですが、最近ansibleに乗り換えたので紹介記事を書いてみます
1. サーバ側に何もインストールする必要がない
chefは管理対象ノードにchef-clientをインストールする必要がありますが、ansibleはPython 2.4が入っていて、sshでログインできればOKです。
chefもパッケージや,knife bootstrap
コマンド等があるので始めやすいですが、何もする必要がないansibleの方が敷居が低いのかなと思ってます。
例えばsshでログインできれば、以下のコマンドを打てば10.0.10.1~10.0.10.3サーバの情報をとってくれます(カーネルバージョン,CPU,メモリ,ディスクサイズ,ディストリビューション等)。
この機能はchefで使われているohai相当のことをしてくれます。
echo 10.0.10.1 > host
echo 10.0.10.2 >> host
echo 10.0.10.3 >> host
ansible -i host all -m setup
出力の一部抜粋
"ansible_lsb": {
"codename": "precise",
"description": "Ubuntu 12.04.4 LTS",
"id": "Ubuntu",
"major_release": "12",
"release": "12.04"
},
このようにすぐに始められます
2. シンプルな構造になっている
ansibleはとてもシンプルで、動かすだけならインベントリ(ホスト名を列挙したもの)とymlコードの2つだけあれば動きます。とっても覚えることが少ないです。
フォルダ構成のベストプラクティスがありますが、それほど複雑ではないです。
chefも少し使う分なら最初のうちは覚えることは少ないですが、2ファイルだけで始められるansibleに比べると覚えることが多い気がします。
例えば、templetaのフォルダ評価順序が以下のようになっているとか何回聞いても忘れてしまいます(まあ大抵templates/defaultフォルダに入れてしまいますが)。
templatesディレクトリ評価順序、Attributeの優先順位はこんな感じでした。
chefのtemplatesディレクトリ評価順序
- host-node[:fqdn]
- node[:platform]-node[:platform_version]
- node[:platform]-version_components
- node[:platform]
- default
chefのAttribute優先順位
- A default attribute located in a cookbook attribute file
- A default attribute located in a recipe
- A default attribute located in an environment
- A default attribute located in role
- A force_default attribute located in a cookbook attribute file
- A force_default attribute located in a recipe
- A normal attribute located in a cookbook attribute file
- A normal attribute located in a recipe
- An override attribute located in a cookbook attribute file
- An override attribute located in a recipe
- An override attribute located in a role
- An override attribute located in an environment
- A force_override attribute located in a cookbook attribute file
- A force_override attribute located in a recipe
- An automatic attribute identified by Ohai at the start of the chef-client run
chefのcookbookとansibleのroleについてのドキュメントは以下の通りです。ansibleの方がシンプルに感じませんか?
- About Cookbooks(注: http://docs.opscode.com/essentials_cookbooks.htmlはその後リンク切れになりました)
- Playbook Roles and Include Statements
chefにあるdefinitions,providersの仕組みは便利ですが、いまのところansibleの自作モジュールで事足りてます。
実行するときもansibleの方が簡単だと思います。
chefの場合,運用する場合はchef serverを立てる必要がありますし、chef-soloで運用する場合でも、どうやってサーバにコードを転送するか(knife solo等)?を考慮する必要があります。
ansibleの場合は手元にあるコードを対象のサーバに対して実行するというだけですから実行環境はとてもシンプルです。
3. コードが分りやすい
まあこれは好みによるところが大きいですが行数が少ないymlで書いたansibleコードの方が個人的に好きです。
コード例
※厳密に同じ意味ではないです
ansible
chef
どうでしょうか?クォートとかrubyのシンタックス等を意識しないで済むのでよりシンプルに感じませんか?(感じなかったらごめんなさい)
ymlだと表現力が乏しいと感じる方もいるかもしれませんが、後述するモジュールの仕組みやシェルスクリプトを転送してリモートで実行等の技を駆使すれば何とかなります(いまのところ)。
またchefのコードが分りにくい点の一つに上から順に実行されるとは限らないというのがあります。
例えば上記chefコードはパッケージのインストール,ユーザの作成よりも先に"テンプレートの更新"という出力を行います。
- 参考リンク: Chefのレシピは上から下に実行されるという誤解(注: http://www.engineyard.co.jp/blog/2013/chef-recipe-lifecycle/ はその後リンク切れになりました)
ansibleの場合は上から順に実行されます。
4. 好きな言語で書ける
ansibleはPythonで作られていますが、モジュールは指定された入力と出力を守ればいいだけです。リモートで実行できるならperl,ruby,bash,javaなんでも使えます。
今まで、シェルスクリプトでinfrastructure as codeまがいな事をやっていたので過去の資産を活用でき、とても助かっています。
- 参考リンク: Ansible モジュール作成のイロハ
5. 同時実行が書きやすい
ansibleはインベントリファイルにサーバをグループとしてまとめられます。
例えば以下のように記述して
[app_server]
192.168.0.1
192.168.0.2
192.168.0.3
192.168.0.4
192.168.0.5
taskの方では以下のようにします。
name: アプリサーバ設定
hosts: app_server
これだけで192.168.0.1~192.168.0.5まで一気に設定してくれます。
chef-solo時代はcapistranoとかtmuxの同期モード等で頑張っていたのですが、どのサーバがどのタスクまで終わったのか確認が難しかったりしました。
ansibleの場合はタスクごとに同期を取って実行してくれるので、appサーバはrailsのインストールまで、dbサーバはmysqlのインストールが終わるまで待ち合わせみたいな書き方もしやすいです。
いやなところとか
ansibleを散々褒めちぎったあとに言うのもなんですが、不満点がないわけではないのでちょっと書いておきます。
ansibleのtemplate jinja2がvimと相性悪い
vimのデフォルトのfoldmarker(折りたたみマーク)は{{{,}}}
なんですが、これがjinja2のテンプレートのsyntaxとバッティングしてエラーになります。
foldmarkerを変えれば済む話なのですが、すでに書いてしまったconfファイルをtemplate化するときに気をつける必要があります。
jinja2の内で変数を組み立てられない
jinja2でも大抵のことはできるんですが、テンプレート内で変数の代入が出来ないのでちょっと使いにくいです。
erbに慣れている部分も多分にありますがjinja2のシンタックスを覚えるのが面倒でした。
ansibleでもerbを使う方法は無くはないのですが、標準テンプレートの方が簡単です。
chefのnot_if相当のことができない
chefではリソース実行のときにnot_ifでコマンドを実行し、結果を元に実行の可否を判断できましたが、ansibleだと一旦コマンドを実行してからregister: result
みたいに保存して後ろで判定しなければいけないのがちょっと面倒です。
あとコマンドを実行しちゃうとchangedに+1されてしまうので、ちょっと気持ち悪いです。
(※ when_changedでカウントを無効にすることが出来ますが、それでもちょっと手間なのかなと)
まとめ
ansible贔屓の内容になってしまいましたが、chefのことをディスっているわけでなくてこんな違いがあるんだなと感じて頂ければ幸いです。
現在chefを使用していて特に不満がなかったり、活用できている人は無理に変える必要はありませんが、chefを使っていて面倒だなと感じたりinfrastructure as code
を実践できていないのならansibleを試してみてはいかがでしょうか?
ubuntu14.04ならapt-get install ansible
で入ります。
実際チュートリアルを見て30分程度で使い始めることができました。