Edited at

Ansible マジック変数の一覧と内容

More than 5 years have passed since last update.

Ansible Playbookで利用できる、マジック変数たち。

公式docに一覧がなかったので、一覧にしてみた。


マジック変数とは

Ansible Playbookには gather_facts:False でも使える変数がある。

「定義済み変数」であり、マジック変数 と呼ばれる。

主に、インベントリに関する情報が得られる。


マジック変数の一覧

値は、Playbookを実行しているターゲットマシン毎にセットされる。

変数名
内容

group_names
このターゲットマシンが属する全グループの一覧

groups
グループ-to-ホストのマッピング

inventory_hostname
インベントリに書かれたホスト名

inventory_hostname_short

inventory_hostnameの最初の "." まで

play_hosts
Playbookが適用されるホスト一覧

inventory_dir
インベントリファイルのあるディレクトリパス

inventory_file
インベントリファイルのベース名

groups は、グループ階層(グループのグループ)を平たく展開し

    グループX:[ ホスト1, ホスト2, ... ]

グループY:[ ホスト1, ホスト2, ホスト3, ... ]

といった形式で、値を保持している。

inventory_hostname_short は、inventory_hostnameをFQDNと見なしてドメイン部分を除いたホスト名。ただ、IPv4 アドレス xx.yy.zz.ww では "xx" となってしまう。思いもよらないバグとならないよう、使わない方がよいかもしれない。

inventory_{dir,file}は、{{ inventory_dir ~ "/" ~ inventory_file }} とすることで、フルパスを構成できる。


Factsのためのマジック変数

重要なマジック変数。

変数名
内容

hostvars
Playbookを適用する全マシンの facts の集合

gather_facts:True の場合、hostvars には、Playbook を実行する全マシンの facts が含まれる。

gather_facts:False だと、値は空になる(未定義ではない)。

★ hostvarsを{{ hostvars["host名"] }}で参照すると、参照時点で以下のメンバが追加される模様。

追加されるメンバ
内容

ansible_connection
sshやlocalなどコネクションタイプ

group_name
前述のマジック変数

inventory_hostname
前述のマジック変数

inventory_hostname_short
前述のマジック変数

ただ、ドキュメントに記述を見つけられなかった。

公式仕様なのか、たまたまなのか、利用するなら念のため本家に質問したほうがよいかもしれない。


予約済みマジック変数

値は入っていない。ユーザが使ってはいけない変数らしい。

変数名
内容

environment
予約済み変数


実際に取得できた値

小さな Playbook を書いて、マジック変数の値を調べてみた。

groups の動きを見るため、インベントリに定義したグループは、無理やり階層化している。こんな感じ。

    test-servers

+---- test-servers1
| +---- localhost1
|
+---- test-servers2
+---- localhost2


実行結果

まず、取得できた値から示す。

gather_facts:Falseで実行している。

[ansibleman@ponet ~]$ ansible-playbook -i hosts magic_vars.yml


PLAY [test-servers] ***********************************************************

TASK: [Facts | ansible_hostname] **********************************************
ok: [localhost1] => {
"ansible_hostname": "{{ ansible_hostname }}"
}
ok: [localhost2] => {
"ansible_hostname": "{{ ansible_hostname }}"
}

TASK: [Facts | ansible_default_ipv4] ******************************************
ok: [localhost1] => {
"ansible_default_ipv4": "{{ ansible_default_ipv4 }}"
}
ok: [localhost2] => {
"ansible_default_ipv4": "{{ ansible_default_ipv4 }}"
}

TASK: [Facts | ansible_env] ***************************************************
ok: [localhost1] => {
"ansible_env": "{{ ansible_env }}"
}
ok: [localhost2] => {
"ansible_env": "{{ ansible_env }}"
}

TASK: [Magic | group_names] ***************************************************
ok: [localhost1] => {
"group_names": [
"test-servers",
"test-servers1"
]
}
ok: [localhost2] => {
"group_names": [
"test-servers",
"test-servers2"
]
}

TASK: [Magic | groups] ********************************************************
ok: [localhost1] => {
"groups": {
"all": [
"localhost1",
"localhost2"
],
"test-servers": [
"localhost1",
"localhost2"
],
"test-servers1": [
"localhost1"
],
"test-servers2": [
"localhost2"
],
"ungrouped": []
}
}
ok: [localhost2] => {
"groups": {
"all": [
"localhost1",
"localhost2"
],
"test-servers": [
"localhost1",
"localhost2"
],
"test-servers1": [
"localhost1"
],
"test-servers2": [
"localhost2"
],
"ungrouped": []
}
}

