Ansible プレイブックでの gather_facts オプションの設定方法

AnsibleBeginner
オンラインで実践に進む

はじめに

Ansible は、システム管理者や開発者がインフラストラクチャを効率的に管理するのに役立つ強力な IT 自動化ツールです。その主要な機能の 1 つは、ターゲットシステムに関する情報を収集する能力であり、「ファクト (facts)」として知られています。Ansible の gather_facts オプションは、プレイブックの実行中にこの情報が収集されるかどうか、およびその方法を決定します。

この実践的な実験 (Lab) では、Ansible プレイブックで gather_facts オプションを構成する方法を学びます。さまざまな設定を調べ、ファクト収集を有効または無効にするタイミングを理解し、収集されたファクトを使用してプレイブックをより動的かつ効率的にする方法を発見します。この実験 (Lab) の終わりには、特定のニーズに応じてファクト収集プロセスを制御することにより、Ansible ワークフローを最適化できるようになります。

Ansible のインストールと gather_facts オプションの探索

まず、Ansible をインストールし、gather_facts オプションが何をするのかを調べてみましょう。このステップでは、Ansible をインストールし、簡単なインベントリを作成し、コマンドを実行してどのようなファクトが収集されるかを確認します。

Ansible のインストール

まず、システムに Ansible をインストールしましょう。

sudo apt update
sudo apt install -y ansible

インストールが完了したら、Ansible が正しくインストールされていることを確認します。

ansible --version

次のような出力が表示されるはずです。

ansible [core 2.12.x]
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/labex/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3/dist-packages/ansible
  ansible collection location = /home/labex/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.10.x (default, Aug 14 2022, 00:00:00) [GCC 11.2.0]
  jinja version = 3.0.3
  libyaml = True

簡単なインベントリの作成

次に、作業用の簡単なインベントリファイルを作成しましょう。インベントリファイルは、Ansible が管理するホストを定義します。この実験 (Lab) では、ローカルインベントリを作成します。

mkdir -p ~/project/ansible
cd ~/project/ansible

エディタを使用して、hosts という名前のインベントリファイルを作成します。

  1. WebIDE のエクスプローラーアイコンをクリックします。
  2. /home/labex/project/ansible ディレクトリに移動します。
  3. 右クリックして「新しいファイル」を選択します。
  4. ファイル名を hosts とします。
  5. 次の内容を追加します。
[local]
localhost ansible_connection=local

このインベントリは、localhost という 1 つのホストのみを持つ local というグループを設定します。ansible_connection=local パラメータは、SSH を使用せずに、ローカルマシン上で直接コマンドを実行するように Ansible に指示します。

gather_facts の探索

デフォルトでどのようなファクトが収集されるかを確認するために、簡単な Ansible コマンドを実行してみましょう。

cd ~/project/ansible
ansible local -i hosts -m setup

上記のコマンドは以下を使用します。

  • local: インベントリからのグループ
  • -i hosts: インベントリファイルを指定します
  • -m setup: ファクトを収集する setup モジュールを実行します

ハードウェア情報(CPU、メモリ)、ネットワーク設定、オペレーティングシステムの詳細、環境変数など、システムに関する詳細情報を含む大きな JSON 出力が表示されます。

この情報は、gather_facts が有効になっている場合に Ansible が収集するものです(これはデフォルトの動作です)。これらのファクトは、プレイブックでターゲットシステムの特性に基づいて決定を下したり、タスクをカスタマイズしたりするために使用できます。

デフォルトのファクト収集を使用した基本的なプレイブックの作成

このステップでは、デフォルトのファクト収集動作を使用し、収集された情報の一部を表示する基本的な Ansible プレイブックを作成します。

Ansible プレイブックの理解

Ansible プレイブックは、管理対象ホストで実行されるタスクのリストを含む YAML ファイルです。プレイブックは、構成、デプロイ、およびオーケストレーションの手順を、シンプルで人間が読める形式で定義する方法を提供します。

最初のプレイブックの作成

Ansible がデフォルトで収集するファクトの一部を表示する簡単なプレイブックを作成しましょう。

  1. WebIDE で、/home/labex/project/ansible ディレクトリに移動します。
  2. facts_playbook.yml という名前の新しいファイルを作成します。
  3. 次の内容を追加します。
