やりたいこと
Capistranoで
$ cap staging deploy
$ cap production deploy
という感じでステージ名を指定してそれに応じて設定を変えるということができますが、それと同じことをAnsibleでやりたい、という話です。
インベントリファイルとgroup vars
Ansibleはステージごとのホスト一覧を -i
オプションでインベントリという概念で指定することができます。
$ ansible-playbook -i hostlist playbook.yml
このインベントリにGroup Variablesという形で変数定義をすることができます。
hostlist
[atlanta]
host1
host2
[raleigh]
host2
host3
[atlanta:vars]
some_server=foo.southeast.example.com
halon_system_timeout=30
self_destruct_countdown=60
escape_pods=2
このGroup Variablesの機能を使うとステージごとにイベントリファイルを分けることで冒頭のことを実現できます。
$ tree
.
├── staging_hosts
├── production_hosts
└── playbook.yml
$ ansible-playbook -i staging_hosts playbook.yml
$ ansible-playbook -i production_hosts playbook.yml
all:vars と vars_filesをうまく使う
と、ここまではhow-to-arrange-inventory-stage-vs-productionに書いてあるのですが、もうちょっとつっこみたい。
上記の情報だと自分的に悩んだのが、
- group毎ではなくてステージ共通の設定を各
[group:vars]
に書くのダルい - Best Practiceにあるように変数はymlでまとめたい(group_vars,host_varsよりもむしろステージ単位の変数のほうがよく使う気がするのだが・・・)
ということで試してできたのがこちら。
$ tree
.
├── staging_hosts
├── production_hosts
├── playbook.yml
└── vars
├── staging.yml
└── production.yml
stagingレベル
staging_hosts
[web]
stg1.hoge.com
stg2.hoge.com
[all:vars]
stage=staging
staging.yml
---
val1=hogehoge
productionレベル
production_hosts
[web]
web1.hoge.com
web2.hoge.com
[all:vars]
stage=production
production.yml
---
val1=fugafuga
playbookで vars_files にstage変数を使う
playbook.yml
- hosts: all
vars_files:
- vars/{{ stage }}.yml
ポイントは、
- インベントリに[all:vars] と書くとすべてのグループに対して共通な設定ができる
- stage という変数をインベントリに定義
- stage変数を vars_files で指定するファイルパスに使用する
というところです。