Memo/Ansible/Jinja2

https://dexlab.net:443/pukiwiki/index.php?Memo/Ansible/Jinja2
 

Jinja2 template

  • pythonのテンプレートエンジン

raw, !unsafe: jinja2のエスケープを無効にして読む


ansibleが使っているjinja2バージョンの確認

  • ansible v2.7.1
    • jinja v2.7.2
  • action_plugins/jin_ver.py
    from ansible.plugins.action import ActionBase
    import jinja2
    
    class ActionModule(ActionBase):
        def run(self, tmp=None, task_vars=None):
            result = super(ActionModule, self).run(tmp, task_vars)
            return dict(jinja_version=jinja2.__version__)
  • playbook.yml
    - hosts: localhost
      connection: local
      gather_facts: no
      tasks:
        - action: jin_ver
          register: result
        - debug: msg="{{ result }}"
  • 実行結果
    ansible-playbook playbook.yml
    ...
    TASK [debug] ************************************************************************************************************************************
    ok: [localhost] => {
        "msg": {
            "changed": false, 
            "failed": false, 
            "jinja_version": "2.7.2"
        }
    }

sort(), dictsort(), reverse(): list、dictのソート

  • sort()
    • 「reverse=True」オプションはansible 2.7.1で使えた。
  • dictsort()
    • 「by='key'|'value'」を指定する。
    • 「reverse=True」オプションはjinja2 v2.10.0から使えるようだ。ansible 2.7.1のjinja2は「v2.7.2」だったので使えなかった。
  • reverse()
    • 逆順で出力。
    • 「dictvar | dictsort(by='value') | reverse」は結果が「"<listreverseiterator object at 0x7f070004c990>」のようになり使えなかった。
  • playbook.yml
    - hosts: localhost
      gather_facts: no
      connection: local
      vars:
        listvar:
        - Node:
            Node: test-c
            Id: c
        - Node:
            Node: test-b
            Id: b
        - Node:
            Node: test-a
            Id: a
        dictvar:
          NodeA: 10
          NodeB: 1
          NodeC: 2
      tasks:
        - name: sort of Node.Node
          debug:
            msg: "{{ listvar | sort(attribute='Node.Node') }}"
    
        - name: dictsort of value
          debug:
            msg: "{{ dictvar | dictsort(by='value') }}"
  • 結果
    ansible-playbook playbook.yml
    ...
    TASK [dictsort of value] ************************************************************************************************************************
    ok: [localhost] => {
        "msg": [
            [
                "NodeB", 
                1
            ], 
            [
                "NodeC", 
                2
            ], 
            [
                "NodeA", 
                10
            ]
        ]
    }
    
    TASK [dictsort of value] ************************************************************************************************************************
    ok: [localhost] => {
        "msg": [
            [
                "NodeB", 
                1
            ], 
            [
                "NodeC", 
                2
            ], 
            [
                "NodeA", 
                10
            ]
        ]
    }
    ...

loopコントロール

  • List of Control Structures
    • 通常の言語のような「break」「continue」が無いようだ。
    • 代わりに「for var in list if var == '' 」の構文がある
  • list中の'aa'だけを出力
{% set list_var1 = ['aa','bb','cc'] %}
{% for var1 in list_var1 if var1 == 'aa' %}
{{ var1 }}
{% endfor %}

jinja2での正規表現

regex_search, regex_findallが使えるようだ

  • 記事

jinja2テンプレートでの三項演算子

  • example_enabledがbooleanの場合、{{ example_enabled }} と記載すると 'True/False' が出力される。'yes/no'を出力するようにしたい。
lineinfile:
    dest=/tmp/example.conf
    line={{ item }}
    with_items:
    - 'example_enabled={{ "yes" if example_enabled else "no" }}'
  • または example_enabled: 'yes' と明示的に文字列して定義する
  • playbook内での例: yum_proxy変数によって、present, absentを切り替える。
ini_file:
    dest: /etc/yum.conf
    section: main
    option: proxy
    value: "{{ yum_proxy }}"
    state: "{{ 'present' if yum_proxy != None else 'absent' }}"
    backup: yes
  • v2.2.1.0: 「yum_proxy:」のように空変数だと、valueに「None」が入るのでabsentにしている。

行頭、行末のホワイトスペースの制御

Whitespace Control - Jinja2 Documentation (2.10)

  • ホワイトスペースの制御。制御構文の前後をそれぞれ別々に制御できる
    • {%- , -%} : ホワイトスペースを削除
    • {%+ , +%} : ホワイトスペースを追加(lstrip_blocksの無効化)

Template テンプレート

  • 例: stateが未定義の時のデフォルトを「present」にする
debug: msg="{{ item.state | default('present') }}"
  • 変数が空の場合。
  • 変数:「var1:」
  • template:「{{ var1 }}」
  • v1.9: 「None」
  • v2.0: 「」
  • ini_fileはv2.2.1.0でも「None」になる。モジュールによって違うようだ
  • コメント: {# ... #}
  • roles/example/tasks/main.yml
- name: config file
  template:
    src: example.conf.j2
    dest: /etc/example/example.conf
    owner: root
    group: root
    mode: 0644
    backup: yes
  • roles/example/templates/example.conf.j2
{{ ansible_distribution }}
  • 他roleのテンプレートも参照できる。例:role:test1 から role:test2のテンプレートを参照
cat roles/test1/tasks/main.yml
- template: src=roles/test2/templates/text2.j2 dest=/tmp/test2.conf mode=0644
  • ansible_managed テンプレート展開時にansibleのシグネチャが入る。ファイルをansibleが管理しているというコメントを埋め込む事ができる。
# {{ ansible_managed }}
  • 展開前
    {% if item1 != "" %}
        item1={{ item1 }}{% endif %}{% if item2 != "" %}
        item2={{ item2 }}
    {% endif %}
  • 展開後
        item1=aaa
        item2=bbb
  • 変数の前後の空白削除: {{ var1 | trim }}

if: 条件分岐

  • 変数に定数が含まれていたらで分岐する
    {% if 'description:' in item.stdout %}
    replace: description
    {% else %}
    add: description
    {% endif %}
    • 1行で書く場合
      {{ 'replace' if 'description:' in item.stdout else 'add' }}: description

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2018-12-18 (火) 19:24:53 (10h)