Ansible-Lint: Die Fusselbürste

Bild: Ansible Logo

Frei übersetzt könnte man Ansible-Lint auch als die Ansible Fusselbürste übersetzen. Das real physikalische Pondon wird ja meist benutzt um z.B. Tierhaare oder Schuppen von angesagter dunkler Kleidung nachhaltig zu bekommen. Gehässige Stimmen meinen nun, mit Ansible-Lint würde es sich ähnlich verhalten, man könne nur geringfügige „Schmutzpartikel“ entfernen. Ansible-Lint kann aber bei richtiger Betrachtung, Verwendung und Bewertung der gemeldeten „Promlemstellungen“ doch mehr.

Beim linting werden mit Hilfe eines statischen Code-Analyse-Tools können stilistische Fehler im Code aufgespürt werden und kommt häufig bei dynamisch typisierte Sprachen wie JavaScript und Python zum Einsatz. Das Kommandozeilen-Tool ansible-lint richtet sich an alle Ansible-Nutzer die wert darauf legen, ihre Playbooks, Rollen und Code-Sammlungen entsprechend einheitlich, strukturiert und code-technisch sauber zu halten. Das Hauptziel, welches hier verfolgt wird ist, bewährte Praktiken, Muster und Verhaltensweisen zu fördern sowie gleichzeitig häufige Fallstricke zu vermeiden, die leicht zu Fehlern führen und dabei die Wartung des Codes erschweren können.

Natürlich sind dabei die Ergebnisse und Rückmeldungen, die beim ansible-lint-Aufruf zurückgemeldet werden, nicht der Weisheit letzten Schluss. Diese sollten immer individuell bewerten, entsprechende Fehler im Code korrigiert werden, oder auch Konfigurationsoptionen bei Ansible-Lint gesetzt werden, die spezifische false-positive Meldungen unterdrücken.

Bevor wir uns nun eingehender mit ansible-lint beschäftigen installieren wir das Programm-Paket mit Hilfe des Paketverwaltungs-Tools unserer Distribution.

  • Arch :
     $ pacman -S ansible-lint
  • Fedora / RHEL :
     # yum install ansible-lint
  • Gentoo :
     # emerge -av ansible-lint
  • openSUSE :
     $ sudo zypper in ansible-lint
  • Ubuntu / Debian :
     $ sudo apt-get install ansible-lint

Was Ansible-Lint alles an Befehlsoptionen mitbringt, offenbart uns die der Programmaufruf mit der Option help.

 $ ansible-lint --help
usage: ansible-lint [-h] [-L] [-f {rich,plain,rst,codeclimate,quiet,pep8}] [-q] [-p] [--parseable-severity] [--progressive] [--project-dir PROJECT_DIR]
                    [-r RULESDIR] [-R] [--show-relpath] [-t TAGS] [-T] [-v] [-x SKIP_LIST] [-w WARN_LIST] [--enable-list ENABLE_LIST] [--nocolor]
                    [--force-color] [--exclude EXCLUDE_PATHS] [-c CONFIG_FILE] [--offline] [--version]
                    [lintables ...]

positional arguments:
  lintables             One or more files or paths. When missing it will enable auto-detection mode.

options:
  -h, --help            show this help message and exit
  -L                    list all the rules
  -f {rich,plain,rst,codeclimate,quiet,pep8}
                        Format used rules output, (default: rich)
  -q                    quieter, reduce verbosity, can be specified twice.
  -p                    parseable output, same as '-f pep8'
  --parseable-severity  parseable output including severity of rule
  --progressive         Return success if it detects a reduction in number of violations compared with previous git commit. This feature works only in git
                        repositories.
  --project-dir PROJECT_DIR
                        Location of project/repository, autodetected based on location of configuration file.
  -r RULESDIR           Specify custom rule directories. Add -R to keep using embedded rules from /usr/lib/python3/dist-packages/ansiblelint/rules
  -R                    Keep default rules when using -r
  --show-relpath        Display path relative to CWD
  -t TAGS               only check rules whose id/tags match these values
  -T                    list all the tags
  -v                    Increase verbosity level (-vv for more)
  -x SKIP_LIST          only check rules whose id/tags do not match these values
  -w WARN_LIST          only warn about these rules, unless overridden in config file defaults to 'experimental'
  --enable-list ENABLE_LIST
                        activate optional rules by their tag name
  --nocolor             disable colored output, same as NO_COLOR=1
  --force-color         Force colored output, same as FORCE_COLOR=1
  --exclude EXCLUDE_PATHS
                        path to directories or files to skip. This option is repeatable.
  -c CONFIG_FILE        Specify configuration file to use. Defaults to ".ansible-lint"
  --offline             Disable installation of requirements.yml
  --version
