hana_shinのLinux技術ブログ

Linuxの技術情報を掲載しています。特にネットワークをメインに掲載していきます。

Ansibleの使い方(マジック変数、ファクト変数編)



1 はじめに

本記事では、以下のドキュメントに記載されているマジック変数とファクト変数について動作確認をしてみます。
特別な変数 — Ansible Documentation

種類 概要
ファクト変数 ターゲットノード(リモートホスト)から収集したシステムに関する情報を保持する変数です。たとえば、ターゲットノードのホスト名やIPアドレスなどの情報を取得できます。ファクトはsetupというモジュールが実行されることにより、対象のターゲットノードでPythonスクリプトが実行され収集されます。
マジック変数 Ansible があらかじめ定義している変数です。マジック変数の中で、ターゲットノードに関する情報を設定した変数をファクト変数と呼びます。ユーザーはマジック変数に値を設定できません。

2 検証環境

動作検証をするための環境は以下のとおりです。enp1s0はNICの名前です。

                          192.168.122.0/24
control(enp1s0) -------------------------------------(enp1s0) node1
               .220                               .87
ホスト名 役割
control コントロールノードとして動作します。Ansibleをインストールします。
node1 ターゲットノードとして動作します。モジュールが実行されるホストです

コントロールノード、ターゲットノードのAlmaLinux版数は以下のとおりです。

[root@server ~]# cat /etc/redhat-release
AlmaLinux release 9.2 (Turquoise Kodkod)

コントロールノード、ターゲットノードのカーネル版数は以下のとおりです。

[root@server ~]# uname -r
5.14.0-284.11.1.el9_2.x86_64

3 事前準備

ansibleのインストールや公開鍵認証の設定方法などは、Ansibleの使い方(モジュール編) - hana_shinのLinux技術ブログを参照してください。

4 インベントリファイルの作成

管理対象となるサーバの一覧を記述したインベントリファイルを作成します。この後のモジュールの動作確認でも、このインベントリファイルを使用します。node1 はターゲットノードのホスト名であり、ansible_host はターゲットノードのIPアドレスを定義しています。

[root@control ~]# vi hosts.ini
[root@control ~]# cat hosts.ini
[nodes]
node1 ansible_host=192.168.122.220

5 ファクト変数を表示する方法

5.1 全てのファクト変数を表示する方法

全てのファクトを表示するplaybookを作成します。
playbook中のgather_facts,ansible_factsの意味は以下のとおりです。
・gather_facts:trueはファクトを収集する。falseはファクトを収集しない。
・ansible_facts:Ansibleが収集したファクトを格納する変数です。

[root@control ~]# vi test.yml
[root@control ~]# cat test.yml
- name: Sample Playbook
  hosts: nodes
  gather_facts: true
  tasks:
    - name: Display Gathered Facts
      debug:
        var: ansible_facts

playbookを実行すると、「Gathering Facts」と表示されるタイミングで、ターゲットノードからファクトが収集されていることがわかります。

[root@control ~]# ansible-playbook -i hosts.ini test.yml

PLAY [Sample Playbook] ************************************************************************************************

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