---
- name: Show System Facts
  hosts: local
  ## By default, gather_facts is set to 'true'

  tasks:
    - name: Display operating system
      debug:
        msg: "Operating System: {{ ansible_distribution }} {{ ansible_distribution_version }}"

    - name: Display CPU information
      debug:
        msg: "CPU: {{ ansible_processor[1] }} with {{ ansible_processor_cores }} cores"

    - name: Display memory information
      debug:
        msg: "Total Memory: {{ ansible_memtotal_mb }} MB"

    - name: Display Python version
      debug:
        msg: "Python version: {{ ansible_python_version }}"

このプレイブックは次のとおりです。

  • インベントリで定義された local グループをターゲットにします。
  • 暗黙的にファクト収集を有効にします(デフォルトの動作)。
  • Ansible が収集したさまざまな情報を表示する 4 つのタスクが含まれています。

プレイブックの実行

次に、プレイブックを実行して、収集されたファクトを実際に見てみましょう。

cd ~/project/ansible
ansible-playbook -i hosts facts_playbook.yml

次のような出力が表示されるはずです。

PLAY [Show System Facts] *****************************************************

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

TASK [Display operating system] **********************************************
ok: [localhost] => {
    "msg": "Operating System: Ubuntu 22.04"
}

TASK [Display CPU information] ***********************************************
ok: [localhost] => {
    "msg": "CPU: Intel(R) Xeon(R) CPU with 2 cores"
}

TASK [Display memory information] ********************************************
ok: [localhost] => {
    "msg": "Total Memory: 3907 MB"
}

TASK [Display Python version] ************************************************
ok: [localhost] => {
    "msg": "Python version: 3.10.6"
}

PLAY RECAP *******************************************************************
localhost                  : ok=5    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

出力の最初のタスクに注目してください:TASK [Gathering Facts]。これは、gather_facts のデフォルト値が true であるため、Ansible が定義されたタスクを実行する前に自動的にファクトを収集していることを示しています。

次に、プレイブックは、収集されたファクトを使用してシステムに関する情報を正常に表示します。各ファクトは、ansible_ プレフィックスが付いた変数を使用して参照されます。

パフォーマンス向上のためのファクト収集の無効化

このステップでは、ファクトが不要な状況で、プレイブックのパフォーマンスを向上させるためにファクト収集を無効にする方法を学びます。

ファクト収集を無効にするタイミングの理解

ファクト収集は便利ですが、特定のシナリオでは不要なオーバーヘッドを追加する可能性があります。

  • システム情報を必要としない単純なタスクを実行する場合
  • プレイブックを頻繁に実行し、ファクトが変更されない場合
  • プレイブックの実行時間を最適化したい場合

ファクト収集を無効にすると、特に複数のホストを管理する場合、プレイブックの実行速度を大幅に向上させることができます。

ファクト収集が無効になっているプレイブックの作成

ファクト収集が無効になっている新しいプレイブックを作成しましょう。

  1. WebIDE で、/home/labex/project/ansible ディレクトリに移動します。
  2. no_facts_playbook.yml という名前の新しいファイルを作成します。
  3. 次の内容を追加します。
---
- name: Playbook with Disabled Fact Gathering
  hosts: local
  gather_facts: false

  tasks:
    - name: Display current time
      command: date
      register: current_time

    - name: Show the current time
      debug:
        msg: "Current time is: {{ current_time.stdout }}"

    - name: List files in the project directory
      command: ls -la ~/project
      register: file_list

    - name: Show file list
      debug:
        msg: "Project directory contents:\n{{ file_list.stdout }}"

このプレイブックは次のとおりです。

  • gather_facts: false でファクト収集を明示的に無効にします。
  • システムファクトに依存しないコマンドを実行します。
  • register キーワードを使用して、コマンド出力をキャプチャします。
  • debug モジュールを使用して、キャプチャされた情報を表示します。

ファクト収集が無効になっているプレイブックの実行

プレイブックを実行して、違いを観察しましょう。

cd ~/project/ansible
ansible-playbook -i hosts no_facts_playbook.yml

次のような出力が表示されるはずです。

PLAY [Playbook with Disabled Fact Gathering] *********************************

TASK [Display current time] **************************************************
changed: [localhost]

