やりたかったこと
あるアプリケーションのインストールおよびその起動まで一括で行う role を作成し、それを使いまわして system1 と system2 を起動する playbook をそれぞれ作成したい
テストと本番の 2 つのインベントリを用意し, 本番では、system1, system2 をそれぞれスケールアウトする
このとき role で利用する 1 つの変数を以下の 4 種類の組み合わせ分用意しなければならなくなった。
- (system1, テスト)
- (system1, 本番)
- (system2, テスト)
- (system2, 本番)
Ansibleのインベントリファイルでステージを切り替える を参考にインベントリでまとめたがったが、上述 4 種類とも変数定義の中身が違うので利用不可能
解決案
単純な文字列、数字なら何も考える必要はなかった。インベントリ内で vars を定義すればよかった。
[group]
test-server
[group:vars]
inventory_group=local2
ただ、変数をオブジェクト構造にしたかったり、どうしても変数が肥大化したりするので、変数は外出しにしたかった。
結論としては、個人的にあまりいい方法ではないと思うが、Best Practice - How to Differentiate Stage vs Production に書いてあるインベントリファイル内で、[<group>:children] の項目を作ることで解決した。
以下、チラシの裏をまとめておこうと思う。
tree
.
├── inventories
│ ├── group_vars
│ │ ├── local1_group1.yml
│ │ ├── local1_group2.yml
│ │ ├── local2_group1.yml
│ │ └── local2_group2.yml
│ ├── local1.yml
│ └── local2.yml
└── playbooks
└── test1.yml
inventories
[group1]
test-server11
[group2]
test-server1A
[local1:children]
group1
group2
[local1_group1:children]
group1
[local1_group2:children]
group2
[group1]
test-server21
test-server22
test-server23
[group2]
test-server2A
test-server2B
test-server2C
[local2:children]
group1
group2
[local2_group1:children]
group1
[local2_group2:children]
group2
vars
inventory_group: local1_group1
inventory_group: local1_group2
inventory_group: local2_group1
inventory_group: local2_group2
playbooks
- hosts: group1
connection: local
gather_facts: no
tasks:
- name: "DEBUG | inventory group1"
debug: msg="{{ inventory_group }}"
- hosts: group2
connection: local
gather_facts: no
tasks:
- name: "DEBUG | inventory group2"
debug: msg="{{ inventory_group }}"
results
$ ansible-playbook -i inventories/local1.yml playbooks/test1.yml
PLAY [group1] *****************************************************************
TASK: [DEBUG | inventory group1] ***************************************************
ok: [test-server11] => {
"msg": "local1_group1"
}
PLAY [group2] *****************************************************************
TASK: [DEBUG | inventory group2] ***************************************************
ok: [test-server1A] => {
"msg": "local1_group2"
}
PLAY RECAP ********************************************************************
test-server11 : ok=1 changed=0 unreachable=0 failed=0
test-server1A : ok=1 changed=0 unreachable=0 failed=0
$ ansible-playbook -i inventories/local2.yml playbooks/test1.yml
PLAY [group1] *****************************************************************
TASK: [DEBUG | inventory group1] ***************************************************
ok: [test-server22] => {
"msg": "local2_group1"
}
ok: [test-server21] => {
"msg": "local2_group1"
}
ok: [test-server23] => {
"msg": "local2_group1"
}
PLAY [group2] *****************************************************************
TASK: [DEBUG | inventory group2] ***************************************************
ok: [test-server2A] => {
"msg": "local2_group2"
}
ok: [test-server2B] => {
"msg": "local2_group2"
}
ok: [test-server2C] => {
"msg": "local2_group2"
}
PLAY RECAP ********************************************************************
test-server21 : ok=1 changed=0 unreachable=0 failed=0
test-server22 : ok=1 changed=0 unreachable=0 failed=0
test-server23 : ok=1 changed=0 unreachable=0 failed=0
test-server2A : ok=1 changed=0 unreachable=0 failed=0
test-server2B : ok=1 changed=0 unreachable=0 failed=0
test-server2C : ok=1 changed=0 unreachable=0 failed=0
今回はテストでは文字列にしたけど、外出ししたのでオブジェクト構造の変数も定義できそう。
多分、もっといい方法はあるんだろうな。