TASK [Display Gathered Facts] *****************************************************************************************
ok: [node1] => {
    "ansible_facts": {
        "all_ipv4_addresses": [
            "192.168.122.220"
        ],
        "all_ipv6_addresses": [
            "fe80::5054:ff:fe2a:749c"
        ],
        "ansible_local": {},
        "apparmor": {
            "status": "disabled"
        },
-snip-

5.2 特定のファクトを表示する方法

(1) カーネル版数を表示する方法

カーネル版数はansible_facts内で以下のように定義されています。したがって、カーネル版数は {{ ansible_facts.kernel }} で参照することができます。

    "ansible_facts": {

        -snip-

        "kernel": "5.14.0-284.11.1.el9_2.x86_64",
    }

カーネル版数を表示するplaybookを作成します。

[root@control ~]# vi test.yml
[root@control ~]# cat test.yml
- name: Sample Playbook
  hosts: node1
  gather_facts: true
  tasks:
    - name: Display Gathered Facts
      debug:
        msg: "The kernel version of the remote host is {{ ansible_facts.kernel }}"

playbookを実行すると、カーネル版数(5.14.0-284.11.1.el9_2.x86_64)が表示されていることがわかります。

[root@control ~]# ansible-playbook -i hosts.ini test.yml

PLAY [Sample Playbook] ************************************************************************************************

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

TASK [Display Gathered Facts] *****************************************************************************************
ok: [node1] => {
    "msg": "The kernel version of the remote host is 5.14.0-284.11.1.el9_2.x86_64"
}

PLAY RECAP ************************************************************************************************************
node1                      : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

[root@control ~]#

(2) ホスト名を表示する方法
ホスト名はansible_facts内で以下のように定義されています。したがって、ホスト名は {{ ansible_facts.nodename }} で参照することができます。

    "ansible_facts": {

        -snip-

        "nodename": "node1",
    }

ターゲットノードのホスト名を表示するplaybookを作成します。

[root@control ~]# vi test.yml
[root@control ~]# cat test.yml
- name: Sample Playbook
  hosts: nodes
  gather_facts: true
  tasks:
    - name: Display Gathered Facts
      debug:
        msg: "The name of the remote host is {{ ansible_facts.nodename }}"

playbookを実行すると、ターゲットノードのホスト名(node1)が表示されていることがわかります。

[root@control ~]# ansible-playbook -i hosts.ini test.yml

PLAY [Sample Playbook] ************************************************************************************************

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

TASK [Display Gathered Facts] *****************************************************************************************
ok: [node1] => {
    "msg": "The name of the remote host is node1"
}

PLAY RECAP ************************************************************************************************************
node1                      : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

[root@control ~]#

(3) インタフェース名を表示する方法
インタフェースはansible_facts内で以下のように定義されています。したがって、インタフェースは {{ ansible_facts.interfaces }} で参照することができます。

    "ansible_facts": {

        -snip-

        "interfaces": [
            "enp1s0",
            "lo"
        ],
    }

ターゲットノードが持っているインタフェース名を表示するplaybookを作成します。

[root@control ~]# vi test.yml
[root@control ~]# cat test.yml
- name: Sample Playbook
  hosts: nodes
  tasks:
    - name: Display Gathered Facts
      debug:
        msg: "The host has the interface {{ ansible_facts.interfaces }}"

playbookを実行すると、ターゲットノードは、2つのインタフェース(lo,enp1s0)を持っていることがわかります。

[root@control ~]# ansible-playbook -i hosts.ini test.yml

PLAY [Sample Playbook] ************************************************************************************************

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

TASK [Display Gathered Facts] *****************************************************************************************
ok: [node1] => {
    "msg": "The host has the interface ['enp1s0', 'lo']"
}

PLAY RECAP ************************************************************************************************************
node1                      : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

[root@control ~]#

(4) IPアドレスを表示する方法

IPアドレスはansible_facts内で以下のように定義されています。したがって、IPアドレスは {{ ansible_facts.enp1s0.ipv4.address }}で参照することができます。

    "ansible_facts": {
        "enp1s0": {

            -snip-

            "ipv4": {
                "address": "192.168.122.220",
                "broadcast": "192.168.122.255",
                "netmask": "255.255.255.0",
                "network": "192.168.122.0",
                "prefix": "24"
            },

        },
    }

ターゲットノードのNIC(enp1s0)に設定されているIPアドレスを表示するplaybookを作成します。

[root@control ~]# vi test.yml
[root@control ~]# cat test.yml
- name: Sample Playbook
  hosts: nodes
  gather_facts: true
  tasks:
    - name: Display Gathered Facts
      debug:
        msg: "IP adress is {{ ansible_facts.enp1s0.ipv4.address }}"

playbookを実行すると、ターゲットノードのNIC(enp1s0)に設定されているIPアドレスが 192.168.122.220 であることがわかります。

[root@control ~]# ansible-playbook -i hosts.ini test.yml

PLAY [Sample Playbook] ************************************************************************************************

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

TASK [Display Gathered Facts] *****************************************************************************************
ok: [node1] => {
    "msg": "IP adress is 192.168.122.220"
}

PLAY RECAP ************************************************************************************************************
node1                      : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

[root@control ~]#

6 マジック変数を表示する方法

マジック変数は、Ansible がシステム内の状態を反映する変数です。ユーザーは、マジック変数に値を設定することはできません。マジック変数の一覧は、特別な変数 — Ansible Documentationを参照してください。
https://docs.ansible.com/ansible/2.9_ja/user_guide/playbooks_variables.html

6.1 プレイブック名を表示する方法(ansible_play_name)

ansible_play_nameは、プレイブック名を表示するマジック変数です。ansible_play_nameを使ってplaybookを作成します。

[root@control ~]# vi test.yml
[root@control ~]# cat test.yml
- name: Sample Playbook
  hosts: nodes
  tasks:
    - name: Display Ansible Playbook Name
      debug:
        msg: "{{ ansible_play_name }}"

playbookを実行すると、プレイブックの名前(Sample Playbook)が表示されていることがわかります。

[root@control ~]# ansible-playbook -i hosts.ini test.yml

PLAY [Sample Playbook] ********************************************************************

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

TASK [Display Ansible Playbook Name] ******************************************************
ok: [node1] => {
    "msg": "Sample Playbook"
}

PLAY RECAP ********************************************************************************
node1                      : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

[root@control ~]#

6.2 パッケージ管理ソフト名を表示する方法(ansible_pkg_mgr)

パッケージ管理ソフトウェアは、コンピュータにインストールされたソフトウェアの記録を管理し、新しいソフトウェアのインストール、既存ソフトウェアのアップデート、そして不要なソフトウェアの削除を容易に行えるソフトウェアです。具体例としては、yum(RHEL7など)、dnf(RHEL 8、9など)、およびyast(SLES)などがあります。ansible_pkg_mgrを使ってplaybookを作成します。

[root@control ~]# vi test.yml
[root@control ~]# cat test.yml
- name: Sample Playbook
  hosts: nodes
  tasks:
    - name: debug ansible_hostname
      debug:
        msg: "{{ansible_pkg_mgr}}"

playbookを実行すると、ターゲットノードのパッケージ管理ソフトがdnfであることがわかります。

[root@control ~]# ansible-playbook -i hosts.ini test.yml

PLAY [Sample Playbook] ************************************************************************************************

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

TASK [debug ansible_hostname] *****************************************************************************************
ok: [node1] => {
    "msg": "dnf"
}

PLAY RECAP ************************************************************************************************************
node1                      : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

[root@control ~]#

6.3 インベントリファイル内のホスト名を表示する方法(inventory_hostname)

inventory_hostnameは、インベントリファイル内のホスト名を示すマジック変数です。この変数を使用してPlaybookを作成することができ、これにより特定のホストに対してロールを動的に適用することができます。なお、inventory_hostname_shortは、FQDNのホスト名の部分だけを示すマジック変数です。たとえば、インベントリファイル内でnode1.example.comと定義されていた場合、inventory_hostname_shortはnode1を示すことになります。

[root@control ~]# cat test.yml
- name: Sample Playbook
  hosts: nodes
  tasks:
    - name: debug ansible_hostname
      debug:
        msg: "{{inventory_hostname}}"

playbookを実行すると、インベントリファイル内のホスト名であるnode1が出力されていることがわかります。

[root@control ~]# ansible-playbook -i hosts.ini test.yml

PLAY [Sample Playbook] ************************************************************************************************

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

TASK [debug ansible_hostname] *****************************************************************************************
ok: [node1] => {
    "msg": "node1"
}

PLAY RECAP ************************************************************************************************************
node1