Ansible include_vars 代替手法:vars, set_fact, lookup の使い分け

2025-05-27

Ansibleの "include_vars" モジュールとは?

"include_vars" モジュールは、Ansibleのタスク内で、外部のファイルから変数を動的に読み込むために使用されます。これにより、設定ファイルやデータファイルに定義された変数を、Playbookの実行中に利用できるようになります。

主な機能と利点

  • 条件付き読み込み
    whenディレクティブを使用して、特定の条件が満たされた場合にのみ変数を読み込むことができます。
  • 変数の上書き
    複数のファイルから同じ変数を読み込む場合、後から読み込まれたファイルの値で上書きされます。
  • 複数の変数ファイルの利用
    複数のファイルから変数を読み込むことができます。これにより、変数の管理を柔軟に行えます。
  • 設定ファイルの分離
    Playbookのロジックと設定データを分離できます。これにより、Playbookの可読性と保守性が向上します。
  • 変数の動的な読み込み
    Playbookの実行時に、指定されたファイルから変数を読み込みます。これにより、環境や状況に応じて異なる変数を適用できます。

使用例

- name: 変数ファイルを読み込む
  include_vars:
    file: vars/my_vars.yml

この例では、"vars/my_vars.yml" ファイルから変数を読み込みます。

ファイル形式

"include_vars" モジュールで読み込むファイルは、YAML形式またはJSON形式である必要があります。

例 (vars/my_vars.yml)

app_name: "MyApp"
app_version: "1.2.3"

Playbookでの利用例

- hosts: all
  tasks:
    - name: 変数ファイルを読み込む
      include_vars:
        file: vars/my_vars.yml

    - name: アプリケーション名を表示
      debug:
        msg: "アプリケーション名: {{ app_name }}"

    - name: アプリケーションバージョンを表示
      debug:
        msg: "アプリケーションバージョン: {{ app_version }}"

このPlaybookを実行すると、"my_vars.yml" ファイルから読み込まれた "app_name" と "app_version" の値が表示されます。

条件付き読み込みの例

- hosts: all
  tasks:
    - name: 環境に応じた変数ファイルを読み込む
      include_vars:
        file: "vars/{{ env }}.yml"
      when: env is defined

この例では、"env" 変数が定義されている場合にのみ、環境に応じた変数ファイルを読み込みます。例えば、"env" が "production" の場合、"vars/production.yml" ファイルが読み込まれます。



一般的なエラーとトラブルシューティング

    • エラーメッセージ
      Could not find or access 'vars/my_vars.yml' のようなエラーが表示される。
    • 原因
      指定されたファイルパスが間違っているか、ファイルが存在しない。
    • 対処法
      • ファイルパスを再確認し、スペルミスがないか確認します。
      • ファイルが指定されたパスに存在するか確認します。
      • 相対パスを使用している場合は、Playbookの実行ディレクトリからの相対パスが正しいか確認します。
      • 絶対パスを使用している場合は、パスが正しいか確認します。
      • ファイルへの読み取り権限があることを確認します。
  1. ファイル形式が不正 (Invalid file format)

    • エラーメッセージ
      YAML error parsing file: vars/my_vars.ymlJSONDecodeError のようなエラーが表示される。
    • 原因
      指定されたファイルがYAMLまたはJSON形式で正しく記述されていない。
    • 対処法
      • YAMLまたはJSONの構文が正しいか確認します。
      • インデントが正しいか確認します (YAMLの場合)。
      • JSONファイルの場合、JSONLintなどのツールを使用してバリデーションを行います。
      • ファイルがUTF-8エンコーディングで保存されていることを確認します。
  2. 変数の上書きに関する問題 (Variable overriding issues)

    • 問題
      複数の "include_vars" タスクで同じ変数を読み込んだ場合、意図しない変数値が使用される。
    • 原因
      後から読み込まれたファイルの値で変数が上書きされるため、変数の優先順位を理解していない。
    • 対処法
      • 変数の優先順位を理解し、意図した変数値が使用されるように "include_vars" タスクの順序を調整します。
      • when ディレクティブを使用して、特定の条件が満たされた場合にのみ変数を読み込むようにします。
      • 変数名を明確にし、衝突を避けるようにします。
  3. 条件付き読み込みの問題 (Conditional loading issues)

    • 問題
      when ディレクティブを使用して条件付きで変数を読み込もうとしたが、変数が読み込まれない。
    • 原因
      when ディレクティブの条件が正しく評価されていない。
    • 対処法
      • when ディレクティブの条件式が正しいか確認します。
      • 条件式で使用している変数が定義されているか確認します。
      • debug モジュールを使用して、条件式の評価結果を確認します。
  4. 変数のスコープの問題 (Variable scope issues)

    • 問題
      "include_vars" で読み込んだ変数が、期待されるタスクやロールで利用できない。
    • 原因
      変数のスコープを理解していない。
    • 対処法
      • "include_vars" はタスクレベルで変数を読み込むため、そのタスク以降のタスクで利用可能です。
      • ロールのデフォルト変数やロール変数を適切に利用します。
      • vars セクションで変数を定義し、Playbook全体で利用できるようにします。
  5. パスの解釈の問題 (Path interpretation issues)

    • 問題
      変数でパスを組み立てて、include_varsで利用しようとした際に意図したファイルがよみこまれない。
    • 原因
      パスの解釈が意図した通りに行われていない。
    • 対処法
      • debugモジュールで変数の内容を確認する。
      • パスの組み立てが正しいか確認する。
      • パスの中に特殊文字が含まれる場合は、適切にエスケープされているか確認する。

