Ansible Jinja2 テンプレート

AnsibleAnsibleBeginner
今すぐ練習

💡 このチュートリアルは英語版からAIによって翻訳されています。原文を確認するには、 ここをクリックしてください

はじめに

この実験では、Ansible で使用される強力なテンプレートエンジンである Jinja2 を学びます。Jinja2 を使うことで、動的なコンテンツを作成でき、Ansible のプレイブックをより柔軟で適応性の高いものにすることができます。この実験を終えると、Ansible で Jinja2 の構文をどのように使用するか、変数、フィルタ、条件分岐、ループを含めて理解するようになります。この知識を使って、より動的で効率的な Ansible のプレイブックと役割を作成できるようになります。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL ansible(("Ansible")) -.-> ansible/ModuleOperationsGroup(["Module Operations"]) ansible(("Ansible")) -.-> ansible/PlaybookEssentialsGroup(["Playbook Essentials"]) ansible/ModuleOperationsGroup -.-> ansible/template("Generate Files from Templates") ansible/PlaybookEssentialsGroup -.-> ansible/loop("Iteration") ansible/PlaybookEssentialsGroup -.-> ansible/playbook("Execute Playbook") subgraph Lab Skills ansible/template -.-> lab-390470{{"Ansible Jinja2 テンプレート"}} ansible/loop -.-> lab-390470{{"Ansible Jinja2 テンプレート"}} ansible/playbook -.-> lab-390470{{"Ansible Jinja2 テンプレート"}} end

Jinja2 の基本を理解する

Jinja2 は、Django のテンプレートをモデルにした、Python 向けの現代的でデザイナーにも親切なテンプレート言語です。Ansible では、Jinja2 を使ってファイルをテンプレート化し、動的なプレイ構造を作成したり、その他のことができます。

まずは簡単な Jinja2 テンプレートを作成してみましょう。まず、プロジェクトディレクトリに移動します。

cd ~/project

次に、テンプレート用のディレクトリを作成します。

mkdir templates
cd templates

hello.j2 という名前の新しいファイルを作成します。

nano hello.j2

次の内容を追加します。

Hello, {{ name }}!

Today is {{ ansible_date_time.date }}.
Your home directory is {{ ansible_env.HOME }}.

nano エディタを保存して終了します (Ctrl+X を押してから Y を押し、その後 Enter を押します)。

このテンプレートでは:

  • {{ name }} は、テンプレートがレンダリングされる際に実際の値に置き換えられる変数です。
  • {{ ansible_date_time.date }}{{ ansible_env.HOME }} は、自動的に埋められる Ansible のファクトです。

次に、このテンプレートを使用するためのプレイブックを作成しましょう。プロジェクトのルートに戻り、use_template.yml という名前の新しいファイルを作成します。

cd ~/project
nano use_template.yml

次の内容を追加します。

---
- name: Use Jinja2 template
  hosts: localhost
  vars:
    name: "Ansible Learner"
  tasks:
    - name: Create file from template
      template:
        src: templates/hello.j2
        dest: /tmp/hello.txt

このプレイブックは、template モジュールを使って Jinja2 テンプレートをレンダリングし、/tmp/hello.txt にファイルを作成します。

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

ansible-playbook use_template.yml

プレイブックを実行した後、作成されたファイルの内容を確認します。

cat /tmp/hello.txt

変数とファクトが実際の値に置き換えられたレンダリングされたテンプレートが表示されるはずです。

Jinja2 フィルタの使用

Jinja2 フィルタは、変数に適用できる関数です。変数とはパイプ記号 (|) で区切られます。Ansible には多くの組み込みフィルタがあり、自作のフィルタも作成できます。

いくつかの一般的なフィルタを示す新しいテンプレートを作成しましょう。filters.j2 という名前の新しいファイルを作成します。

cd ~/project/templates
nano filters.j2

次の内容を追加します。

1. 大文字変換フィルタ: {{ name | upper }}
2. 長さフィルタ: {{ name | length }}
3. デフォルトフィルタ: {{ optional_var | default('No value provided') }}
4. 結合フィルタ: {{ fruits | join(', ') }}
5. ランダムな要素: {{ fruits | random }}
6. 最初の要素: {{ fruits | first }}
7. JSON エンコード: {{ complex_data | to_json }}

次に、このテンプレートを使用するためのプレイブックを作成します。プロジェクトのルートに戻り、use_filters.yml という名前の新しいファイルを作成します。

cd ~/project
nano use_filters.yml

次の内容を追加します。

