Differentiate environments with ansible
ansibleでdigitaloceanの構成管理をしている。このときvagrantを使って試しながら本番に適用しているのだが、本番にしか適用したくない設定(mackerel-agentのインストールとか)、開発環境にのみ適用したい設定が出てきた。
それっぽいワードで調べてみたら、group_varsやhost_varsとwhenステートメントを組み合わせる方法が手軽そうだった。
- Multistage environments with Ansible – Ross Tuck
- Inventory — Ansible Documentation
- Conditionals — Ansible Documentation
リンクを参考に以下のような感じでインベントリを設定した。
development
[ponpokopon-vm]
192.168.33.10 ansible_ssh_user=vagrant ansible_ssh_private_key_file=.vagrant/machines/default/virtualbox/private_key
[all:vars]
stage=development
production
[ponpokopon-production]
ponpokopon.me ansible_ssh_user=username ansible_ssh_private_key_file=~/.ssh/id_rsa
[all:vars]
stage=production
プレイブックでは以下のようにwhenステートメントを使いgroup_varsの内容で条件分岐することで、適用先を変えることができる。
- name: mackerel-agent is installed
yum: pkg=mackerel-agent state=installed
when: stage == "production"
tags: mackerel
group_varsについて
インベントリとかグループとかまだあまり慣れてないので整理。
ansibleはインベントリという単位でプレイブック適用先を管理している。
インベントリ1(productionとか)
[グループ1(baseとかwebとか)]
ホスト1(192.168.1.10とか)
ホスト2
[グループ2]
ホスト1
ホスト3
インベントリ2
[グループ1]
ホスト4
ホスト5
[グループ2]
ホスト4
ホスト6
この時、グループで共通の変数を定義することができる。これがgroup_vars。
[グループ1(baseとかwebとか)]
ホスト1(192.168.1.10とか)
ホスト2
[グループ2]
ホスト1
ホスト3
[グループ1:vars]
group1_var1=hogehoge
group1_var2=piyopiyo
そしてこの変数は定義したグループに対してプレイブックが実行された際に参照することができる。ただし、この書き方では環境を示す変数を定義したい場合、グループごとに設定をしないとダメなのでグループが複数ある場合ちょっとめんどくさい。
[グループ1(baseとかwebとか)]
ホスト1(192.168.1.10とか)
ホスト2
[グループ2]
ホスト1
ホスト3
[グループ1:vars]
stage=production
[グループ2:vars]
stage=production
そこでall:vars
を使う。all:vars
は全てのグループに適用される変数なので、結果的にそのインベントリ全体に適用される変数になる。
[グループ1(baseとかwebとか)]
ホスト1(192.168.1.10とか)
ホスト2
[グループ2]
ホスト1
ホスト3
[all:vars]
stage=production
感想
chefの場合は環境ごとの設定はenvironment/{production.json,development.json}
、グループはroles/{web.json,db.json}
、ホストはnodes/{192.168.1.10.json,192.168.1.11.json
}みたいにバラバラのファイルとして存在しているが、ansibleの場合インベントリでまとめて定義されるという違い。
この辺の違いはjsonが辞書型のような形式で、yamlがインデントで構造を表現していることに起因している…のかな?