てくなべ (tekunabe)

ansible / network / automation / StackStorm

[Ansible] template モジュールの基本的な使い方(Jinja2テンプレートからファイル生成)

■ はじめに

Ansible には、Jinja2 というテンプレートエンジンによるテンプレートファイルを利用してファイルを生成してリモートに送れる template モジュール があります。httpd.conf などの設定ファイルを、変数とテンプレートから生成するといった用途に利用できます。

この記事では、 template モジュールの公式ドキュメントに記載されている使用例をベースにして、使い方を説明します。

なお、公式ドキュメントの使用例は、Playbook 単位ではなくtask 単位で記載されています。この記事では Playbook 単位で例示します。

動作確認環境

  • Ansible 2.3.0, 2.7.8
  • CentOS 7.6 (Ansible 側、管理対象ホスト側とも)

目次


■ [例1] 単純にテンプレートからファイルを生成して送る

Playbook

Jinja2 テンプレートファイル foo.j2 を元にファイルを生成して、リモートに /etc/file.conf として送る Playbook です。

- hosts: linux
  gather_facts: no
  become: yes

  tasks:
    # Example from Ansible Playbooks
    - template:
        src: ./foo.j2
        dest: /etc/file.conf
        owner: bin
        group: wheel
        mode: 0644

  vars:
    test_name: Ansible
  • src オプション
    • もととなる Jinja2 テンプレートファイル名を指定します。(必須)
    • 今回指定している ./foo.j2 の内容は後述します。
  • dest オプション
    • 送り先のリモートのファイル名を指定します。(必須)
  • onwer オプション
    • リモートファイルの所有者を指定します。
  • group オプション
    • リモートファイルの所有グループを指定します。
  • mode オプション
    • リモートファイルの mode を指定します。
    • 8進数で指定する場合は、0644 のように 0 から始めるか、'644' のようにクォーテーションで囲う必要があります。
    • u=rw,g=r,o=r のような指定もできます。

使用するテンプレートファイル (./foo.j2)は以下のとおりです。

Hello, {{ test_name }}!

{{ test_name }} には、今回の場合 Playbook 内の vars ディレクティブ で指定した変数 test_name の値が展開されます。

Jinja2 の書式の詳細は、Jinja2 のドキュメントを確認してください。

本タスクで指定していないその他のオプション例

  • backup オプション
    • dest オプションで指定したリモートのファイルがすでに存在する場合に、バックアップをとるかどうか指定するオプションです。(デフォルト no
    • バックアップファイルの名前はタイムスタンプを含むものになります。

実行ログ

ここでは、リモートに /etc/file.conf が存在しない状態で Playbook を実行します。

  • Ansible 側
$ ansible-playbook -i inventory template_simple.yml 

PLAY [linux] ******************************************************************************

TASK [template] ***************************************************************************
changed: [linux1]

PLAY RECAP ********************************************************************************
linux1                     : ok=1    changed=1    unreachable=0    failed=0   
  • リモート上の確認
$ cat /etc/file.conf
Hello, Ansible!
$ ls -al /etc/file.conf
-rw-r--r--. 1 bin wheel 16 Mar  3 05:44 /etc/file.conf

無事に /etc/file.conf が生成され、テンプレートで指定した変数 {{ test_name }} も展開されました。 所有者やパーミッションも指定したとおりになりました。

なお、この後もう一度同じ Playbook を実行した場合は、すでに同じ内容、権限 になっていることを検出して、とくに何もしません。そのため、対象ファイルの更新日時も変わりません。


■ [例2] 正しい内容に生成されるかを事前に検証する

Playbook

Jinja2 テンプレートファイル sudoers.j2 を元にファイルを生成して、リモートに /etc/file.conf として送って適用する前に /usr/sbin/visudo -cf %s コマンドでファイルのフォーマットを確認する Playbook です。

- hosts: linux
  gather_facts: no
  become: yes

  tasks:
    # Copy a new "sudoers" file into place, after passing validation with visudo
    - template:
        src: ./sudoers.j2
        dest: /etc/sudoers
        validate: '/usr/sbin/visudo -cf %s'

  vars:
    wheel_group_name: wheel
  • src オプション
    • もととなる Jinja2 テンプレートファイル名を指定します。(必須)
    • 今回指定している ./sudoers.j2 の内容は後述します。
  • dest オプション
    • 送り先のリモートのファイル名を指定します。(必須)
  • validate オプション
    • 生成したファイルの内容が正しいか検証するためのコマンドを指定します。対象を %s で指定します。
    • ファイルの内容のフォーマットエラーが、システムへ大きく影響するためあらじめ検証たい場合に利用できます。

使用するテンプレートファイル (./sudoers.j2)は以下のとおりです。

(...略...)
%{{ wheel_group_name }}  ALL=(ALL)       ALL
(...略...)

{{ wheel_group_name }} には、今回の場合 Playbook 内の vars ディレクティブ で指定した変数 wheel_group_name の値が展開されます。

実行ログ

  • Ansible 側
$ ansible-playbook -i inventory template_validate.yml            

PLAY [linux] ********************************************************************************************************

TASK [template] *****************************************************************************************************
changed: [linux1]

PLAY RECAP **********************************************************************************************************
linux1                     : ok=1    changed=1    unreachable=0    failed=0   
  • リモート上の確認
$ sudo cat /etc/sudoers
(...略...)
%wheel  ALL=(ALL)       ALL
(...略...)

無事に /etc/sudoers が生成され、テンプレートで指定した変数 {{ wheel_group_name }} も展開されました。


■ まとめ

公式ドキュメントの使用例をベースにして、template モジュール の使い方を説明しました。

他に「こんなことできるかな?」と気になる事がありましたら、公式ドキュメントで詳細をご確認ください。

docs.ansible.com

また、template モジュールは Files modules に分類されています。Files modules には、他にも、指定した正規表現にマッチするすべての文字列を置換する replace や、行単位で編集する lineinfile などのモジュールがあります。詳細は Files modules の一覧からご確認ください。