ansible-lint is a tool to check Ansible Playbook.
ansible-lint checks playbooks for practices and behaviour that could
potentially be improved. As a community backed project ansible-lint supports
only the last two major versions of Ansible.
Please read Contribution guidelines if you wish to contribute.
The code in the ansible-lint repository is licensed under the MIT license. If you contribute to this repository, that license applies to your contributions.
The ansible-lint project also imports the Ansible python module, which is licensed under the GPLv3 license. Because of this import, the GPLv3 rules apply to the full distribution of ansible-lint. We maintain the MIT license on the repository so we can fully use an MIT license in the future if we ever remove the runtime dependency on Ansible code.
Installing the ansible-lint python package does not install any GPL dependencies, all of them are listed as extras.
ansible-lint was created…
It helps you to find syntax problems like extra spaces or lines, or point out where doesn't follow Ansible best practice.
[koh@kohs-MBP] ~/work/linttest % ansible-lint site.yml  Trailing whitespace site.yml:6 msg: hello  Package installs should not use latest site.yml:8 Task/Handler: install httpd [koh@kohs-MBP] ~/work/linttest %
Below is the list of default rules.
But each playbook or teams might have their own rules that oppose to Ansible best practice.
Here is how to configure ansible-lint.
*Version of ansible-lint is
Rules are configurable with options of ansible-lint command.
[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 %
Basically, you can configure everything with command line options but it is better to use a configuration file to share with your team, or to implement into CI.
Next is how to configure with a file.
It should be placed at
./.ansible-lint by default, or a file which specified with the option
This is an example from the official doc.
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
Specify paths or files to exclude from lint.
Change the format of the output.
Each error will be converted to one line.
# parseable: false [koh@kohs-MBP] ~/work/linttest % ansible-lint site.yml  Trailing whitespace /Users/koh/work/linttest/roles/201/tasks/main.yml:4 msg: hello  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  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 %
Not completely 0 but a bit reduced.
# quiet: true [koh@kohs-MBP] ~/work/linttest % ansible-lint site.yml  /Users/koh/work/linttest/roles/201/tasks/main.yml:4  /Users/koh/work/linttest/roles/202/tasks/main.yml:2  /Users/koh/work/linttest/roles/203/tasks/main.yml:4 [koh@kohs-MBP] ~/work/linttest %
Specify files or directories in which you put original rule files.
Specify tags or error IDs that should be skipped.
You can check about tags with
[koh@kohs-MBP] ~/work/linttest % ansible-lint -T ANSIBLE0002 [''] ANSIBLE0004 [''] ANSIBLE0005 [''] ANSIBLE0006 [''] ANSIBLE0007 [''] ANSIBLE0008 [''] ANSIBLE0009 [''] ANSIBLE0010 [''] ANSIBLE0011 [''] ANSIBLE0012 [''] ANSIBLE0013 [''] ANSIBLE0014 [''] ANSIBLE0015 [''] ANSIBLE0016 [''] ANSIBLE0017 [''] ANSIBLE0018 [''] ANSIBLE0019 [''] behaviour [''] bug [''] command-shell ['', '', '', '', '', ''] deprecated ['', '', '', '', ''] formatting ['', '', '', '', '', '', ''] idempotency [''] idiom ['', ''] metadata ['', '', '', ''] module ['', '', '', ''] oddity [''] readability [''] repeatability ['', '', ''] resources ['', ''] safety [''] task ['', '', '', ''] [koh@kohs-MBP] ~/work/linttest %
Opposite of skip_list, specify tags that you want to check.
If True, default rules are applied.
If you want to check only your original rules, set it to False.
Specify the verbosity of the output.
It only takes 2 kinds of values which are 0 or greater than 0.
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))
By adding a comment, you can skip checks by lines.
Below is an example of the 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 %
This playbook throws 403 error.
[koh@kohs-MBP] ~/work/linttest % ansible-lint site.yml  Package installs should not use latest site.yml:4 Task/Handler: install latest httpd [koh@kohs-MBP] ~/work/linttest %
If you really want to keep your httpd updated but not other packages, you can do like below. (you still should not do that though.)
[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, the line will be skipped from checks.
[koh@kohs-MBP] ~/work/linttest % ansible-lint site.yml [koh@kohs-MBP] ~/work/linttest %
You can create your own rules.
There are some explanations on README and also I recommend you to have a look at scripts of the default rules.
Here is my example of how to create my own rule.
[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 can take
true to set
True for boolean.
With this rule, it throws errors if
true are used.
*This is a really cheap script only for this explanation please use it with your own risk.
[koh@kohs-MBP] ~/work/linttest % cat .ansible-lint rulesdir: - ./origrules/ [koh@kohs-MBP] ~/work/linttest %
With this site.yml, it throws 2 errors as intended.
[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  Use "True" for boolean site.yml:8 enabled: yes  Use "True" for boolean site.yml:14 enabled: true [koh@kohs-MBP] ~/work/linttest %
Creating own rules is much easier than I expected.
So it is good to try one.