てくなべ (tekunabe)

ansible / network automation / 学習メモ

[Ansible] ansible-lint 経由の yamllint と、直接 yamllint する場合とではデフォルトルールが異なる

はじめに

ansible-lint にはは、yamllint を呼んで YAML としてのチェックをする機能があります。

たとえば、1行あたりの文字数が何文字以内であるべきか、真偽値はどう指定するべきか、などのルールです。

うすうす感じていた(?)のですが、ansible-lint 経由で yamllint を呼んでチェックするときと、直接 yamllint でチェックするときとでは、デフォルトのルールが異なります。

Ansible London 19th April 2022 の動画の、24:55 頃からのスライド で、そういうことか、と知りました。

  • 環境
    • ansible-lint 6.14.4
    • yamllint 1.30.0

それぞれ比較してみる

試しに以下の Playbook をチェックします。

---
- name: Hello
  hosts: localhost
  gather_facts: false

  tasks:
    - name: Hello
      ansible.builtin.debug:
        msg: very long message very long message very long message very long message very long message

なお、各 linter の設定ファイル(.yamllint.config/ansible-lint.yml など)は用意しない状態ではじめます。

直接 yamlllint

まず、直接 yamllint でチェックします。

$ yamllint hello.yml
hello.yml
  9:81      error    line too long (102 > 80 characters)  (line-length)

長い行がエラーとして検出されました。

ansible-lint 経由の yamllint

次に ansible-lint 経由のチェックです。

$ ansible-lint hello.yml 

Passed with production profile: 0 failure(s), 0 warning(s) on 1 files.

特に問題なく Passed となりました。終了コードも 0 でした。

これらの結果から、少なくとも、1行あたりの文字数のチェックについては挙動が異なることが分かります。

どこで定義されている?

では、ansible-lint 経由の場合、yamllint 単体のデフォルト設定をどこで変えているのだろうと気になって、探してみたのですが src/ansiblelint /yaml_utils.py の中のようです。

extends: default
rules:
  comments:
    # https://github.com/prettier/prettier/issues/6780
    min-spaces-from-content: 1
  # https://github.com/adrienverge/yamllint/issues/384
  comments-indentation: false
  document-start: disable
  # 160 chars was the default used by old E204 rule, but
  # you can easily change it or disable in your .yamllint file.
  line-length:
    max: 160
  # We are adding an extra space inside braces as that's how prettier does it
  # and we are trying not to fight other linters.
  braces:
    min-spaces-inside: 0  # yamllint defaults to 0
    max-spaces-inside: 1  # yamllint defaults to 0
  octal-values:
    forbid-implicit-octal: true  # yamllint defaults to false
    forbid-explicit-octal: true  # yamllint defaults to false

https://github.com/ansible/ansible-lint/blob/v6.14.4/src/ansiblelint/yaml_utils.py#L43-L62 より)

今回試した line-length 以外の変更点としては、ドキュメントは --- で始めること(document-start)というルールも無効化されていました(yamllint 単体としてはデフォルトで有効)。

ansible-lint 経由のデフォルトから変える場合

yamllint 単体で実行するときと同様、設定ファイル.yamllint.yamllint.yaml.yamllint.yml ・・・(略)の優先順で読み込まれる)で設定しておきます。

その yamllint の設定ファイルの内容と、例の ansible-lint 経由で yamllint を実行する場合の設定をマージ(上書きではなく)するようです。

github.com

マージなので、もし yamllint 単体としてのデフォルト値に戻したい場合、yamllint の設定ファイルに明示的に設定が必要なのかなと思います。たとえば line-length80 に戻すのであれば、

rules:
  line-length:
    max: 80

のように。

もしかしたらもっといい方法があるかもしれません。

おわりに

ansible-lint から yamllint も呼ばれると、別々に実行しなくて便利ですね。今回試したように、デフォルト値が異なるという事情はありますが、扱い方を知っておけば特に問題なさそうです。