Help us understand the problem. What is going on with this article?

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なので、動作も軽快。

h2suzuki
ICT企業を脱サラして、ごにょごにょ。でもやっぱりICT関係。
http://eng-manima.blogspot.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away