ばうあーろぐ TOP へ戻る

Chef を捨てて Ansible に移行した

この記事は書かれてから1年以上が経過しており、最新の情報とは異なる可能性があります

前の記事の WordPress を捨てて Hugo に移行した よりも前に、 ずいぶん前に “Chef を捨てて Ansible に移行” していたのですが、 書いておかないと忘れるので自分用にメモしておきます。

プロビジョニングツールを使い始める前の自分

Chef を利用する前は、 いわゆる プロビジョニングツール というのものを一切使っておらず、 サーバの構築はそのマシンでうまく行くまで何度も行う、 トライアンドエラーのようなサーバ構築を行っておりました。

こういうのって、ちゃんとコマンドラインで入力した内容をメモるなりして きちんと手順化していかないと、 すぐに忘れたりして環境の再現ができなかったりするんですよね。

最初は実機に対して直接作業を行うことが多かったので、 普段慣れない端末への入力だったり、異なる OS でのオペレーションなども相まって 上手くインストールできないと結構なストレスを感じることも多くありました。

そのうち、実機にそのまま試すのではなく、サンドボックスのような自由に試せる環境を 予め用意し、まずはそっちで試してみようと思い、 VirtualBox + Vagrant を導入して 自分のマシン上に対象となる Linux マシンと同一の環境を作り、 先にそちらで試すようになりました。

それと同時に、非常に簡易的ではありますが、 シェルスクリプトベース の手順書のようなものを自分で用意するようになり、 よくある一般的なサーバのセットアップ作業程度であれば 素早く再現できるようになりました。

ここまで来てようやく サーバのセットアップ手順をまとめることへの重要性 に 段々と気づくようになってきます。

Chef を導入し使い始めたころの自分

手元の環境をローカル、セットアップ対象をリモートとすると、 Chef 自体をリモートの方にインストールする必要 があったのですが、 Vagrant のプラグインである vagrant-omnibus を利用して 初回起動時に自動的に Chef をインストールできたことでだいぶ楽できました。

Chef の Cookbook と呼ばれる手順書のファイル群を自分で書くか、 あるいは https://supermarket.chef.io/ などで公開されている サードパーティ製の Cookbook を利用するなどして、 シェルスクリプトベースで書かれていた秘伝のタレになりつつあった手順書を なんとか汎用化していこうと思い、少しずつ置き換えを進めていきました。

みんなが当たり前に行う一般的な手順であればあるほど、 同じ Cookbook を使うはずなので(ユーザーの作成や Web サーバのインストールなど)、 こういったよくある Cookbook は可能な限り多く使われているサードパーティ製を使い、 可能な限りレールから逸れないようにしようと思い、 サードパーティ製を積極的に利用していきました。 (もちろん無条件に信用したわけではなく、利用するものはきちんと中身を吟味したうえで利用しています)

用意さえできれば、あとはコマンド1つで全部整うのは正直気持ちが良いですね。 手元の Vagrant 環境と、VPS 環境とで環境変数を括り出し、 異なる環境で同じ Cookbook が正しく動作するととても清々しいです。

Chef の Cookbook は debian 系がほとんど

運用し始めると、公開されているサードパーティ製の Cookbook は そのほとんどが debian 系 だということに気づきます。

実際 debian 系の方が世界ではシェアが多く、 逆に日本だけが特殊のようで(要出典、Web サーバに限った話ですかね?) Red Hat 系の方が多いようです。 ちなみに CentOS も Red Hat 系に含まれます。

もちろん利用の多いサードパーティ製の Cookbook は debian 系と Red Hat 系とで きちんと処理を分けて書かれているのですが、 中にはおまけ程度にしか用意されていない or そもそも debian 系しか用意してない といったものもあり、かゆいところに手が届かないケースもたびたび出てきました。

アップデート地獄

運用がしばらく続くと、個々の Cookbook でアップデートが起こります。 それ以前に各種ミドルウェア、アプリケーションにおいてもアップデートは当然起こりえます。 そうなると Cookbook でバージョンの差異などが吸収しきれなくなってきて、 プロビジョニングが通らなくなるケースが出てきます。

問題はある程度見えていて、直接リモートのサーバを直せばすぐ解決するのですが、 手順としてまとめられているので、「直接手を出したらだめだ、手順書の意味がない・・・」と ぐっとこらえて Cookbook の方をちまちま修正する日々が続きます。

Ruby からくる記述の多様性

プロビジョニングツール以外でも、変更があったときにフックとして あれを行うといった処理がよくあるかと思いますが、 Chef においても同様の処理が用意されてます。

ただ、色々と利用していくうちに、記述の仕方が数多くあり、 かなり煩雑になってきてしまい若干混乱をきたしてしまってました。 まあ僕が整理して書けてないだけなんですが、整理する気が段々起きなくなってくるんですよね・・・。 変更があったときにフックしたいだけなんですけどね・・・。

Chef Zero ってなんぞ・・・

たぶん僕が使い方を完全にわかってないせいだと思うのですが、 一時期「これからは Chef Zero だ」みたいな風潮(?)の高まり(?)があって、 僕も空いたタイミングで重い腰をあげて Chef Zero に移行してみました。

結論からいうとそのまま移行せずに使ってれば良かったなーという印象です。 Chef Zero があれば Chef Server が不要でうんぬんかんぬんとか、 僕はただシェルスクリプトの手順書を置き換えたかっただけなんですけどね・・・。

運用していくと Chef への不満が徐々にたまる

不満をまとめるとこんな感じです。

Chef 使ってる方から見ると色々とお叱り受けそうな感じですが、 一言でいうと 僕にはオーバースペックすぎた んじゃないかと・・・。 (大企業でサーバたくさんあって、という状況でルール定めてやる分には非常に良いと思います)