TASK: [Magic | inventory_hostname] ********************************************
ok: [localhost1] => {
"inventory_hostname": "localhost1"
}
ok: [localhost2] => {
"inventory_hostname": "localhost2"
}

TASK: [Magic | inventory_hostname_short] **************************************
ok: [localhost1] => {
"inventory_hostname_short": "localhost1"
}
ok: [localhost2] => {
"inventory_hostname_short": "localhost2"
}

TASK: [Magic | play_hosts] ****************************************************
ok: [localhost1] => {
"play_hosts": [
"localhost1",
"localhost2"
]
}
ok: [localhost2] => {
"play_hosts": [
"localhost1",
"localhost2"
]
}

TASK: [Magic | inventory_dir] *************************************************
ok: [localhost1] => {
"inventory_dir": "/home/ansibleman"
}
ok: [localhost2] => {
"inventory_dir": "/home/ansibleman"
}

TASK: [Magic | inventory_file] ************************************************
ok: [localhost1] => {
"inventory_file": "hosts"
}
ok: [localhost2] => {
"inventory_file": "hosts"
}

TASK: [Magic for Facts | hostvars] ********************************************
ok: [localhost1] => {
"hostvars": {
"localhost1": {},
"localhost2": {}
}
}
ok: [localhost2] => {
"hostvars": {
"localhost1": {},
"localhost2": {}
}
}

TASK: [Reserved | environment] ************************************************
ok: [localhost1] => {
"environment": {}
}
ok: [localhost2] => {
"environment": {}
}

PLAY RECAP ********************************************************************
localhost1 : ok=12 changed=0 unreachable=0 failed=0
localhost2 : ok=12 changed=0 unreachable=0 failed=0


若干の説明


  • Factsは、gather_facts:False にしたので、未定義変数の状態。debugモジュールでは、未定義変数は文字列として処理される。


  • group_name では、localhost1 と localhost2 で、ちゃんと別々のグループ一覧を取得できている。


  • play_hosts では、Playbookを実行する全ターゲットマシン名を取得できている。


少し脇道にそれるが、ansible_hostnameは、ターゲットマシンの本当のホスト名になる。Factsの一つなので、gather_facts:True にすると、ちゃんとターゲットマシン上で取得して、正しい値が入る。


Playbook

上記の結果を得るために書いた Playbook は、こちら。


magic_vars.yml

--- # file: magic_vars.yml

- hosts: test-servers

gather_facts: "{{ check_env | default(False) }}"

tasks:

# Facts
- name: Facts | ansible_hostname
debug: var=ansible_hostname
- name: Facts | ansible_default_ipv4
debug: var=ansible_default_ipv4
- name: Facts | ansible_env
debug: var=ansible_env

# Magic variables
- name: Magic | group_names
debug: var=group_names
- name: Magic | groups
debug: var=groups
- name: Magic | inventory_hostname
debug: var=inventory_hostname
- name: Magic | inventory_hostname_short
debug: var=inventory_hostname_short
- name: Magic | play_hosts
debug: var=play_hosts
- name: Magic | inventory_dir
debug: var=inventory_dir
- name: Magic | inventory_file
debug: var=inventory_file

# Magic variable for Facts
- name: Magic for Facts | hostvars
debug: var=hostvars

# Reserved magic variable
- name: Reserved | environment
debug: var=environment


check_env 変数をコマンドラインの -e オプションから与えると、Playbookを書き換えなくても、gather_facts:を制御できるようにしている。

以下のように実行する。

ansible-playbook -i hosts magic_vars.yml

Factsを収集したいときには、こう。

ansible-playbook -i hosts magic_vars.yml -e "check_env=True"


インベントリと /etc/hosts

利用したインベントリファイルはこちら。


hosts

[test-servers1]

localhost1 ansible_connection=local

[test-servers2]
localhost2 ansible_connection=local

[test-servers:children]
test-servers1
test-servers2


/etc/hosts で、インベントリ上のホスト名とIPアドレスを対応付け。

127.0.0.1   localhost localhost.localdomain

127.0.0.1 localhost1
127.0.0.1 localhost2


活用例|ホスト名の一括設定

インベントリに書かれたホスト名を使って、全ターゲットマシンにホスト名を一括設定してみる。


set_hostname.yml

--- # file: set_hostname.yml

- hosts: test-servers
gather_facts: False
tasks:
- name: Set the hostname using the inventory
hostname: name={{ inventory_hostname }}
sudo: yes

インベントリに書いてあるホスト名は、/etc/hostsなどに登録し、IPアドレスと対応させておく。

こんな感じで実行。

    $ ansible-playbook -i hosts set_hostname.yml

沢山の仮想マシンを新規に立ち上げ、初期セットアップするときに便利かもしれない。gather_facts:Falseなので、動作も軽快。