group_varsで定義した変数を他のgroup_varsで使用する

## 環境

```
# ansible --version
ansible 2.7.1
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /bin/ansible
  python version = 2.7.5 (default, Sep 12 2018, 05:31:16) [GCC 4.8.5 20150623 (Red Hat 4.8.5-36)]
```


## bashの場合

変数を定義したファイル(hoge.vars, fuga.vars)があり、お互いに定義されている変数を参照したときの結果

```:hoge.vars
param_a=param_a
result_a=$param_b
```

```:fuga.vars
param_b=param_b
result_b=$param_a
```

```bash:test.sh
#!/bin/bash

. /home/work/hoge.vars
. /home/work/fuga.vars

echo "result_a : $result_a"
echo "result_b : $result_b"

exit 0
```

```
# ./test.sh
result_a :
result_b : param_a
```

当然ながらparam_bが未定義なのに```result_a=$param_b```とやっても
値は行ってきませんよという話です。


## Ansible(group_vars)の場合

```:hosts
[local-srv]
127.0.0.1

[group_a:children]
local-srv

[group_b:children]
local-srv
```

```yml:group_vars/group_a.yml
---
param_a: param_a

result_a: "{{ param_b }}"
```

```yml:group_vars/group_b.yml
---
param_b: param_b

result_b: "{{ param_a }}"
```

```yml:test.yml
---
- hosts: all
  tasks:

  - debug: var=result_a
  - debug: var=result_b
```


```bash
# ansible-playbook -i hosts -l local-srv test.yml

PLAY [all] ***********************************************************************************

TASK [Gathering Facts] ***********************************************************************
ok: [127.0.0.1]

TASK [debug] *********************************************************************************
ok: [127.0.0.1] => {
    "result_a": "param_b"
}

TASK [debug] *********************************************************************************
ok: [127.0.0.1] => {
    "result_b": "param_a"
}

PLAY RECAP ***********************************************************************************
127.0.0.1                  : ok=3    changed=0    unreachable=0    failed=0
```

group_varsを読み込んだ後、"{{ xxxx }}"が補完(代入)されるのであろう。ありがたい。


## 使い道

![サーバ一覧.png](https://qiita-image-store.s3.amazonaws.com/0/259373/adfb641b-60d7-ac7c-b6ea-acef3cecec47.png)

上記を階層で書くと以下のとおり。

```
Project
|`試験環境  ★環境として10.0.0.13,14のログサーバを持つ
| |`webサーバ  ☆10.0.0.13をログサーバとする
| |  ` test-web01
|  `dbサーバ   ☆10.0.0.14をログサーバとする
|    ` test-db01
|
|`開発環境  ★環境として20.0.0.13,14のログサーバを持つ
| |`webサーバ  ☆20.0.0.13をログサーバとする
| |  ` dev-web01
|  `dbサーバ   ☆20.0.0.14をログサーバとする
|    ` dev-db01
|
 `本番環境  ★環境として30.0.0.13,14のログサーバを持つ
  |`webサーバ  ☆30.0.0.13をログサーバとする
  | |` master-web01
  |  ` master-web02
   `dbサーバ   ☆30.0.0.14をログサーバとする
    |` master-db01
     ` master-db02
```

これを今回学んだことに照らし合わせると以下のとおり

```:master_hosts
[web_servers]
master-web01
master-web02

[db_servers]
master-db01
master-db02

[master_env:children]
web_servers
db_servers
```

```yml:group_vars/master_env.yml
---
syslog_srv_list:
  host_a: "30.0.0.13"
  host_b: "30.0.0.14"
```

```yml:group_vars/web_servers.yml
syslog_host: "{{ syslog_srv_list.host_a }}"
```

```yml:group_vars/db_servers.yml
syslog_host: "{{ syslog_srv_list.host_b }}"
```

```yml:syslog_set.yml
---
- hosts: all
  tasks:
    - name: print sysloghost
      debug:
        msg="ログサーバは {{ syslog_host }} です."
```

実行結果

```bash
# ansible-playbook -i master_hosts syslog_set.yml

PLAY [all] ***********************************************************************************

TASK [Gathering Facts] ***********************************************************************
ok: [master-web02]
ok: [master-db02]
ok: [master-db01]
ok: [master-web01]

TASK [print sysloghost] **********************************************************************
ok: [master-web01] => {
    "msg": "ログサーバは 30.0.0.13 です."
}
ok: [master-web02] => {
    "msg": "ログサーバは 30.0.0.13 です."
}
ok: [master-db01] => {
    "msg": "ログサーバは 30.0.0.14 です."
}
ok: [master-db02] => {
    "msg": "ログサーバは 30.0.0.14 です."
}

PLAY RECAP ***********************************************************************************
master-db01                : ok=2    changed=0    unreachable=0    failed=0
master-db02                : ok=2    changed=0    unreachable=0    failed=0
master-web01               : ok=2    changed=0    unreachable=0    failed=0
master-web02               : ok=2    changed=0    unreachable=0    failed=0
```

### host_vars/hostname.ymlに直接書いた場合

web01,web02それぞれに同じ定義 ```syslog_host: "xx.xx.xx.xx"``` を書く必要が出てくる。これがサーバ100～200台になると編集するのも大変(編集漏れが一番怖い)。今回のように「webxxはログサーバA」と決まっているならgroup:xxx_servers.ymlに書くことがマシだろう。

### group_vars/{web|db}_servers.yml に直接書いた場合

今回の目的を達するだけならweb_servers.ymlに ```syslog_host: "xx.xx.xx.xx"```を書けばいい。しかし今回はweb or dbだったがサーバ種別が増えた場合、例えばweb, db, backup, mainと増えて相変わらず環境ごとにログサーバが2つだった場合、host_varsに書くことと同じ状況になってしまう。

またmaster_env.ymlなど最上位のグループに定義することで、ログサーバを一覧で見られるなど管理が楽になる。