てくなべ (tekunabe)

ansible / network automation / 学習メモ

[Ansible] ansible-lint で hosts ディレクティブに変数が含まれると発生するエラーの対処案2つ

はじめに

hosts: "{{ targets }}" のように、hosts に変数を利用していると、ansible-lint のチェックで変数未定義のエラーになってしまいます。

$ ansible-lint debug.yml 
WARNING  Listing 1 violation(s) that are fatal
syntax-check[specific]: The field 'hosts' has an invalid value, which includes an undefined variable. The error was: 'targets' is undefined. 'targets' is undefined
assert.yml:2:3


                  Rule Violation Summary                   
 count tag                    profile rule associated tags 
     1 syntax-check[specific] min     core, unskippable    

Failed: 1 failure(s), 0 warning(s) on 1 files.

これにひっかかると、他のチェックがされなくなるのでどうにかしたいところです。

かといって、このチェックは .config/ansible-lint.yml の設定の skip_list に指定してスキップすることはできません。

私が分かっている範囲では、これを回避するには2つの方法があります。

  • 検証環境
    • ansible-lint 6.22.2

対処案1: default フィルターを利用

ルール syntax-check の説明ページにもありますが、変数未定義時の代わりの値を指定する default フィルターを利用する方法です。これ自体はもともと Ansible でも利用できる機能です。

---
- name: Test play
  hosts: "{{ targets | default([]) }}"
  gather_facts: false
  connection: local

  tasks:
    - name: Debug
      ansible.builtin.debug:
        msg: Hello

こんな風にしておけば、変数未定義のエラーは起こらなくなります。

対処案2: ansible-lint としての extra_vars で定義しておく

対処案1では Playbook を修正する必要がありますが、修正したくない場合こちらの案が候補になります。

ansible-lint の設定ファイル内の extra_vars で変数を定義しておけばエラーは起こらなくなります。

  • .config/ansible.yml:
---
extra_vars:
  targets: []

Playbook は以下の通り。default フィルターは利用しません。

---
- name: Test play
  hosts: "{{ targets }}"
  gather_facts: false
  connection: local

  tasks:
    - name: Debug
      ansible.builtin.debug:
        msg: Hello

おわりに

設定ファイルが思いのほか気が利いてるので、一度目を通すと新しい発見があるかもしれません。

ansible.readthedocs.io

参考

関連 issue

github.com