TASK [Show the current time] *************************************************
ok: [localhost] => {
    "msg": "Current time is: Wed May 17 15:30:45 UTC 2023"
}

TASK [List files in the project directory] ***********************************
changed: [localhost]

TASK [Show file list] ********************************************************
ok: [localhost] => {
    "msg": "Project directory contents:\ntotal 20\ndrwxr-xr-x 3 labex labex 4096 May 17 15:25 .\ndrwxr-xr-x 4 labex labex 4096 May 17 15:20 ..\ndrwxr-xr-x 2 labex labex 4096 May 17 15:25 ansible\n"
}

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

今回は出力に Gathering Facts タスクがないことに注目してください。プレイブックは、最初に定義されたタスクから直接開始します。

実行時間の比較

パフォーマンスの違いを確認するために、簡単なタイミングスクリプトを作成しましょう。

  1. WebIDE で、/home/labex/project/ansible ディレクトリに移動します。
  2. compare_timing.sh という名前の新しいファイルを作成します。
  3. 次の内容を追加します。
#!/bin/bash

echo "Running playbook with fact gathering enabled..."
time ansible-playbook -i hosts facts_playbook.yml > /dev/null

echo -e "\nRunning playbook with fact gathering disabled..."
time ansible-playbook -i hosts no_facts_playbook.yml > /dev/null
  1. スクリプトを実行可能にします。
chmod +x compare_timing.sh
  1. 比較スクリプトを実行します。
./compare_timing.sh

ファクト収集が無効になっているプレイブックが、ファクト収集が有効になっているプレイブックよりも速く実行されることを示す出力が表示されるはずです。この簡単な例では違いは小さいかもしれませんが、複数のリモートホストで複雑なプレイブックを実行する場合は、大きな違いになる可能性があります。

選択的なファクト収集の使用

場合によっては、すべてのシステム情報ではなく、特定のファクトのみが必要になることがあります。Ansible では、必要な情報を収集しながら、パフォーマンスを最適化するために選択的なファクト収集が可能です。

ファクトサブセットの理解

Ansible は、ファクトを次のようなサブセットに整理します。

  • all: すべてのファクト(デフォルト)
  • min / minimal: 最小限のファクトセット
  • hardware: CPU、メモリ、およびデバイス情報
  • network: ネットワークインターフェースとルーティング情報
  • virtual: 仮想化の詳細
  • ohai: Ohai からのファクト(利用可能な場合)
  • facter: Facter からのファクト(利用可能な場合)

必要なファクトのみを選択することで、必要な情報にアクセスしながら、プレイブックのパフォーマンスを向上させることができます。

選択的なファクト収集を使用したプレイブックの作成

ハードウェア関連のファクトのみを収集するプレイブックを作成しましょう。

  1. WebIDE で、/home/labex/project/ansible ディレクトリに移動します。
  2. selective_facts_playbook.yml という名前の新しいファイルを作成します。
  3. 次の内容を追加します。
---
- name: Selective Fact Gathering
  hosts: local
  gather_facts: true
  gather_subset:
    - "!all" ## Exclude all facts by default
    - "hardware" ## Then include only hardware facts

  tasks:
    - name: Display CPU information
      debug:
        msg: "CPU: {{ ansible_processor[1] }} with {{ ansible_processor_cores }} cores"

    - name: Display memory information
      debug:
        msg: "Total Memory: {{ ansible_memtotal_mb }} MB"

    - name: Try to access network facts (should fail)
      debug:
        msg: "Default IPv4 Address: {{ ansible_default_ipv4.address }}"
      ignore_errors: true

このプレイブックは次のとおりです。

  • gather_facts: true でファクト収集を有効にします。
  • gather_subset を使用して、収集するファクトを制限します。
  • まず、!all ですべてのファクトを除外します。
  • 次に、hardware でハードウェアファクトのみを含めます。
  • 制限を示すために、ネットワークファクト(収集されなかった)にアクセスしようとします。

選択的なファクト収集を使用したプレイブックの実行

プレイブックを実行して、選択的なファクト収集を実際に見てみましょう。

cd ~/project/ansible
ansible-playbook -i hosts selective_facts_playbook.yml

次のような出力が表示されるはずです。

PLAY [Selective Fact Gathering] **********************************************

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