<code>

==== man-page ====
In der Man-Page des Python Scripts finden sich noch ein paar weitere Optionen, die dort beschrieben sind.
   $ man ansible-lint 
<code>ANSIBLE-LINT(1)                                 System administration commands                                 ANSIBLE-LINT(1)

NAME
       ansible-lint - lint tool for Ansible playbooks

SYNOPSIS
       ansible-lint [-M module_path] [-l] [-s] [module...]

DESCRIPTION
       ansible-lint checks Ansible playbooks for practices and behaviour that could potentially be improved.

OPTIONS
       --version:

       show program’s version number and exit

       -M DIRECTORY, --module-path=DIRECTORY
           the DIRECTORY search path to load modules from. The default is /usr/share/ansible. This can also be set with the
           ANSIBLE_LIBRARY environment variable.

       -s, --snippet=
           Produce a snippet which can be copied into a playbook for modification, like a kind of task template.

       -l, --list=
           Produce a terse listing of modules and a short description of each.

       -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

       -r RULESDIR
           specify one or more rules directories using one or more -r arguments. Any -r flags override the default rules in
           /usr/lib/python3/dist-packages/ansiblelint/rules, unless -R is also used.

       -R
           Use default rules in /usr/lib/python3/dist-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)
       -M DIRECTORY, --module-path=DIRECTORY
           the DIRECTORY search path to load modules from. The default is /usr/share/ansible. This can also be set with the
           ANSIBLE_LIBRARY environment variable.

       -s, --snippet=
           Produce a snippet which can be copied into a playbook for modification, like a kind of task template.

       -l, --list=
           Produce a terse listing of modules and a short description of each.

       -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

       -r RULESDIR
           specify one or more rules directories using one or more -r arguments. Any -r flags override the default rules in
           /usr/lib/python3/dist-packages/ansiblelint/rules, unless -R is also used.

       -R
           Use default rules in /usr/lib/python3/dist-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.

AUTHOR
       ansible-lint was originally written by Will Thames

COPYRIGHT
       Copyright © 2013-2016 Will Thames <will@thames.id.au>

       ansible-lint is released under the terms of the MIT License.

SEE ALSO
       ansible-playbook(1), ansible(1)

ansible-lint                                              08/12/2017                                           ANSIBLE-LINT(1)

Eine weitaus aussagekräftigere Dokumentation zu Ansible-Lint findet sich in der Online-Dokumentation des Projektes!

Die Verwendung der „Fusselbürste“ aka Ansible-Lint ist denkbar einfach. Im einfachsten Fall muss lediglich das Python-Script gefolgt mit dem zu prüfenden Objekt aufgefrufen werden. Beispiele:

  • Eine spezifische YML-Datei:
     $ ansible-lint ~/ansible/roles/inventory/tasks/harvester.yml
  • Eine Rolle:
     $ ansible-lint ~/ansible/roles/fetch_exporter/
  • Ein einzelnes Playbook:
     $ ansible-lint ~/ansible/playbooks/ansible_grundconfig_v2.yml
  • Alle Playbooks:
     $ ansible-lint ~/ansible/playbooks/

Ist alles O:K: wird UNIX-like keinerlei Rückmeldung gegeben.

Im Fehlerfall hingegen erfolgt eine detaillierte Rückmeldung und auch schon meist ein Hinweis, was denn schief gelaufen sein könnte.

Bsp.:

 $ ansible-lint playbooks/linting_demo.yml

WARNING  Listing 1 violation(s) that are fatal
literal-compare: Don't compare to literal True/False
playbooks/linting_demo.yml:23 Task/Handler: Fehlerhinweis im Fehlerfall ausgeben

You can skip specific rules or tags by adding them to your configuration file:
# .ansible-lint
warn_list:  # or 'skip_list' to silence them completely
  - literal-compare  # Don't compare to literal True/False

Finished with 1 failure(s), 0 warning(s) on 1 files.

Beim Task Fehlerhinweis im Fehlerfall ausgeben ab Zeile 23 sollte man also nicht gegen True sondern besser gegen ! oder 0 prüfen. Gesagt getan:

 $ vim +23 playbooks/linting_demo.yml

Nach Korrektur des Fehlers und abermaligen ansible-lint-Aufruf erfolgt keinerlei Fehlermeldung, also ist in diesem Beispiel alles wieder in Butter.