---
- name: Use Jinja2 filters
  hosts: localhost
  vars:
    name: "ansible learner"
    fruits:
      - apple
      - banana
      - cherry
    complex_data:
      key1: value1
      key2:
        - item1
        - item2
  tasks:
    - name: Create file from template
      template:
        src: templates/filters.j2
        dest: /tmp/filters.txt

    - name: Display file contents
      command: cat /tmp/filters.txt
      register: file_contents

    - name: Show file contents
      debug:
        var: file_contents.stdout_lines

このプレイブックは、さまざまな Jinja2 フィルタを変数に適用し、結果を表示します。

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

ansible-playbook use_filters.yml

出力には、各フィルタが入力データをどのように変更するかが示されます。これは、テンプレート内のデータを操作するためにフィルタをどのように使用するかを示しています。

Jinja2 の条件分岐

Jinja2 を使うと、テンプレート内で条件文を使用できます。特定の条件に基づいてコンテンツを含めるか除外する必要がある場合には、これは特に便利です。

conditionals.j2 という名前の新しいテンプレートファイルを作成します。

cd ~/project/templates
nano conditionals.j2

次の内容を追加します。

{% if user_type == 'admin' %}
Welcome, Administrator!
You have full access to the system.
{% elif user_type == 'user' %}
Welcome, User!
You have limited access to the system.
{% else %}
Welcome, Guest!
You have read-only access to the system.
{% endif %}

{% if fruits %}
Available fruits:
{% for fruit in fruits %}
  - {{ fruit }}
{% endfor %}
{% else %}
No fruits available.
{% endif %}

次に、このテンプレートを使用するためのプレイブックを作成します。プロジェクトのルートに戻り、use_conditionals.yml という名前の新しいファイルを作成します。

cd ~/project
nano use_conditionals.yml

次の内容を追加します。

---
- name: Use Jinja2 conditionals
  hosts: localhost
  vars:
    user_type: "admin"
    fruits:
      - apple
      - banana
      - cherry
  tasks:
    - name: Create file from template (admin)
      template:
        src: templates/conditionals.j2
        dest: /tmp/conditionals_admin.txt

    - name: Create file from template (user)
      template:
        src: templates/conditionals.j2
        dest: /tmp/conditionals_user.txt
      vars:
        user_type: "user"

    - name: Create file from template (guest)
      template:
        src: templates/conditionals.j2
        dest: /tmp/conditionals_guest.txt
      vars:
        user_type: "guest"
        fruits: []

    - name: Display file contents
      command: "cat {{ item }}"
      loop:
        - /tmp/conditionals_admin.txt
        - /tmp/conditionals_user.txt
        - /tmp/conditionals_guest.txt
      register: file_contents

    - name: Show file contents
      debug:
        var: file_contents.results[item].stdout_lines
      loop: [0, 1, 2]

このプレイブックは、同じテンプレートを使用して異なる変数値で 3 つの異なるファイルを作成し、テンプレート内の条件文がどのように機能するかを示しています。

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

ansible-playbook use_conditionals.yml

出力には、異なる条件に基づいてテンプレートコンテンツがどのように変化するかが示されます。

Jinja2 のループ

Jinja2 は、リストや辞書を反復処理するためのループ構文を提供します。変数データに基づいて繰り返しコンテンツを生成する必要がある場合には、これは特に便利です。

loops.j2 という名前の新しいテンプレートファイルを作成します。

cd ~/project/templates
nano loops.j2

次の内容を追加します。

1. 単純なループ:
{% for item in simple_list %}
   - {{ item }}
{% endfor %}

2. インデックス付きのループ:
{% for item in simple_list %}
   {{ loop.index }}. {{ item }}
{% endfor %}

3. 辞書を反復処理するループ:
{% for key, value in simple_dict.items() %}
   {{ key }}: {{ value }}
{% endfor %}

4. ネストしたループ:
{% for category, items in nested_dict.items() %}
   {{ category }}:
   {% for item in items %}
     - {{ item }}
   {% endfor %}
{% endfor %}

5. ループ内の条件分岐:
{% for item in simple_list %}
   {% if loop.first %}最初の項目: {% endif %}
   {% if loop.last %}最後の項目: {% endif %}
   {{ item }}
{% endfor %}

次に、このテンプレートを使用するためのプレイブックを作成します。プロジェクトのルートに戻り、use_loops.yml という名前の新しいファイルを作成します。

cd ~/project
nano use_loops.yml

次の内容を追加します。

---
- name: Use Jinja2 loops
  hosts: localhost
  vars:
    simple_list:
      - apple
      - banana
      - cherry
    simple_dict:
      name: John Doe
      age: 30
      city: New York
    nested_dict:
      fruits:
        - apple
        - banana
      vegetables:
        - carrot
        - potato
  tasks:
    - name: Create file from template
      template:
        src: templates/loops.j2
        dest: /tmp/loops.txt

    - name: Display file contents
      command: cat /tmp/loops.txt
      register: file_contents

    - name: Show file contents
      debug:
        var: file_contents.stdout_lines

