ここが便利だよAnsible

急遽エントリが空いたので投稿します。

# はじめに

前回、以下のエントリにてAnsibleの使いづらいところを紹介しました。
[ここがヘンだよAnsible (ハマりどころと対策について) | Ansible Advent Calendar 2015 22日目](http://qiita.com/unchemist/items/9da2d92f026c10fd38f7)

その中で、それでもAnsibleを使い続けます、とお伝えしたのですが、Ansibleを使っていてこれは便利！と思ったところを紹介します。

私はchef-soloをずっと使っていたので、特にchef-soloとの比較になります。chef-serverすら使ったことがないので、server-clientでプロビジョニングを行うものとしては経験がありません。もし他のプロダクトでもできるよっていうことであれば、優しく指摘してください…。

<img width="200px" alt="ansible_logo_black_square.png" src="https://qiita-image-store.s3.amazonaws.com/0/16458/b74e239a-f9e9-060c-3817-8707445e92b8.png">

# 便利な特徴

## 運用パターンに応じて実行taskを絞ることができる : tag機能

tag機能とは、個々のtaskに対するラベル付けのようなものです。
これが便利すぎます。

### tag機能とは

[Tags — Ansible Documentation](http://docs.ansible.com/ansible/playbooks_tags.html)

例えば、以下のようなtaskを作ったとします。

```yaml:tasks/main.yml
- 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のみを選んで実行することができます。

例えば上記の例だと、以下のように書いてみます。

```yaml:tasks/main.yml
- 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の入れ替えだけ行いたい場合は、実行時に以下のようにします。

```bash:configタグのtask実行
ansible-playbook example.yml --tags="config"
```

ここでは、`config`というtagが指定されているものだけ実行しています。
tagの便利なところは2つあります。

* 複数指定できる  
上記の例のように、1つのtaskに複数のtagを指定できます。
* 特定のtag"以外"のtask、という指定もできる  
`--skip-tags` を指定することによって、特定のtag以外を実行することもできます。

```bash:configタグ以外のtask実行
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](http://docs.ansible.com/ansible/intro_dynamic_inventory.html)
[AnsibleのDynamic InventoryでAWS EC2管理](http://qiita.com/teru1000/items/d8d292186aee6c631ee0)

# Ansible 2.0でさらに便利に！

実は、それでも若干使いづらいと思ったことが何点かあったのですが、見事にansible 2.0でそれが解消しそうで、非常に期待しています。

[Ansible 2.0 変更点まとめ](http://qiita.com/yuta_h3/items/30dcfd939cb13b7e24fa)

主だったところで言うと、

* block機能
* strategy plugin

でしょうか。
詳細は上記リンクをご覧ください。

# 最後に

こうして見ると、ansibleは**既に動いているシステムをいかに取り込むか**というところで、非常に気を配ってくれていると感じます。一から作るのであれば何でもいいのかもしれませんが、既存の資産や運用をそのまま流用することができるという意味で、ansibleは大きなメリットがあると思いました。

皆様も、ansibleで良いお年を。