初めてのAnsible（4章：変数とファクト）


[「初めてのAnsible」](https://www.oreilly.co.jp/books/9784873117652/)を読み進めながらのメモ

前掲
[初めてのAnsible（1章：イントロダクション）](http://qiita.com/c0tt0n-candy/items/512049586f5a1f1279f3)
[初めてのAnsible（2章：Playbook:始めてみよう）](http://qiita.com/c0tt0n-candy/items/36b4eb2717447071ad21)
[初めてのAnsible（3章：インベントリ:サーバーの記述）](http://qiita.com/c0tt0n-candy/items/1b109c53d8709717a1bb)

# 変数

## playbook内での変数定義

playbook 中での変数定義はファイルに追い出すこともできる

```:playbook1.yml
- name : Configure webserver with nginx
  hosts: vagrant
  become: True
  vars:
    key_file: /etc/nginx/ssl/nginx.key
    cert_file: /etc/nginx/ssl/nginx.crt
    conf_file: /etc/nginx/sites-available/default
    server_name: localhost
  tasks:
    - name: install nginx
      apt: name=nginx update_cache=yes cache_valid_time=3600
```

というような playbook 内で定義している変数は `vars_files` を利用し分離可能

```:playbook2.yml
- name : Configure webserver with nginx
  hosts: vagrant
  become: True
  vars_files:
    - nginx.yml
  tasks:
    - name: install nginx
      apt: name=nginx update_cache=yes cache_valid_time=3600
```

```:nginx.yml
key_file: /etc/nginx/ssl/nginx.key
cert_file: /etc/nginx/ssl/nginx.crt
conf_file: /etc/nginx/sites-available/default
server_name: localhost
```

## 登録変数

* `register`節を利用し、タスクの結果に応じて登録された変数

```格納例
- name: capture output of whoami command
  command: whoami
  register: login
```

`whoami` の実行結果を変数 `login` に格納している

変数を確認したい場合には `debug` モジュールを利用して出力すればよい

```格納した変数を確認
- name: capture output of whoami command
  command: whoami
  register: login
- debug: var=login
```


このとき、`register`節を利用して登録した変数の型は以下のような辞書（マッピング）になる

```
ok: [vagrant1] => {
    "login": {
        "changed": true,
        "cmd": [
            "whoami"
        ],
        "delta": "0:00:00.002230",
        "end": "2016-11-13 05:49:52.211117",
        "rc": 0,
        "start": "2016-11-13 05:49:52.208887",
        "stderr": "",
        "stdout": "vagrant",
        "stdout_lines": [
            "vagrant"
        ],
        "warnings": []
    }
}
```

ここで注意しなければならないのは、`register`節を利用したモジュールによって返すキーは異なる、ということ

例えば...
次のような `apt` モジュールを利用した際の出力を変数に登録して確認する

```apt-install.yml
- name : Install webserver with nginx
  hosts: vagrant1
  become: True
  vars:
  tasks:
    - name: install nginx
      apt: name=nginx update_cache=yes cache_valid_time=3600
      register: install
    - debug: var=install
```

初回実行時は未インストールであるため、以下のような出力となる

```:初回実行時
ok: [vagrant1] => {
    "install": {
        "cache_update_time": 1479016674,
        "cache_updated": true,
        "changed": true,
        "diff": {},
        "stderr": "",
        "stdout": "Reading package lists...\nBuilding dependency tree... ...",
        "stdout_lines": [
            "Reading package lists...",
            "Building dependency tree...",
            "Reading state information...",
            "The following extra packages will be installed:",
              :
            "Setting up nginx (1.4.6-1ubuntu3.7) ...",
            "Processing triggers for libc-bin (2.19-0ubuntu6.9) ..."
        ]
    }
}
```

しかし、2回目の実行時にはすでにインストールされているため、出力が以下のように変わる

```:2回目実行時
ok: [vagrant1] => {
    "install": {
        "cache_update_time": 1479016674,
        "cache_updated": false,
        "changed": false
    }
}
```

このように `regster` 節を利用するモジュールによって、出力されるキーが異なってくる場合もあるため注意が必要

特に...
登録変数の辞書のキーへアクセスする場合、playbook 実行に失敗する可能性がある

```:登録変数中のキーアクセス
// ドット(.)を利用
{{ install.stdout }}

// 添え字([])を利用
{{ install['stdout'] }}
```

上記のような形式で登録変数のキーアクセスが可能
前述のようなホストの状態によって出力が変化するモジュールで登録した変数の場合、そのキーが存在しないにも関わらずアクセスしようとする場合が生じうる

# ファクト

* ホストに関する以下のような情報を保存した変数
	* CPUのアーキテクチャ
	* OS
	* IPアドレス ...
* `setup`モジュールでファクトを収集できる
	* playbook中で明示しなくても自動的に呼んでくれている


## ファクトの表示

ファクトを確認したい場合には前述の`setup`モジュールを利用すればよい

`ansible vagrant1 -m setup` とすると結構な量の出力が得られるので眺めてみてもいいかも
見たい方はここを -> [ansible-quickref/facts.rst](https://github.com/lorin/ansible-quickref/blob/master/facts.rst)

さらっと見て分かるのは、ファクトはすべて `ansible_xxx` みたいな形式になってるってこと


一部のファクトのみ得たい、という場合には `ansible vagrant1 -m setup 'filter=ansible_all_ipv4_addresses'` みたいな感じでフィルタリングすることも可能

##  [組み込み変数](http://docs.ansible.com/ansible/playbooks_variables.html#magic-variables-and-how-to-access-information-about-other-hosts)

* playbook中でいつでも使えるように定義されている変数

一部を載せておくけど、それぞれ使って確認して見た方がいいかも

### `hostvars`

* Ansible のホスト名をキーとして、変数名と値のマッピングを値とする辞書

あるホストから他のホストに定義された変数を利用する場合などに使える

```
{{ hostvars['db.example.com'].ansible_eth1.ipv4.address }}
```

組み込み変数 `hostvars` を利用することで、Ansibleの知っているホストに定義された変数を、ホスト名をキーとして取得することができる

※ Ansibleが知っている -> Ansibleがまだファクトを収集していないホストについてはむり

### `inventory_hostname`

* Ansibleが知っている現在のホスト名

インベントリファイルでエイリアスが定義されている場合にはエイリアス名となる

```
hostvars[inventory_hostname]
```

`hostvars` と組み合わせることで、現在のホストに関連づけられた全ての変数を取得できる

### `groups`

* Ansibleのグループ名をキーとして、そのグループのメンバーのホスト名のリストを値とする辞書

```
{% for host in groups.web %}
	server {{ host.inventory_hostname }} {{ host.ansible_default_ipv4.address }}:80
{% endfor %}
```

上記のような設定ファイルでは、`web`というグループに含まれるホストに関して、そのホスト名とIPアドレスを取得している