このプレイブックは、Jinja2 テンプレートでループを使用するさまざまな方法を示しています。

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

ansible-playbook use_loops.yml

出力には、テンプレート内の異なるループ構文が提供された変数に基づいてどのようにコンテンツを生成するかが示されます。

高度な Jinja2 の技法

この最後のステップでは、マクロやフィルタを含む、いくつかの高度な Jinja2 の技法を探ります。マクロは、プログラミング言語の関数に似た、再利用可能なテンプレートの断片です。

advanced.j2 という名前の新しいテンプレートファイルを作成します。

cd ~/project/templates
nano advanced.j2

次の内容を追加します。

{% macro render_list(title, items) %}
{{ title }}:
{% for item in items %}
  - {{ item }}
{% endfor %}
{% endmacro %}

1. マクロの使用:
{{ render_list("Fruits", fruits) }}

{{ render_list("Vegetables", vegetables) }}

2. set の使用:
{% set greeting = "Hello, " + name + "!" %}
{{ greeting }}

3. カスタムフィルタ (プレイブックで定義):
{{ complex_data | to_nice_json }}

4. 空白の制御:
{% for item in fruits -%}
    {{ item }}
{%- if not loop.last %}, {% endif %}
{%- endfor %}

5. 生のブロック (処理なし):
{% raw %}
This {{ will_not_be_processed }}
{% endraw %}

6. 別のテンプレートをインクルード:
{% include'simple_include.j2' %}

次に、簡単なインクルードファイルを作成します。simple_include.j2 という名前の新しいファイルを作成します。

nano simple_include.j2

次の内容を追加します。

This is content from an included template.
Current user: {{ ansible_user_id }}

次に、この高度なテンプレートを使用するためのプレイブックを作成します。プロジェクトのルートに戻り、use_advanced.yml という名前の新しいファイルを作成します。

cd ~/project
nano use_advanced.yml

次の内容を追加します。

---
- name: Use advanced Jinja2 techniques
  hosts: localhost
  vars:
    name: "Ansible Expert"
    fruits:
      - apple
      - banana
      - cherry
    vegetables:
      - carrot
      - potato
      - broccoli
    complex_data:
      key1: value1
      key2:
        - item1
        - item2
    custom_filters:
      to_nice_json: "{{ '(' ~ ((complex_data | to_json) | replace('\"', '\\\"')) ~ ')' | from_json | to_nice_json }}"
  tasks:
    - name: Create file from template
      template:
        src: templates/advanced.j2
        dest: /tmp/advanced.txt

    - name: Display file contents
      command: cat /tmp/advanced.txt
      register: file_contents

    - name: Show file contents
      debug:
        var: file_contents.stdout_lines

このプレイブックは、マクロ、カスタムフィルタ、空白の制御、そして他のテンプレートのインクルードを含む、高度な Jinja2 の技法を示しています。

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

ansible-playbook use_advanced.yml

出力には、これらの高度な Jinja2 の技法が実際にどのように機能するかが示されます。

まとめ

この実験では、Ansible で Jinja2 テンプレートを調べ、幅広い機能と技法を学びました。以下が主な要点です。

  1. Jinja2 の基本構文:テンプレートで変数と Ansible のファクトをどのように使用するかを学びました。
  2. Jinja2 フィルタ:テンプレート内のデータを操作するためのさまざまな組み込みフィルタを調べました。
  3. 条件分岐:if-elif-else 文を使って、条件に基づいて動的なコンテンツを作成しました。
  4. ループ:リストや辞書を反復処理する方法、ネストしたループやループ制御を学びました。
  5. 高度な技法:マクロ、カスタムフィルタ、空白の制御、生のブロック、そしてテンプレートのインクルードを調べました。

これらの Jinja2 の機能により、Ansible で非常に動的で柔軟なテンプレートを作成できます。これらを使って、さまざまなシナリオやデータ入力に対応できる設定ファイル、スクリプト、その他のコンテンツを生成できます。

Ansible を使い続けるうちに、Jinja2 テンプレートをマスターすることが、効率的で適応力のあるプレイブックとロールを作成するために不可欠であることがわかります。これにより、より簡潔で保守しやすいコードを書くことができ、繰り返しを減らし、Ansible プロジェクトをよりスケーラブルにすることができます。

Jinja2 は強力ですが、柔軟性と読みやすさをバランスさせることが重要です。あまりに複雑なテンプレートは保守しにくいので、テンプレートの設計には常に明確さを追求しましょう。

これらの Jinja2 の機能を Ansible プロジェクトで練習してみると、ますます複雑な自動化タスクを簡単に処理できるようになります。