Ansibleのベストプラクティスに学ぶ
しばらく更新が開いてしまいました。
今年の前半はDockerやKubernetesに追いかけていたのですが、
近頃は仕事でAWS*1とAnsibleを中心に使っているため、関心もそちらに寄ってきています。
今回はAnsibleのベストプラクティスについて勉強したので書いていきます。
Ansibleのベストプラクティスとは
「ベストプラクティスとは大きく出たな 」
「そもそも何のベストプラクティスなんだろう?」
とお思いの方もいるかも知れませんが、 Ansibleでは公式でベストプラクティスを公開しています。
Best Practices — Ansible Documentation
こちらを見てみると分かる通り、ファイルやディレクトリの構成のようです。
Ansibleではご存知の通り様々なファイルが使用されます。
大きく分けるとプレイブックとインベントリの2つが中心ですが、細かい挙動などをファイル毎に分けていくとかなりの数に分類されます。
それをうまく活用しつつ、キレイに配置しよう、というのがベストプラクティスと呼ばれるものだと思います。
公式サイトでは2種類のベストプラクティスを紹介しています。
ベストプラクティスな構成を作ってみる
ドキュメントを読んでいても(英語だし)いまいちピンとこなかったので、
ベストプラクティスを真似た構成を作ってみました。
手前味噌ですが、練習用も兼ねてリポジトリを作っています。
github.com
ちなみに今の仕事でも商用/検証環境が別れているのでAlternative Directory Layoutのほうをベースにしています。
インベントリの構成
ディレクトリ構成は以下のようになっています。
. ├── inventory │ ├── production │ │ ├── group_vars │ │ │ ├── all.yml │ │ │ ├── app.yml │ │ │ ├── db.yml │ │ │ └── web.yml │ │ ├── hosts │ │ └── host_vars │ │ └── webserver2.yml │ └── staging │ ├── group_vars │ │ ├── all.yml │ │ ├── app.yml │ │ ├── db.yml │ │ └── web.yml │ ├── hosts │ └── host_vars
インベントリファイルの内容は以下のようです。
$ cat inventory/production/hosts [web] webserver1 webserver2 [app] appserver [db] dbserver
変数はすべてgroup_vars
, host_vars
に記載しています。
ProductionとStagingで同じようなグループ構成にしつつ
IPアドレスやパラメータの違いを*_vars
で吸収させることで、
共通のPlaybookを使うことができるのが良さですね。
各種の変数には強弱というか優先順位があります。
Variables — Ansible Documentation
思っている以上に数があって覚えるのは大変そうですし、よく使うのはこの辺りです。*2
↑ 弱い
* role defaults
* inventory group_vars/all
* inventory group_vars/
* inventory host_vars/
* include_vars
↓ 強い
role defaults
は最も弱い変数なのでデフォルト値として、他の変数に上書きされたりするんですね。
でも、バージョンアップの対応として高いバージョンをhost_vars→group_varsと段階的にバージョンアップしていき、
確証が取れたら最終的にdefaultsのバージョンを上げる、というような使い方もできます。
include_vars
などの強力な変数はほぼ上書きできないので、もはや定数みたいな扱いですね。
こういった変数の構成はプログラミングのようでInfrastructure as Codeしている感があって好きですね。
ロールの構成
ロールを作っているうちに「大した仕事させない割にはすごいファイル数だな…」と感じました。
Tipsですが、ロールを作るのにいちいち特定のディレクトリ名を作るのが面倒だと思い調べたところ、
ansible-galaxy init
というコマンドを知りました。
$ ansible-galaxy init common/hoge --offline - common/hoge was created successfully $ tree common/hoge/ common/hoge/ ├── defaults │ └── main.yml ├── files ├── handlers │ └── main.yml ├── meta │ └── main.yml ├── README.md ├── tasks │ └── main.yml ├── templates ├── tests │ ├── inventory │ └── test.yml └── vars └── main.yml 8 directories, 8 files
上のように、ロールで使われるディレクトリを1コマンドで一気に作ってくれます。
(デフォルトではAnsible Galaxyのサイトを一度見に行くようなので--offline
を付けることでローカル実行で早く終わるようです)
ちなみにリポジトリの方はまだ挙動を知る段階なので見やすさ重視で不要なディレクトリ/ファイルは削除してます。
でもtests
とか気になるのでいずれ触ってみたいと思います。*3
最後に
今回Ansible公式のベストプラクティスを紹介しましたが、
Qiitaなどで見ると俺的ベストプラクティスがいくつか紹介されています。
環境によっても使い方は様々だと思うので、実環境での使いやすさや好みでベストな構成を考えるのも良いのかもしれません。
私も「これだ!」という構成を見つけるまでは公式のベストプラクティスをベースで作っていきたいと思います。*4