Ein oft gemeldeter Fehler, der sehr leicht korrigiert werden kann, sind Leerzeichen, die am Zeilenende zu viel sind.

WARNING  Listing 1 violation(s) that are fatal
yaml: trailing spaces (trailing-spaces)
playbooks/linting_demo.yml:36 

You can skip specific rules or tags by adding them to your configuration file:
# .ansible-lint
warn_list:  # or 'skip_list' to silence them completely
  - yaml  # Violations reported by yamllint

Finished with 1 failure(s), 0 warning(s) on 1 files.

Vergißt mann aber z.B. die Dateirechte beim Anlegen richtig zu setzen, bekommt man einen entsprechenden Hinweis präsentiert.

 $ ansible-lint playbooks/ssh_client_config.yml

WARNING  Listing 1 violation(s) that are fatal
risky-file-permissions: File permissions unset or incorrect
roles/ssh_client/tasks/client_config.yml:4 Task/Handler: Generieren und kopieren der SSH Client Konfiguration ~/.ssh/config.

You can skip specific rules or tags by adding them to your configuration file:
# .ansible-lint
warn_list:  # or 'skip_list' to silence them completely
  - experimental  # Violations reported by yamllint

Finished with 0 failure(s), 1 warning(s) on 7 files.

Beim folgenden Beispiel bekommen wir eine Fehlermeldung präsentiert, deren wir uns aber nicht anschließen wollen und diese Fehlermeldung als „O:K:“ akzeptieren wollen.

 $ ansible-lint playbooks/ansible_grundconfig_v2.yml

WARNING  Listing 1 violation(s) that are fatal
package-latest: Package installs should not use latest
playbooks/ansible_grundconfig_v2.yml:142 Task/Handler: Passwort-Manager pass installieren

You can skip specific rules or tags by adding them to your configuration file:
# .ansible-lint
warn_list:  # or 'skip_list' to silence them completely
  - package-latest  # Package installs should not use latest

Finished with 1 failure(s), 0 warning(s) on 1 files.

Gesagt, getan - wir werden also dem Vorschlag folgen und einen entsprechenden Eintrag in der .ansible-lint-Datei in unserem Arbeitsverzeichnis anlegen.

 $ vim ~/ansible/.ansible-lint
.ansible-lint
# .ansible-lint
warn_list:  # or 'skip_list' to silence them completely
  - package-latest  # Package installs should not use latest

Ein erneuter Ansible-Lint-Aufruf bringt nun:

 $ ansible-lint playbooks/ansible_grundconfig_v2.yml

WARNING  Listing 1 violation(s) that are fatal
package-latest: Package installs should not use latest
playbooks/ansible_grundconfig_v2.yml:142 Task/Handler: Passwort-Manager pass installieren


Finished with 0 failure(s), 1 warning(s) on 1 files.

Will man diese Meldung gar nicht mehr sehen, benutzt man statt warn_list entsprechend skip_list in der Ansible-lint Konfigurationsdatei.

 $ vim ~/ansible/.ansible-lint
.ansible-lint
# .ansible-lint
skip_list:  # to silence them completely
  - package-latest  # Package installs should not use latest

Ein erneuter Ansible.Lint-Aufruf bringt nun:

 $ ansible-lint playbooks/ansible_grundconfig_v2.yml

Schon ist die Fehler-/Warmeldung auch verschwunden.

Man darf von ansible-lint keine Wunder erwarten, aber man hat mit diesem Python-Script ein Werkzeug an der Hand, mit dem man durchaus seinen Code einheitlich, strukturiert und code-technisch sauber zu halten vermag. Somit kann man guten Gewissens bestätigen, dass das Hauptziel sein kann, bewährte Praktiken, Muster und Verhaltensweisen zu fördern sowie gleichzeitig häufige Fallstricke zu vermeiden, die leicht zu Fehlern führen und dabei die Wartung des Codes erschweren können. Vor allem bei gemeinschaftlich genutzten und gepflegten Code kann sich das durchaus als sehr hilfreich heraus kristallisieren.

Links

Diese Website verwendet Cookies. Durch die Nutzung der Website stimmen Sie dem Speichern von Cookies auf Ihrem Computer zu. Außerdem bestätigen Sie, dass Sie unsere Datenschutzbestimmungen gelesen und verstanden haben. Wenn Sie nicht einverstanden sind, verlassen Sie die Website.Weitere Information
  • linux/ansible/lint.txt
  • Zuletzt geändert: 10.10.2022 18:46.
  • von django