2015/09/29

AnsibleとServerspecでインベントリファイルを共通化した

去年の明け頃からAnsibleを使い出して、去年の春ごろから仕事でも充分使えると判断して、今はサーバを構築するのは全てAnsibleでPlaybookを書いて構築→保守という流れが確立しています。とはいえ、他社と共同管理であるサーバも多く、構築完了から時間が経過した後に最初に書いたPlaybookを実行して、Playbookに反映されていない変更が巻き戻るという管理上の問題がありました。`ansible-playbook --check`での検査で何故かChangedになるタスクがあったり(これは僕の書き方が悪いのかも)して、テスト目的ではServerspecを使う事を検討し、実際に使ってみる事にしました。

結論としては、Serverspecは充分使えると判断してAnsible Playbookで実行した内容のテストをServerspecで記述して、構築完了後〜何か変更を加えるときに毎回`rake`を実行するという形が合理的であるとの解を得ました。

となると次は、ディレクトリ名からホスト名を得るServerspecにAnsibleのインベントリファイルを読込んで、対象とするホスト定義を共通化したいと思いました。最終的な目的は、Ansibleのインベントリファイルのみでホスト定義をしてServerspecもそれを読み、AnsibleのBest Practicesに従ったディレクトリ構造の中にServerspecのテストコード用ファイルを入れる事で、それを達成する為にRakefileを改造しました。

make-server

自分で使うAnsibleのロールやPlaybookの動作テスト用にいつでもVagrant環境を準備出来るフレームワーク的な何かをmake-serverという名前でGitHubに置いてまして、今回はそれを大改造しました。

改造項目

  1. ansible/rolesってディレクトリ名を変える→server/roles
  2. roles/以下を構築手段別に再分類する→roles/{rpm,pkg,deb,src,env}とか
  3. rake実行時にインベントリファイルを読込む→Rakefile改造とlib/ansible_helper.rb作成
  4. roles/ロール名/spec/*.rbに入れたテストコードをrakeで実行→lib/ansible_helper.rb作成

改造後

全体のディレクトリ構造

Gistに書いたのですが、以下のような構造になりました。

Rakefile

たぶんですが、同じ目的を達成するソフトウェアは探せば何処かにあると思います。が、シシマイ(p5-Sisimai)のRuby化をするにあたってRubyに慣れておきたいという意図もあり、結局は自分でRubyを学びつつ、改造する事にしました。改造した内容は、
  • .default-inventoryfileの中身またはENV['INVENTORY']からインベントリファイルを決定
  • roles/ロール名/spec/*.rb以下のファイルを探してターゲットを作る
  • lib/spec_helper.rbに渡す環境変数を作る
  • ターゲット名はspec:インベントリに書いたホスト名:ロール名って構造にする
ってところです。

lib/ansible_heler.rb

Rakefileから読込まれるファイルとしてansible_helper.rbってのを作りました。目的は
  • Ansibleのインベントリファイルを読込みspec_helper.rbに渡すテスト対象ホスト名を取得
  • spec/*.rbでroles/ロール名/vars/main.ymlを読込んで変数を参照する
  • spec/*.rbでgroup_vars/の該当するファイルを読込んで参照する
あたりです。とはいえ、mx[0:4].nyaan.jpみたいな形式のホスト定義は未だ読めないので、さっさと直したいところではあります。この問題解決を後回しにしたのは、普段Ansibleを使う目的がWeb,Mail,DBをそれぞれ1台作るってケースが多くて、Webのクラスタを5台作るようなケースが殆ど無いので、1台ごとにホスト名を冠したディレクトリを作ってPlaybookもインベントリファイルもそのホスト専用に書く事が多いからです。

rake -T

改造したRakefileと作ったlib/ansible_helper.rbによって、`rake -T`を実行すると次のようなターゲットが構成されるようになりました。
% rake -T ⏎
rake spec:mx:all            # Run all the serverspec tests to mx
rake spec:mx:ansible-env    # Run tests for Ansible environment
rake spec:mx:bootstrap      # Run serverspec tests to mx(bootstrap)
rake spec:mx:src/dovecot    # Run serverspec tests to mx(src/dovecot)
rake spec:mx:src/opensmtpd  # Run serverspec tests to mx(src/opensmtpd)
rake spec:mx:src/perl       # Run serverspec tests to mx(src/perl)
`rake`を実行すると上記のターゲットが全て実行されますし、OpenSMTPDのテストだけするなら`rake spec:mx:src/opensmtpd`を実行するという使い方になります。

Makefile

おっさんなのでMakefileとの付き合いも長く、Makefileのほうが好きです。自分が使う目的で、なるべくAnsibleとServerspecを使う為の環境が楽に作れるように、決まりきった作業をなるべく短いコマンドで実行出来るようにいくつかターゲットを定義しています。
  • make login → Vagrant仮想マシンにSSHログインする
  • make up, make down → Vagrant仮想マシンを起動・停止する
  • make server → AnsibleとServerspec実行に必要なファイルをcloneしたmake-serverからコピーする
  • make ロール名-role → ロールのディレクトリ構造(tasks,vars,templates,filesとか)を作る
  • make *-box → Vagrant仮想マシンを作ってVagrantfileや専用インベントリファイルを作る
  • make test → rake spec:*を実行する
  • make build → ansible-playbook -i server/インベントリ server/Playbookファイルの長いコマンドを実行する
何より`make`ってコマンドは打ちやすいので気に入ってます。

今後のmake-server

make-serverに置いてる全てのロールにServerspecのテストコードを入れているわけではないので、書き上がり次第追加する予定です。

Playbookも今のところ、ソースビルドするものが中心で、毎回コンパイルオプションをメモ書きから調べるのが面倒なので、Playbookにしておくって程度の充実度です。

Serverspecのテストやロールが充実してきたら、Infratasterのテストもいれようかと思っていまが、とりあえずは対象サーバを構築するのに最低限必要なファイルとPlaybookとテストコードが一元管理できる状態には出来たので一旦満足したとこです。

0 件のコメント:

コメントを投稿