トラブルシューティングの一般的な手順

  • Ansibleのドキュメントを参照する
    Ansibleの公式ドキュメントには、"include_vars" モジュールに関する詳細な情報が記載されています。
  • Playbookを段階的に実行する
    問題が発生する箇所を特定するために、Playbookを段階的に実行します。
  • debug モジュールを使用する
    変数の値や条件式の評価結果を表示します。
  • デバッグモードで実行する
    -vvv オプションを使用して、詳細なデバッグ情報を表示します。
  • エラーメッセージをよく読む
    エラーメッセージには、問題の原因に関する重要な情報が含まれています。


例1: 基本的な変数ファイルの読み込み

---
- hosts: localhost
  tasks:
    - name: 変数ファイルを読み込む
      include_vars:
        file: vars/my_vars.yml

    - name: 変数を出力する
      debug:
        msg: "アプリケーション名: {{ app_name }}, バージョン: {{ app_version }}"

vars/my_vars.yml

app_name: "My Application"
app_version: "1.2.3"

説明

  • debug モジュールを使用して、読み込んだ変数 app_nameapp_version の値を出力しています。
  • この例では、include_vars モジュールを使用して "vars/my_vars.yml" ファイルから変数を読み込んでいます。

例2: 複数の変数ファイルの読み込みと変数の上書き

---
- hosts: localhost
  tasks:
    - name: 基本的な変数ファイルを読み込む
      include_vars:
        file: vars/base_vars.yml

    - name: 環境固有の変数ファイルを読み込む
      include_vars:
        file: vars/{{ env }}_vars.yml
      when: env is defined

    - name: 変数を出力する
      debug:
        msg: "アプリケーション名: {{ app_name }}, 設定: {{ config_value }}"

vars/base_vars.yml

app_name: "Default App"
config_value: "default"

vars/production_vars.yml

app_name: "Production App"
config_value: "production"

実行コマンド

ansible-playbook my_playbook.yml -e "env=production"

説明

  • production_vars.ymlapp_nameconfig_value の値が上書きされるため、最終的に Production Appproduction が出力されます。
  • when: env is defined を使用して、env 変数が定義されている場合にのみ環境固有の変数ファイルを読み込むようにしています。
  • この例では、base_vars.ymlproduction_vars.yml の2つの変数ファイルを読み込んでいます。

例3: 条件付きで変数ファイルを読み込む

---
- hosts: localhost
  tasks:
    - name: OSの種類に応じて変数ファイルを読み込む
      include_vars:
        file: "vars/{{ ansible_os_family }}.yml"
      when: ansible_os_family is defined

    - name: 変数を出力する
      debug:
        msg: "OSファミリー: {{ ansible_os_family }}, OS固有の設定: {{ os_config }}"

vars/Debian.yml

os_config: "Debian specific settings"

vars/RedHat.yml

os_config: "RedHat specific settings"

説明

  • 例えば、ターゲットホストが Debian 系の場合、vars/Debian.yml が読み込まれます。
  • when: ansible_os_family is defined を使用して、ansible_os_family 変数が定義されている場合にのみ変数ファイルを読み込むようにしています。
  • この例では、ansible_os_family 変数の値に基づいて、異なる変数ファイルを読み込んでいます。

例4: 変数ファイル内の変数をパスとして使用する

---
- hosts: localhost
  tasks:
    - name: 変数ファイルからパスを読み込む
      include_vars:
        file: vars/path_vars.yml

    - name: 別の変数ファイルを読み込む
      include_vars:
        file: "{{ included_vars_path }}"

    - name: 変数を出力する
      debug:
        msg: "読み込んだ変数の値: {{ my_variable }}"