不満はたまれども、サーバは動いているので保守しなくてはなりません。

とある日、急ぎでこれを追加でインストールしなくてはいけない、といった状況が生まれ、 時間もなく止むを得ず 直接ログインしてコマンドを叩く ことに。

はい、禁断の一手。

その日以降、Chef コマンドは叩かれなくなり、 いよいよ代用のプロビジョニングツールを探すことになりました。

Chef を捨てて Ansible に移行した

ようやく Ansible の話に入っていくわけなんですが、 Ansible の良いところは以下かなーと思っています。

Chef の Cookbook に対して、Ansible の手順書のファイル群は playbook と呼ばれるのですが、 これが YAML で出来ており、とてもシンプルにまとまってすっきりします。

これは YAML だから良いというよりも、設定ファイルであるからこそ、 用意された記述方法しか許されないという点がシンプルさに繋がっているかと思います。 (YAML が素晴らしいとは言ってません。) Ansible でフックしたい場合は、 notify と書くしかありません。

Chef の時は debian 系しか用意されてない場合もあってつらかったのですが、 Ansible では yum モジュールと apt モジュールのそれぞれを用意しており、 Red Hat 系では yum モジュールを普通に使えば良いので、 そもそも playbook は最初から別モノになります。 無理に汎用化されてないので、逆に利用しやすい かなと思います。

あとセットアップ対象のリモートマシンに何もインストールせず、 SSH だけ動けば OK という プッシュベース なのが非常に楽でした。

一方でローカルに若干インストールしづらいデメリットも

リモートには Ansible をインストールする必要がない一方で、 ローカルには当然インストールする必要があります。

これが若干めんどくさかったのですが、 記事を書いている時点で Ansible 2.0.1.0 だったんですね。 (インストールした頃は 1.9 だったっけか) このバージョンは、現時点での最新バージョンである 2.1 ではなく、 2.1 で入った新機能を使いたくもあったので、 Python のパッケージの依存関係に若干はまりつつも個別にインストールしました。

Ansible って、利用するモジュールによって追加でパッケージが必要なものもあるので そのあたりは使っていて注意かもしれませんね。 その辺の詳しいことは各モジュールのページに書いてあります。 https://docs.ansible.com/ansible/list_of_all_modules.html

(おまけ)ここから ansible 2.1 が普通に提供されてたら関係ない話

現時点で Homebrew に 2.1 が提供されていなかったので 以下を元に(当時の)最新版を入れました。

http://docs.ansible.com/ansible/intro_installation.html#latest-releases-via-pip

2016/11/21追記

ansible 2.2 が Homebrew に来てました。 これでクソみたいなインストール作業に時間を割かなくてすみますね!

% brew info ansible ansible: stable 2.2.0.0 (bottled), HEAD Automate deployment, configuration, and upgrading https://www.ansible.com/ Not installed From: https://github.com/Homebrew/homebrew-core/blob/master/Formula/ansible.rb ==> Dependencies Build: pkg-config ✘ Required: libyaml ✘, openssl@1.1 ✘ ==> Requirements Required: python ✔

2016/11/21追記ここまで

ちなみに Docker 周りは Ansible 2.1 でサポートがかなり強化されたので、 今後は 2.1 以降を入れた方が良いかもです。

docker_container モジュール、いいよ。

https://www.ansible.com/blog/ansible-2.1

確かこんな感じで入れたと思います。(メモが残ってたので多分これかと)

$ curl https://bootstrap.pypa.io/ez_setup.py -o - | python
$ sudo easy_install pip
$ sudo pip install ansible
PyYAML-3.11 ansible-2.1.0.0 cryptography-1.4 jinja2-2.8 paramiko-2.0.1 pycrypto-2.6.1

ただ、これだと CentOS7 など一部で問題が起きるため、 ここからさらに paramiko のバージョンを 2.x から 1.x にダウングレードする必要があります。 (ややこしいのですが、ローカルに入れた ansible の依存パッケージのバージョンで 一部のリモートの環境にて問題が起きるケースがあるようです)

sudo pip install paramiko==1.17.x

みたいな感じですかね。

詳しくは http://www.paramiko.org/changelog.html#2.0.0, http://www.paramiko.org/installing-1.x.html などをご確認ください。

あるいはリモート環境に直接アクセスして、ローカルの ansible の環境に合うように リモートの sshd_config の設定などを適宜見直すといった方法でも問題ないかと思います。 (が、リモートに接続して設定変更するのは本末転倒な気がするので僕はやりません)

Python のパッケージの依存関係、面倒で嫌になりますね・・・。 (対象マシンのパッケージの依存関係を解決したいがために ansible 経由で Docker を入れようとするも、 ansible のローカル側のパッケージ依存に悩まされるというこの本末転倒感・・・。)

まとめ

まだ運用し続けているわけではないので、 これから問題が出てくる可能性も十分あるのですが、 今のところ快適に利用できています。

一応、Chef でやっていたローカル、リモートで変数を括り出して 同じ playbook でプロビジョニングする、といった程度は問題なく出来ています。 (ユーザー作成や SSH ポート番号の変更など) そのうち知見たまったらまたアウトプットしたいですね。

ちなみに、これは Chef でも Ansible でも両方に言えることですが、 手作業でインストールできない人がプロビジョニングツールを使ったら あら不思議、インストールできちゃったわ!なんてことはない ですし、 あったとしても後でトラブルで死ぬだけなので、ちゃんと元のコマンドを理解して 用法用量を守って正しくお使いください。

参考URL

この記事は書かれてから1年以上が経過しており、最新の情報とは異なる可能性があります

もし記事内に誤りなどございましたら、 @girigiribauer までご一報いただけると助かります。