急遽エントリが空いたので投稿します。
はじめに
前回、以下のエントリにてAnsibleの使いづらいところを紹介しました。
ここがヘンだよAnsible (ハマりどころと対策について) | Ansible Advent Calendar 2015 22日目
その中で、それでもAnsibleを使い続けます、とお伝えしたのですが、Ansibleを使っていてこれは便利!と思ったところを紹介します。
私はchef-soloをずっと使っていたので、特にchef-soloとの比較になります。chef-serverすら使ったことがないので、server-clientでプロビジョニングを行うものとしては経験がありません。もし他のプロダクトでもできるよっていうことであれば、優しく指摘してください…。
便利な特徴
運用パターンに応じて実行taskを絞ることができる : tag機能
tag機能とは、個々のtaskに対するラベル付けのようなものです。
これが便利すぎます。
tag機能とは
例えば、以下のようなtaskを作ったとします。
- name: install application
yum: name=application state=present
- name: deploy config
template: src=templates/app.conf.j2 dest=/etc/application/app.conf
- name: deploy scripts
template: src=templates/{{ item }}.sh.j2 dest=/usr/local/application/{{ item }}
with_items: "{{ script_list }}"
- name: start application
service: name=application state=started
よくあるような、
- yumでインストール
- configの入れ替え
- スクリプトの配置
- アプリケーション起動
の例です。
これに対して、以下のようなケースはないでしょうか?
- プロビジョニングは行いたいけど、反映は後にしたいので再起動だけしないでおきたい
- 逆に、あとで再起動だけ行いたい
- serverspecのテストだけ実行したい
tag機能のメリット
tag機能を利用することによって、特定のtaskのみを選んで実行することができます。
例えば上記の例だと、以下のように書いてみます。
- name: install application
yum: name=application state=present
tags:
- install
- name: deploy config
template: src=templates/app.conf.j2 dest=/etc/application/app.conf
tags:
- install
- config
- name: deploy scripts
template: src=templates/{{ item }}.sh.j2 dest=/usr/local/application/{{ item }}
with_items: "{{ script_list }}"
tags:
- install
- script
- name: start application
service: name=application state=started
tags:
- install
- start
上記は極端な例ですが…例えばconfigの入れ替えだけ行いたい場合は、実行時に以下のようにします。
ansible-playbook example.yml --tags="config"
ここでは、config
というtagが指定されているものだけ実行しています。
tagの便利なところは2つあります。
- 複数指定できる
上記の例のように、1つのtaskに複数のtagを指定できます。 - 特定のtag"以外"のtask、という指定もできる
--skip-tags
を指定することによって、特定のtag以外を実行することもできます。
ansible-playbook example.yml --skip-tags="config"
tag機能の注意
もっとも、安易にtag運用を行うのではなく、考えるべきところもあります。ここまで言っておいてなんですが、tag機能を使うと運用が複雑になります。どんなときに何を動かすか/動かさないべきかを考えて設計する必要があるためです。
例えば、上記の例でscript配置だけを動していると、いつか「本当はconfig配置も一緒に行うべきだった」というケースが出てくるかもしれません。担当があなただけであれば把握できると思いますが、チームで行う以上は連携が必要になってしまいます。
そんなとき、tagで動いたり動かなかったりするくらいなら、冪等性に任せて頭から全部実行する方が楽に決まっています。ansibleが勝手に変更がない箇所はskipしてくれるからです。
それでもtag機能を活用したいのは、システムの運用が全てカバーできるからです。
最初に記載した通り、「再起動だけ」とか「〜〜だけ」という運用が現在あるのであれば、そのパターンごとにtagを付ければよく、逆に運用パターンごとにplaybookファイルを量産するという苦痛から解放されるというメリットがあります。そういう意味では、現在ansible化していない状態で、どれくらいの運用パターンがあるのかを考える必要があります。
品質を一定に保ちやすい : yaml形式による定義
chefでいうrecipe部分はrubyによって記述されます。chefのルールに従って書けば簡単ですが、実態はrubyなので、rubyのコードを書けば何でもできます。
一方、ansibleはyamlです。記法でしかないので、逸脱したことはできません。記載する以上は(基本的には)yaml形式に則って書くしかありません。
複数人で開発する以上、コードの品質は一定に保ちたくなります。ファイルがrubyであれば、ruby上級者/初心者によってrecipeの品質は大きく異なることが予想されます。一方、yaml形式のansibleは、誰が書いてもほぼ同じ書き方にするしかありません(例外はありますが)。推進する立場から見ると、これは大きなメリットではないでしょうか?
プログラムに慣れた人であれば、逆にその不自由さがストレスにもなるようですが、ansibleは大抵のmoduleがあるのでそれでほとんどはカバーできる気がします。
ホスト一覧を外部から取得できる : dynamic inventory
サーバの構成情報の"マスタ"を、ansibleやchefなどの構成管理ツールが握っているわけではない場合があります。例えば、AWSはapiによってec2インスタンスの一覧を取得することができます。システムによっては、データベースなどにホスト一覧を格納しているケースもあるでしょう。
こうしたケースで、構成管理ツール側でホスト一覧を別途保持しておくのは二重管理になり避けたいところです。情報の同期に問題があった場合、一部に対して動作しないということもありえます。
そうした時に、ansibleのdynamic inventory機能は外部からそのまま構成情報を取得することができます。
既存の資産をそのまま流用できるのは大きなメリットだと思います。
Dynamic Inventory — Ansible Documentation
AnsibleのDynamic InventoryでAWS EC2管理
Ansible 2.0でさらに便利に!
実は、それでも若干使いづらいと思ったことが何点かあったのですが、見事にansible 2.0でそれが解消しそうで、非常に期待しています。
主だったところで言うと、
- block機能
- strategy plugin
でしょうか。
詳細は上記リンクをご覧ください。
最後に
こうして見ると、ansibleは既に動いているシステムをいかに取り込むかというところで、非常に気を配ってくれていると感じます。一から作るのであれば何でもいいのかもしれませんが、既存の資産や運用をそのまま流用することができるという意味で、ansibleは大きなメリットがあると思いました。
皆様も、ansibleで良いお年を。