TASK [Display CPU information] ***********************************************
ok: [localhost] => {
    "msg": "CPU: Intel(R) Xeon(R) CPU with 2 cores"
}

TASK [Display memory information] ********************************************
ok: [localhost] => {
    "msg": "Total Memory: 3907 MB"
}

TASK [Try to access network facts (should fail)] *****************************
fatal: [localhost]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'address'..."}
...ignoring

PLAY RECAP *******************************************************************
localhost                  : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=1

最初の 2 つのタスクは、収集されたハードウェアファクトにアクセスするため成功しますが、3 番目のタスクは、ネットワークファクトが収集されなかったため失敗することに注意してください。このエラーが発生してもプレイブックの実行を続行するために、ignore_errors: true を使用しました。

複数のファクトサブセットを使用したプレイブックの作成

次に、ハードウェアとネットワークの両方のファクトを収集するプレイブックを作成しましょう。

  1. WebIDE で、multiple_subsets_playbook.yml という名前の新しいファイルを作成します。
  2. 次の内容を追加します。
---
- name: Multiple Fact Subsets
  hosts: local
  gather_facts: true
  gather_subset:
    - "!all" ## Exclude all facts by default
    - "hardware" ## Include hardware facts
    - "network" ## Include network facts

  tasks:
    - name: Display CPU information
      debug:
        msg: "CPU: {{ ansible_processor[1] }} with {{ ansible_processor_cores }} cores"

    - name: Display memory information
      debug:
        msg: "Total Memory: {{ ansible_memtotal_mb }} MB"

    - name: Display network information
      debug:
        msg: "Default IPv4 Address: {{ ansible_default_ipv4.address }}"

このプレイブックを実行します。

ansible-playbook -i hosts multiple_subsets_playbook.yml

今回は、ハードウェアとネットワークの両方のファクトを収集したため、すべてのタスクが成功するはずです。

収集されたファクトを条件付きタスクで使用する

収集されたファクトの最も強力な使用方法の 1 つは、プレイブックで条件付きロジックを実装することです。このステップでは、実行するタスクを決定するためにファクトを使用するプレイブックを作成します。

Ansible での条件付きタスクの理解

Ansible では、when キーワードを使用して、変数、ファクト、またはタスクの結果に基づいてタスクを条件付きで実行できます。これにより、より動的で適応性の高いプレイブックを作成できます。

条件付きタスクを使用したプレイブックの作成

オペレーティングシステムに基づいて異なるアクションを実行するプレイブックを作成しましょう。

  1. WebIDE で、/home/labex/project/ansible ディレクトリに移動します。
  2. conditional_facts_playbook.yml という名前の新しいファイルを作成します。
  3. 次の内容を追加します。
---
- name: Conditional Tasks Based on Facts
  hosts: local
  gather_facts: true

  tasks:
    - name: Display OS information
      debug:
        msg: "Running on {{ ansible_distribution }} {{ ansible_distribution_version }}"

    - name: Task for Ubuntu systems
      debug:
        msg: "This is an Ubuntu system. Would run apt commands here."
      when: ansible_distribution == "Ubuntu"

    - name: Task for CentOS systems
      debug:
        msg: "This is a CentOS system. Would run yum commands here."
      when: ansible_distribution == "CentOS"

    - name: Task for systems with at least 2GB RAM
      debug:
        msg: "This system has {{ ansible_memtotal_mb }} MB RAM, which is sufficient for our application."
      when: ansible_memtotal_mb >= 2048

    - name: Task for systems with less than 2GB RAM
      debug:
        msg: "This system has only {{ ansible_memtotal_mb }} MB RAM, which may not be sufficient."
      when: ansible_memtotal_mb < 2048

このプレイブックは次のとおりです。

  • システムに関するすべてのファクトを収集します。
  • オペレーティングシステム情報を表示します。
  • オペレーティングシステムのタイプに基づいてタスクを条件付きで実行します。
  • RAM の量に基づいてタスクを条件付きで実行します。

条件付きプレイブックの実行

プレイブックを実行して、条件付きタスクを実際に見てみましょう。

cd ~/project/ansible
ansible-playbook -i hosts conditional_facts_playbook.yml

Ubuntu で実行しているため、次のような出力が表示されるはずです。

