Ansibleを使う上での教訓

# はじめに
「[Ansible Advent Calendar 2017](https://qiita.com/advent-calendar/2017/ansible) 」の12/7(木)の記事です。

この記事では、私が業務でAnsibleを使っている中で得た、教訓となるようなポイントを紹介していきます。普段から使ってる人からしたら当たり前じゃん！って思うことも多々書いてあると思いますが、暖かい目で見守っていただけたら幸いです。

# 1. 対象がAnsibleで管理できる状態か調べておこう
Ansibleといえばお手軽に実行できるのが1つの魅力です。

(例外は有るが)基本的な要件として、Ansible実行サーバと実行対象サーバに **Python** が入っており、Ansible実行サーバから実行対象サーバに **ssh** さえ繋げれば実行できます。(細かい要件を知りたい方は公式ページでチェック → [control & managed machine requirements](http://docs.ansible.com/ansible/latest/intro_installation.html#control-machine-requirements))

「じゃあLinuxならPython入ってるしSSH繋がるからAnsibleで管理できるんだ！」
そう思って古いバージョンのRHELに実行しようとしたら、なんとエラーが！
この記事で詳しくは書きませんが(いつか別で書くかな…)、必要なモジュールが入っていなかったり、yumのバージョンが古かったりすると、たとえPythonが入ってたとしても実行できない場合があります。

私はまだWindowsに対して実行したことありませんが、[Windowsでも事前準備](https://qiita.com/yunano/items/f9d5652a296931a09a70)が必要だったりするみたいです。

いざ実行しようと思ったときに繋がらない！ってなるのは精神的によくないので、実行できることは最低限確認しておきましょう。

# 2. まずはDry runで実行しよう
新規で構築するサーバなら、何か失敗してもたいして問題にはならないと思います。

しかし、すでに稼働しているサーバに対してAnsibleを実行する場合は、既存の何かに影響を与えてしまう可能性があります。

教訓1の接続確認もそうですが、まずは `--check --diff` をつけてDry runで実行してみましょう。それで実行できることを確認し、何が変更点となるのかもチェックしておきましょう。

# 3. Ansibleのバージョンアップは慎重にしよう
Ansibleは年に数回のペースで新しいバージョンが[リリース](https://github.com/ansible/ansible/releases)されています。新しいバージョンになればモジュールの追加やbugfixなどがあるため、すぐにでもバージョンをあげたいと思うことでしょう。

が、待ってください！すぐにバージョンアップをするとこれまで使っていたPlaybook/Roleが使えなくなってしまう可能性もあります。

## 3.1 Deprecation Warningに対応していない問題
Ansibleを実行していると **Deprecation Warning** という表示を見たことある方もいるのではないかと思います。これは、近いバージョンで今の記法/モジュールの使い方では動作しなくなりますよ、という警告です。

この警告が出てる間に関しては問題なく動作しますが、Ansibleのバージョンをあげたら動かなくなってしまう、ということがあります。実際私は2.1から2.2にあげたらへんでそういう事象に遭遇しました。

なので今実行しているPlaybookで **Deprecation Warning** が出ている記法/モジュールなどに関しては、バージョンアップに更新情報をチェックしたり、別環境で試したりした方が良いでしょう。

## 3.2 エンバグ問題
Ansibleに限った話ではないですが、コーディングをしていれば当然bugが混入します。検証時には正常に動作していたのに、いざ本番で使っていたらbugを踏んでしまった…なんてこともあります。

私の現場ではAnsible2.2から2.3にあげたときに、includeがリソースを膨大に消費する、というbugを踏み、あえなく2.2に戻すということを経験しました。

未知のバグに関しては事前に見つけようがないですが、「これまで動いてたのになんで動かなくなったの！？」っていうことも往々にしてありえるので、そういう事象もあるということを心の片隅に留めておいてください。

そしてバグを見つけたら、まずはGithubのissueで同じ状況になっている人がいないか調べてみましょう。

# 4. 機密情報の扱いには気をつけよう
Ansibleのtemplateには、どうしても機密情報(パスワード情報など)を入れなければいけない状況が出てくると思います。例えばパスワードであったりAPIキーなどがあると思います。

そのような機密情報ををvarsファイルなどに書いたままGitなどにアップロードしてしまっては、機密情報が丸見えになってしまいます。また、Ansible実行時に「--diff」オプションをつけていたりすると、実行時のログにパスワードが出力されてしまいます。

なので、機密情報の書いてあるファイルはansible-vaultを使い暗号化するようにしましょう。また、実行ログに関してはタスク部に「no_log: yes」オプションをつけるなりして、機密情報がログに出漁されないようにしましょう。

# 5. Role/Playbookの設計はしっかり行っておこう
私の現場では複数のチームでroleの開発を行ってきました。それぞれのチームが独立して開発を進めていったがために、それぞれのroleは独自のルールに則って作られていました。
最終的にそれらを一緒に使おうとしたとき、同じ値を持つ変数が違う変数名で定義されていたり、変数がhost_varsやgroup_varsに分散していたると、とてもわかりづらい状態となっていました。

そういうことが起こらないようにある程度のルールはチーム間で共有しておくことが重要だと感じました。変数の命名規則やコーディングルールなどは、開発を行っていれば当たり前に行っていると思いますが、Ansibleでは変数の定義場所が独特だと思うので、その辺もしっかり決めておくべきだと感じました。

以下は決めておくべきルールの一例です。

- 変数の命名規則
    - 変数名の最初にはrole名をつける
    - 変数は小文字で統一する
    - 変数名の単語と単語の間はアンダーバーで区切る
    - 何を表す変数なのか一目でわかる単語を使う
    - 変数にローマ字表記の単語は使わない　など
- 変数の定義場所
    - role内で利用する全ての変数はdefaultsに定義する
    - ホストごとに可変の値はhost_varsに定義する
    - 環境単位(開発環境、本番環境など)で変わる値はgroup_varsに定義する
    - 一時的に上書きしたい変数はextra_varsを使う　など
- inventoryの分割単位
    - 環境単位(開発環境、本番環境など)で分割
    - サーバ種別(Webサーバ、Batchサーバなど)で分割
    - 導入するミドルウェア(Apache、Tomcatなど)で分割　など
- その他コーディング規約
    - 各タスクにnameは必ずつける
    - インデントはスペース2つで統一する
    - モジュールにパラメータを渡す時は1行に1パラメータずつに書く
    - 文字列はダブルクォートではなくシングルクォートで囲む
    - boolean型はyes/noではなくTrue/Falseに統一する　など

# 6. templateにあまり複雑な処理は入れないようにしよう
jinja2テンプレートでは、一般的なプログラム言語で使われるループや条件分岐など、[基本的な処理](http://jinja.pocoo.org/docs/2.10/)は記述することができます。従ってこの中で様々な処理を書くこともできますが、可読性やメンテナンス性が落ちてしまうため (jinja2のコードが見づらいと思うのは自分だけ…？)、何か処理が必要になるものは **独自フィルタ** を作って切り分けておいたほうがいいと感じました。

フィルタを作る、というと難しそうでとっかかりに抵抗があるかもしれませんが、そこまで恐る必要はありません。決められたフォーマットに従って関数を定義するだけでお手軽に作ることができます。
[【Ansible】独自Plugins－filter_plugins編－](https://qiita.com/komattaka/items/cee55c5473ad9bcc96b6)


# 7. shell/commandモジュールに頼り過ぎないようにしよう
何かやりたい操作があるとき、command/shellモジュールを使えば基本的には実現できてしまいます。しかし、それではAnsibleが売りにしている冪等性が担保できません。

自分がやりたいと思ったことは、すでに他の人がやりたいと思っていたりすることが大半です。なので、まずはGoogle先生に聞いてみることをオススメします。

ここ最近では日本でのユーザも増えてきており、日本語で紹介しているサイトも多くあるため、英語が苦手な方でもそこまで心配しなくても大丈夫です。（もちろん公式の英語のドキュメントを見るのが1番良いのですが！)

# おわりに
昨年はなかなか埋まりの悪かった [Ansible Advent Calendar 2016](https://qiita.com/advent-calendar/2016/ansible) でしたが、今年はあっと言う間に埋まって驚きました。1Ansibleユーザとして、これからもAnsibleが広まってユーザが増えてくれれば良いなと感じました。