ansible-lintの設定
ansible-lintというAnsibleのPlaybookの問題点を指摘してくれるツールがあります。
無駄なスペースを検知してくれたり、Playbookのベストプラクティスに沿わないような記載を指摘してくれます。
[koh@kohs-MBP] ~/work/linttest % ansible-lint site.yml [201] Trailing whitespace site.yml:6 msg: hello [403] Package installs should not use latest site.yml:8 Task/Handler: install httpd [koh@kohs-MBP] ~/work/linttest %
デフォルトルールの一覧はこちらです。
Playbookの書き方や運用の仕方によっては特定のルールを無視したり別途ルールを追加したりしたい場合もあると思います。
そのための設定方法についてまとめました。
※ ansible-lintのバージョンは 4.1.0
をもとに説明しています。
コマンドラインでの設定
コマンドラインのオプションでも各ルールを設定できます。
オプション一覧(クリックで展開)
[koh@kohs-MBP] ~/work/linttest
% ansible-lint --help
Usage: ansible-lint [options] playbook.yml [playbook2 ...]
Options:
--version show program's version number and exit
-h, --help show this help message and exit
-L list all the rules
-q quieter, although not silent output
-p parseable output in the format of pep8
--parseable-severity parseable output including severity of rule
-r RULESDIR specify one or more rules directories using one or
more -r arguments. Any -r flags override the default
rules in
/Users/koh/.pyenv/versions/3.7.3/lib/python3.7/site-
packages/ansiblelint/rules, unless -R is also used.
-R Use default rules in
/Users/koh/.pyenv/versions/3.7.3/lib/python3.7/site-
packages/ansiblelint/rules in addition to any extra
rules directories specified with -r. There is no need
to specify this if no -r flags are used
-t TAGS only check rules whose id/tags match these values
-T list all the tags
-v Increase verbosity level
-x SKIP_LIST only check rules whose id/tags do not match these
values
--nocolor disable colored output
--force-color Try force colored output (relying on ansible's code)
--exclude=EXCLUDE_PATHS
path to directories or files to skip. This option is
repeatable.
-c C Specify configuration file to use. Defaults to
".ansible-lint"
[koh@kohs-MBP] ~/work/linttest
%
基本的にはコマンドラインでのオプションですべて設定できるのですが、チームでルールを共有したりCIに組み込んだりする際には設定ファイルに指定するケースが多いと思います。
設定ファイルでの記載方法について書いていきます。
設定ファイル
デフォルトでは ./.ansible-lint
、もしくはオプション -c
で指定したファイルになります。
公式の例はこのような形になっています。
exclude_paths: - ./my/excluded/directory/ - ./my/other/excluded/directory/ - ./last/excluded/directory/ parseable: true quiet: true rulesdir: - ./rule/directory/ skip_list: - skip_this_tag - and_this_one_too - skip_this_id - '401' tags: - run_this_tag use_default_rules: true verbosity: 1
https://docs.ansible.com/ansible-lint/configuring/configuring.html#configuration-file
それぞれの設定項目について説明していきます。
exclude_paths (--exclude)
チェックから除外するパス/ファイルを指定します。
parseable (-p)
出力の形式を変更できます。
複数行に分かれているものが1行にまとまります。
# parseable: false [koh@kohs-MBP] ~/work/linttest % ansible-lint site.yml [201] Trailing whitespace /Users/koh/work/linttest/roles/201/tasks/main.yml:4 msg: hello [202] Octal file permissions must contain leading zero or be a string /Users/koh/work/linttest/roles/202/tasks/main.yml:2 Task/Handler: error 202 [203] Most files should not contain tabs /Users/koh/work/linttest/roles/203/tasks/main.yml:4 msg: " tab" [koh@kohs-MBP] ~/work/linttest %
# parseable: true [koh@kohs-MBP] ~/work/linttest % ansible-lint site.yml /Users/koh/work/linttest/roles/201/tasks/main.yml:4: [E201] Trailing whitespace /Users/koh/work/linttest/roles/202/tasks/main.yml:2: [E202] Octal file permissions must contain leading zero or be a string /Users/koh/work/linttest/roles/203/tasks/main.yml:4: [E203] Most files should not contain tabs [koh@kohs-MBP] ~/work/linttest %
quiet (-q)
出力形式を変更できます。
0にはなりませんが少し減ります。
# quiet: true [koh@kohs-MBP] ~/work/linttest % ansible-lint site.yml [201] /Users/koh/work/linttest/roles/201/tasks/main.yml:4 [202] /Users/koh/work/linttest/roles/202/tasks/main.yml:2 [203] /Users/koh/work/linttest/roles/203/tasks/main.yml:4 [koh@kohs-MBP] ~/work/linttest %
rulesdir (-r)
自作のruleを格納したファイル/ディレクトリを指定できます。
自作ruleについては後述します。
skip_list (-x)
スキップするタグやエラーIDを指定できます。
タグについては -T
オプションで一覧を出力できます。
タグ一覧(クリックで展開)
[koh@kohs-MBP] ~/work/linttest
% ansible-lint -T
ANSIBLE0002 ['[201]']
ANSIBLE0004 ['[401]']
ANSIBLE0005 ['[402]']
ANSIBLE0006 ['[303]']
ANSIBLE0007 ['[302]']
ANSIBLE0008 ['[103]']
ANSIBLE0009 ['[202]']
ANSIBLE0010 ['[403]']
ANSIBLE0011 ['[502]']
ANSIBLE0012 ['[301]']
ANSIBLE0013 ['[305]']
ANSIBLE0014 ['[304]']
ANSIBLE0015 ['[104]']
ANSIBLE0016 ['[503]']
ANSIBLE0017 ['[501]']
ANSIBLE0018 ['[101]']
ANSIBLE0019 ['[102]']
behaviour ['[503]']
bug ['[304]']
command-shell ['[305]', '[302]', '[304]', '[306]', '[301]', '[303]']
deprecated ['[105]', '[104]', '[103]', '[101]', '[102]']
formatting ['[104]', '[203]', '[201]', '[204]', '[206]', '[205]', '[202]']
idempotency ['[301]']
idiom ['[601]', '[602]']
metadata ['[701]', '[704]', '[703]', '[702]']
module ['[404]', '[401]', '[403]', '[402]']
oddity ['[501]']
readability ['[502]']
repeatability ['[401]', '[403]', '[402]']
resources ['[302]', '[303]']
safety ['[305]']
task ['[502]', '[503]', '[504]', '[501]']
[koh@kohs-MBP] ~/work/linttest
%
tags (-t)
skip_listの逆でこの値が指定された場合は指定されたタグのみチェックします。
ちなみにskip_listとtags両方に同じ値を設定するとスキップされるみたいです。
use_default_rules (-R)
trueの場合デフォルトのルールが適用されます。
自作のルールのみチェックしたい場合にはfalseに指定します。
verbosity (-v)
出力の詳細度を指定できます。
数値で出力量が変わりそうに見えますが現状0か1以上かでのみ挙動が変わりそうです。
for file in files: if self.verbosity > 0: print("Examining %s of type %s" % (file['path'], file['type'])) matches.extend(self.rules.run(file, tags=set(self.tags), skip_list=self.skip_list))
Playbook内での設定
Playbook内でコメントを入れることにより行単位でチェック対象から外すことができます。
例として下記のようなPlaybookを作成します。
[koh@kohs-MBP] ~/work/linttest % cat site.yml --- - hosts: all tasks: - name: install latest httpd yum: name: httpd state: latest - name: install mysql yum: name: mysql state: installed [koh@kohs-MBP] ~/work/linttest %
このPlaybookに対してansible-lintを実行すると403のエラーが返されます。
[koh@kohs-MBP] ~/work/linttest % ansible-lint site.yml [403] Package installs should not use latest site.yml:4 Task/Handler: install latest httpd [koh@kohs-MBP] ~/work/linttest %
どうしてもhttpdは常に最新にしておきたいけど他のパッケージはlatestにはしたくないといったとき(多分無い)には下記のように記載できます。
[koh@kohs-MBP] ~/work/linttest % cat site.yml --- - hosts: all tasks: - name: install latest httpd yum: name: httpd state: latest # noqa 403 - name: install mysql yum: name: mysql state: installed [koh@kohs-MBP] ~/work/linttest %
実際にエラーを返す行に # noqa ID
とコメントを入れるとチェック対象から除外されます。
[koh@kohs-MBP] ~/work/linttest % ansible-lint site.yml [koh@kohs-MBP] ~/work/linttest %
自作ルール
ansible-lint用のルールを自作することができます。
READMEにも作成の仕方が記載されていますが、デフォルトルールのスクリプトを参考にするとわかりやすいと思います。
https://github.com/ansible/ansible-lint#creating-custom-rules
https://github.com/ansible/ansible-lint/tree/master/lib/ansiblelint/rules
試しに一つ自作ルールを作成してみます。
適当なディレクトリを作成してルール用のスクリプトを作成します。
[koh@kohs-MBP] ~/work/linttest % cat origrules/True4BooleanRule.py from ansiblelint import AnsibleLintRule class True4BooleanRule(AnsibleLintRule): id = '99' shortdesc = 'Use "True" for boolean' description = 'We should "True" for boolean not "yes" or "true".' tags = ['formatting'] def match(self, file, line): return ': yes' in line or ': true' in line [koh@kohs-MBP] ~/work/linttest %
PlaybookではbooleanのTrueを指定する際に True
以外にも yes
, true
なども使用できます。
このルールでは先頭大文字の True
に統一するべく yes
, true
を検知してエラーを出します。
※例のためのスクリプトなのでかなり雑に書いています。使用する際には適宜修正してください。
.ansible-lint
に下記のように記載します。
[koh@kohs-MBP] ~/work/linttest % cat .ansible-lint rulesdir: - ./origrules/ [koh@kohs-MBP] ~/work/linttest %
site.ymlを下記のようにすると3つのタスクのうち上2つが目論見通りエラーになります。
[koh@kohs-MBP] ~/work/linttest % cat site.yml --- - hosts: all tasks: - name: this should be error service: name: httpd state: started enabled: yes - name: this should be error too service: name: mysqld state: started enabled: true - name: this is ok service: name: haproxy state: started enabled: True [koh@kohs-MBP] ~/work/linttest % ansible-lint site.yml [99] Use "True" for boolean site.yml:8 enabled: yes [99] Use "True" for boolean site.yml:14 enabled: true [koh@kohs-MBP] ~/work/linttest %
まとめ
設定ファイルでの各パラメータの説明等が公式ドキュメントに見当たらなかったのでまとめてみました。
自作ルールの作成が思ったよりも簡単だったので色々試してみたいですね。