vars/path_vars.yml

included_vars_path: "vars/second_vars.yml"

vars/second_vars.yml

my_variable: "value from second file"
  • このようにして、変数ファイル内で定義されたパスを使用して、動的に別の変数ファイルを読み込むことができます。
  • 次の include_vars は、読み込んだ included_vars_path の値をパスとして使用して、vars/second_vars.yml を読み込みます。
  • 最初の include_varsincluded_vars_path 変数を読み込みます。


include_vars の代替方法

    • Playbookまたはロールの vars ディレクティブを使用して、静的に変数を定義できます。

    • 外部ファイルから変数を読み込むのではなく、Playbookまたはロール内に直接変数を記述します。

    • 利点

      • シンプルで直感的。
      • 静的な変数を定義するのに適しています。
    • 欠点

      • 変数の数が多くなると、Playbookまたはロールが煩雑になる可能性があります。
      • 変数の動的な読み込みには適していません。

    • ---
      - hosts: localhost
        vars:
          app_name: "My Application"
          app_version: "1.2.3"
        tasks:
          - name: 変数を出力する
            debug:
              msg: "アプリケーション名: {{ app_name }}, バージョン: {{ app_version }}"
      
  1. vars_files ディレクティブ

    • Playbookまたはロールの vars_files ディレクティブを使用して、外部ファイルから変数を読み込むことができます。

    • include_vars と同様に、外部ファイルから変数を読み込みますが、タスクレベルではなくPlaybookまたはロールレベルで読み込みます。

    • 利点

      • Playbookまたはロール全体で利用可能な変数を定義できます。
      • include_vars よりもスコープが広いです。
    • 欠点

      • タスクレベルでの動的な読み込みには適していません。

    • ---
      - hosts: localhost
        vars_files:
          - vars/my_vars.yml
        tasks:
          - name: 変数を出力する
            debug:
              msg: "アプリケーション名: {{ app_name }}, バージョン: {{ app_version }}"
      
  2. set_fact モジュール

    • set_fact モジュールを使用して、タスク内で動的に変数を定義できます。

    • 条件付きで変数を設定したり、他のタスクの結果に基づいて変数を設定したりできます。

    • 利点

      • 非常に柔軟性が高いです。
      • 動的な変数の定義に適しています。
    • 欠点

      • 複雑なロジックを記述する必要がある場合があります。

    • ---
      - hosts: localhost
        tasks:
          - name: OSの種類に基づいて変数を設定する
            set_fact:
              os_config: "Debian specific settings"
            when: ansible_os_family == "Debian"
      
          - name: 変数を出力する
            debug:
              msg: "OS固有の設定: {{ os_config }}"
      
  3. lookup プラグイン

    • lookup プラグインを使用して、外部ファイルやデータソースから変数を読み込むことができます。

    • file, fileglob, ini, json_query など、さまざまなlookupプラグインが用意されています。

    • 利点

      • 非常に強力で柔軟性があります。
      • さまざまなデータソースから変数を読み込むことができます。
    • 欠点

      • lookupプラグインの種類によっては、複雑な構文を記述する必要がある場合があります。

    • ---
      - hosts: localhost
        tasks:
          - name: ファイルから変数を読み込む
            set_fact:
              file_content: "{{ lookup('file', 'vars/my_vars.yml') }}"
      
          - name: 変数を出力する
            debug:
              msg: "ファイルの内容: {{ file_content }}"
      
  4. ロールのデフォルト変数とロール変数

    • ロールの defaults/main.yml ファイルにデフォルト変数を定義できます。
    • ロールの vars/main.yml ファイルにロール変数を定義できます。
    • 利点
      • ロールの再利用性を高めることができます。
      • ロールのカスタマイズを容易にします。
    • 欠点
      • ロールのスコープ内でしか利用できません。
  5. インベントリ変数

    • インベントリファイルまたはインベントリスクリプトを使用して、ホストまたはグループ固有の変数を定義できます。
    • 利点
      • ホストまたはグループ固有の設定を管理できます。
    • 欠点
      • インベントリの管理が必要になります。

適切な方法の選択

  • ホストまたはグループ固有の設定を管理する場合は、インベントリ変数を使用します。
  • ロールの再利用性を高める場合は、ロールのデフォルト変数とロール変数を使用します。
  • タスク内で動的に変数を定義する場合は、set_fact モジュールまたは lookup プラグインを使用します。
  • Playbookまたはロール全体で利用可能な変数を定義する場合は、vars_files ディレクティブを使用します。
  • 静的な変数を定義する場合は、vars ディレクティブを使用します。