dotfilesでAnsibleを使っていてansible-lintも入れていた(v5)
v6に上げるとそもそも実行できないなどの問題が発生したのでしばらく上げてなかったが重い腰を上げて対応した
色々変更したので作業ログを残しておく、どこかの誰かの参考程度にでもなれば嬉しい…
実行環境のバージョン
$ ansible-lint --version ansible-lint 6.17.0 using ansible-core:2.15.0 ruamel-yaml:0.17.31 ruamel-yaml-clib:0.2.7
Python 3.10.6
v6に上げて実行してみる
WARNING Listing 488 violation(s) that are fatal
途方もない…
自動修正
$ ansible-lint --write hoge.yml
--write
オプションを渡すことで対象のファイルと、関連するroleなどのファイルも修正してくれる
自動修正後の警告
WARNING Listing 147 violation(s) that are fatal
かなり減った
- 自動修正の内容が分かるPR
feature/migration ansible lint v6 by swfz · Pull Request #794 · swfz/dotfiles
ansibleを実行できるところまでエラーを潰していく
lintだけだし大丈夫かなと思ったら怒られた
include
ERROR! this task 'ansible.builtin._include' has extra params, which is only allowed in the following modules: ansible.legacy.import_role, ansible.builtin.shell, ansible.legacy.win_command, ansible.legacy.add_host, import_role, ansible.legacy.include_tasks, raw, meta, ansible.legacy.meta, group_by, ansible.windows.win_command, ansible.builtin.set_fact, ansible.legacy.script, ansible.builtin.include_role, ansible.builtin.script, ansible.legacy.include_role, ansible.legacy.include, ansible.builtin.win_shell, ansible.builtin.import_role, include_role, ansible.builtin.win_command, ansible.legacy.command, ansible.windows.win_shell, ansible.builtin.group_by, command, ansible.legacy.include_vars, ansible.builtin.add_host, ansible.builtin.include_tasks, ansible.legacy.set_fact, win_shell, ansible.legacy.import_tasks, ansible.builtin.include_vars, script, include_tasks, ansible.builtin.raw, ansible.builtin.import_tasks, shell, win_command, include_vars, set_fact, ansible.builtin.meta, ansible.builtin.command, ansible.legacy.raw, include, ansible.builtin.include, import_tasks, ansible.legacy.group_by, ansible.legacy.shell, add_host, ansible.legacy.win_shell The error appears to be in '/usr/local/src/ansible/roles/git/tasks/main.yml': line 2, column 3, but may be elsewhere in the file depending on the exact syntax problem. The offending line appears to be: --- - name: Debian tasks ^ here
--write
オプションでモジュールの指定をFCQNへ変換してくれたようだが、include
は対応されてなかった模様
変換したら_include
になっていたがそもそもないよって話っぽい、自動書き換えができないものに関しては_
付けるようになっているのかも?
移行先としてはinclude_tasks
,include_vars
などがあるみたいだったが今回はinclude_tasks
が適切そうだったので手で書き換えた
- 差分
- name: Redhat tasks - ansible.builtin._include: redhat.yml + ansible.builtin.include_tasks: redhat.yml when: ansible_os_family == 'RedHat'
handlerへの通知指定
--write
で各設定ファイル中のname
の値は1文字目を大文字にするというルールが適用された
その結果、handlerで指定するタスク名が変更されずに「ないよ!」というエラーが発生した
- tasks/main.yml
- name: Set config ansible.builtin.template: src=smb.conf dest=/etc/samba/smb.conf mode=0644 register: samba_config - notify: restart samba + notify: Restart samba
- handlers/main.yml
--- - name: Restart samba ansible.builtin.service: name=smb state=restarted when: ansible_env.get('CI', None) and ansible_env.CI != "true"
最初の文字大文字推奨するんであればこの辺も対応してよ…って感じはするが
expected input
- anyenv/tasks/main.yml
ansible.builtin.expect: command: "{{ ansible_env.HOME }}/.anyenv/libexec/anyenv install --init" responses: - .*Do you want to checkout.*: true + '.*Do you want to checkout.*': y
--write
オプションで書き換えられてたので戻した
ansible-lintの設定を見る
設定ファイルのドキュメント
この辺読みつつ対応する
Configuration - Ansible Lint Documentation
出力フォーマット
$ ansible-lint -f json ubuntu.yml > lint.json
jsonフォーマットもしくはsarifフォーマットじゃないと詳しい情報が出てこない
- pep8フォーマット
centos.yml:2: name[play] centos.yml:32: yaml[comments]
なるほど…
- jsonフォーマット
[ { "type": "issue", "check_name": "name[play]", "categories": [ "idiom" ], "url": "https://ansible-lint.readthedocs.io/rules/name/", "severity": "major", "description": "All plays should be named.", "fingerprint": "5493323e150e33e04cd3e881e653620fcb888eade98f89d020f35fc837272cee", "location": { "path": "centos.yml", "lines": { "begin": 2 } } }, { "type": "issue", "check_name": "yaml[comments]", "categories": [ "formatting", "yaml" ], "url": "https://ansible-lint.readthedocs.io/rules/yaml/", "severity": "major", "description": "Too few spaces before comment", "fingerprint": "fac9d557e84fefa8205a6aec84c3749120882c6d54f90889c945f349afc1959f", "location": { "path": "centos.yml", "lines": { "begin": 32 } } },
既存の警告をignoreする
とりあえず、動かすところを目的としたいので、すべてIgnoreに放り込んで少しずつ対応できるようにする
$ ansible-lint --nocolor centos.yml codespace.yml mac.yml ubuntu.yml > lint.txt $ cat lint.txt | awk -F"[: ]" '{print $1 " " $4}' | sort | uniq > .ansible-lint-ignore
これで
- .ansible-lint-ignore
centos.yml yaml[comments] roles/actionlint/tasks/main.yml var-naming[no-role-prefix] roles/actionlint/tasks/main.yml yaml[comments]
こんな感じになる
この状態でlintを実行すると次のようになる
$ ansible-lint centos.yml codespace.yml mac.yml ubuntu.yml WARNING Listing 140 violation(s) marked as ignored, likely already known centos.yml:33: yaml[comments] (warning) roles/actionlint/tasks/main.yml:2: var-naming[no-role-prefix] (warning) roles/actionlint/tasks/main.yml:2: yaml[comments] (warning) roles/actionlint/tasks/main.yml:10: var-naming[no-role-prefix] (warning)
検知はしているがignoreしているよというメッセージが出力される
marked as ignored, likely already known
ということで終了コードは0になる(fatal errorが存在する場合は終了コード2だった)
既存の警告の解消
yaml[comments]
コメントの前に2つ以上スペース入れろってやつ
--write
で自動修正したやつすべて警告対象になってた
自動修正とは?…
- 修正PR
feature/ansible lint comments by swfz · Pull Request #796 · swfz/dotfiles
var-naming[no-role-prefix]
変数はroleのprefixを入れろって言っている
ツールのバージョンチェックをする箇所で同じような命名規則にしていたのですべて警告対象になった
- 修正差分(role名: actionlint)
ansible.builtin.shell: command -v actionlint environment: PATH: /usr/local/bin:{{ ansible_env.PATH }} - register: exist_actionlint + register: actionlint_exist changed_when: false ignore_errors: true ansible.builtin.shell: actionlint --version | head -n 1 environment: PATH: /usr/local/bin:{{ ansible_env.PATH }} - register: version_in_actionlint + register: actionlint_current_version changed_when: false ignore_errors: true - when: exist_actionlint.rc == 0 + when: actionlint_exist.rc == 0 - block: - name: Get tar.gz - name: Install changed_when: true ansible.builtin.command: mv /tmp/actionlint /usr/local/bin/actionlint - when: exist_actionlint.rc != 0 or ( version_in_actionlint is defined and version_in_actionlint.stdout.find(actionlint_version) == -1 ) + when: actionlint_exist.rc != 0 or ( actionlint_current_version is defined and actionlint_current_version.stdout.find(actionlint_version) == -1 )
他にも結構量があったのでsedで書き換えたい
lint.txt
はpep8フォーマットで出力したファイル
cat lint.txt | grep no-role-prefix | awk -F":" '{print $1}' | uniq | xargs sed -i 's/\(exist\)_\([a-z]*\)/\2_\1/g' cat lint.txt | grep no-role-prefix | awk -F":" '{print $1}' | uniq | xargs sed -i 's/\(version_in\)_\([a-z]*\)/\2_current_version/g'
いくつか命名規則に沿っていないものもあったので手動で修正した
- 修正PR
feature/ansible lint var naming by swfz · Pull Request #797 · swfz/dotfiles
name[missing]
blockにもname
が必要らしい
- 対象PR
feature/ansible lint name missing by swfz · Pull Request #798 · swfz/dotfiles
key-order[task]
key-order - Ansible Lint Documentation
キー名のルール
- nameは一番初めにしないといけない
block,rescue,alwaysは最後にしないといけない
対象PR
feature/ansible lint key order by swfz · Pull Request #799 · swfz/dotfiles
no-free-form
1行に色々パラメータ含めて書くなってやつ
- name: Configure make install jo - ansible.builtin.command: chdir=/tmp/{{ jo.dir }} {{ item }} + ansible.builtin.command: + chdir: /tmp/{{ jo.dir }} + cmd: "{{ item }}" changed_when: true with_items: - ./configure
キーによって変数はクオートしないといけない? っぽいのがある模様
適切なクオートができていないと次のように構文エラーとなってしまい解析できなかった
ansible-lint roles/jo/tasks/main.yml WARNING Listing 1 violation(s) that are fatal roles/jo/tasks/main.yml:1: load-failure[runtimeerror]
少し詰まった
- 対象PR
feature/ansible lint no free form by swfz · Pull Request #801 · swfz/dotfiles
risky-file-permission
risky-file-permissions - Ansible Lint Documentation
get_url
などで取得できるファイルのpermissionを明示的に指定しろって話っぽい
- 対象PR
feature/ansible lint risky file permission by swfz · Pull Request #800 · swfz/dotfiles
no-changed-when
no-changed-when - Ansible Lint Documentation
コマンド系のモジュール使用時に、changedにする条件を指定する
- 対象PR
feature/ansible lint no changed when by swfz · Pull Request #802 · swfz/dotfiles
command-instead-of-shell
command-instead-of-shell - Ansible Lint Documentation
それ本当にshell使う必要あるの?ってやつ
環境変数の拡張やパイプを使った複数のコマンドの連結などを使わない場合はcomandにしてねという感じ
command-instead-of-module
command-instead-of-module - Ansible Lint Documentation
それコマンドじゃなくてモジュールでできるよね?ってやつ
- 対象PR
feature/ansible lint command instead of module by swfz · Pull Request #806 · swfz/dotfiles
jinja[spacing]
jinja - Ansible Lint Documentation
jinjaテンプレートで記述する箇所に適切なスペースをいれてねというやつ
- 対象PR
feature/ansible lint jinja by swfz · Pull Request #808 · swfz/dotfiles
おわり
つかれた