PLAY [Conditional Tasks Based on Facts] **************************************

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

TASK [Display OS information] ************************************************
ok: [localhost] => {
    "msg": "Running on Ubuntu 22.04"
}

TASK [Task for Ubuntu systems] ***********************************************
ok: [localhost] => {
    "msg": "This is an Ubuntu system. Would run apt commands here."
}

TASK [Task for CentOS systems] ***********************************************
skipping: [localhost]

TASK [Task for systems with at least 2GB RAM] ********************************
ok: [localhost] => {
    "msg": "This system has 3907 MB RAM, which is sufficient for our application."
}

TASK [Task for systems with less than 2GB RAM] *******************************
skipping: [localhost]

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

条件に基づいて、一部のタスクが実行され、他のタスクがスキップされることに注目してください。CentOS タスクは、Ubuntu で実行しているためスキップされ、「2GB RAM 未満」タスクは、システムに 2GB RAM 以上があるためスキップされます。

より実用的な例の作成

次に、実際の環境で使用できる、より実用的な例を作成しましょう。

  1. WebIDE で、practical_conditional_playbook.yml という名前の新しいファイルを作成します。
  2. 次の内容を追加します。
---
- name: Practical Conditional Playbook
  hosts: local
  gather_facts: true

  vars:
    app_dir: "/home/labex/project/app"

  tasks:
    - name: Create application directory
      file:
        path: "{{ app_dir }}"
        state: directory
        mode: "0755"

    - name: Configure for production environment
      copy:
        dest: "{{ app_dir }}/config.yml"
        content: |
          environment: production
          memory_limit: high
          debug: false
      when: ansible_memtotal_mb >= 4096

    - name: Configure for development environment
      copy:
        dest: "{{ app_dir }}/config.yml"
        content: |
          environment: development
          memory_limit: low
          debug: true
      when: ansible_memtotal_mb < 4096

    - name: Display configuration
      command: cat {{ app_dir }}/config.yml
      register: config_content

    - name: Show configuration
      debug:
        msg: "{{ config_content.stdout_lines }}"

このプレイブックは次のとおりです。

  • アプリケーションのディレクトリを作成します。
  • 利用可能なシステムメモリに基づいて、異なる構成ファイルを書き込みます。
  • 結果の構成を表示します。

実用的なプレイブックを実行します。

ansible-playbook -i hosts practical_conditional_playbook.yml

この例は、収集されたファクトを使用して、システム特性に基づいて構成を自動的に適応させる方法を示しています。

まとめ

この実験では、Ansible プレイブックで gather_facts オプションを効果的に設定し、使用する方法を学びました。これまでの成果をまとめます。

  1. 基本的なファクト収集: Ansible をインストールし、デフォルトのファクト収集の動作を調べ、Ansible が収集する幅広いシステム情報を確認しました。

  2. ファクト収集の無効化: ファクトが不要な場合に、プレイブックのパフォーマンスを向上させるために、ファクト収集を無効にする方法を学びました。

  3. 選択的なファクト収集: パフォーマンスと必要な情報の両立を図るために、特定のファクトサブセットのみを収集する方法を発見しました。

  4. 条件付きタスク: 収集されたファクトに基づいて、プレイブックに条件付きロジックを実装し、システムの特性に応じた動的な動作を可能にしました。

  5. 実用的なアプリケーション: 実際のシナリオで収集されたファクトを使用する方法を示す実用的な例を作成しました。

gather_facts オプションを習得することで、必要なシステム情報にアクセスしながら、Ansible プレイブックを最適化してパフォーマンスを向上させることができます。この知識は、より効率的で柔軟かつ強力な自動化ワークフローを作成するのに役立ちます。

覚えておくべきいくつかのベストプラクティス:

  • 必要な場合にのみファクト収集を有効にする
  • 特定の情報のみが必要な場合は、選択的なファクト収集を使用する
  • プレイブックをより適応性の高いものにするために、収集されたファクトを条件付きタスクに活用する
  • 同じホストでプレイブックを頻繁に実行する場合は、ファクトのキャッシュを検討する

これらのスキルを習得することで、インフラストラクチャ管理のニーズに合わせて、より洗練された効率的な Ansible 自動化を作成する準備が整いました。