What is Ansible Lint?
Ansible Lint is a command-line tool, part of the ansible-lint upstream community project, for linting of Ansible Playbooks, Roles, and Collections. Ok, so what exactly is "linting?" Its fundamental objective is to promote proven behaviors, patterns, and practices while avoiding typical traps that can quickly result in errors or make code more difficult to maintain. That is - leverage community recommendations and opinions in writing Ansible content by means of a tool to help ensure what you're writing is generally valid.
Additionally, Ansible Lint is designed to assist users in updating their code to function with more recent Ansible versions. Even though the version of Ansible being used in production can be an older version of ansible-core, we advise utilizing it with the most recent version.
Ansible Lint is opinionated just like any other linter. However, because community members contributed to its rules, each user has the option to enable or disable them on an individual or category basis.
Why should I use Ansible Lint?
The goal of Ansible Lint is to flag programming errors, bugs, stylistic errors and suspicious constructs and also ensure that content created by different people has a similar look and feel. This makes the adoption and use of Ansible content easier in the community, and by extension, the enterprise. By keeping the number of configurable features at a minimum, authors can achieve more consistent outcomes.
Ansible Lint should be considered a trusted advisor to Ansible content creators, helping them write and package higher quality Ansible content. While not all rules may be applicable in all situations, they should be followed whenever possible.
In 2022, additional rules have been added to help content creators ready their content for production. With ansible-lint
and these rules, developers can have confidence that their playbooks, roles, and task files are easy to understand and produce consistent results, whether deployed on servers in a home lab, or mission-critical systems in the cloud.
Adopting Ansible Lint will save time by focusing on the quality of the content and less so on the nuances of formatting and style. As code formatting is not an art, we can save time and effort on a project by applying a standardized code style and formatting.
Guidelines to add new rule
Multiple rules may be added based on the requirements. Adding a new rule should combine implementation, testing and documentation.
Some guidelines to create a new Ansible Lint rule include the following:
- Use a short but clear class name, which must match the filename.
- Pick an unused ID; the first number is used to determine the rule section. Refer to the rules page and pick one that matches the best your new rule and see which one fits best.
- Include experimental tags. Any new rule must stay as experimental for at least two weeks until this tag is removed in the next major release.
- Update all class level variables.
- Implement linting methods needed by your rule, these are the ones starting with match prefix. Implement only those you need. For the moment you will need to look at how similar rules were implemented to figure out what to do.
- Update the tests. It must have at least one test and likely also a negative match one.
- If the rule is task specific, it may be best to include a test to verify its use inside blocks as well.
- Optionally run only the rule specific tests with a command like:
tox -e py38-core -- -k NewRule
- Run tox in order to run all ansible-lint tests. Adding a new rule can break some other tests. Update them if needed.
- Run
ansible-lint -L
and check that the rule description renders correctly. - Build the documentation using the
tox -e docs
command and check that the new rule is displayed correctly in them.
Here is a reference example MetaTagValidRule that may be useful to create new rules.
Creating Custom Rules
Rules are described using a class file per rule. For example, default rules are named DeprecatedVariableRule.py
, etc.
Each rule definition should have the following:
- ID: A unique identifier.
- Short description: Brief description of the rule.
- Description: What the rule is looking for.
- Tags: One or more tags that may be used to include or exclude the rule.
- At least one of the following methods:
- Match that takes a line and returns none or false; if the line doesn't match the test, and true or a custom message, when it does. (This allows one rule to test multiple behaviors - see e.g. the CommandsInsteadOfModulesRule.)
- Matchtask that operates on a single task or handler, such that tasks get standardized to always contain a module key and module_arguments key. Other common task modifiers, such as when, with_items, etc., are also available as keys, if present in the task.
An example rule using match
is:
from ansiblelint.rules import AnsibleLintRule
class DeprecatedVariableRule(AnsibleLintRule):
"""Deprecated variable declarations."""
id = 'EXAMPLE002'
description = 'Check for lines that have old style ${var} ' + \ 'declarations'
tags = { 'deprecations' }
def match(self, line: str) -> Union[bool, str]:
return '${' in line
An example rule using matchtask
is:
from typing import TYPE_CHECKING, Any, Dict, Union
import ansiblelint.utils
from ansiblelint.rules import AnsibleLintRule
if TYPE_CHECKING:
from ansiblelint.file_utils import Lintable
class TaskHasTag(AnsibleLintRule):
"""Tasks must have tag."""
id = 'EXAMPLE001'
description = 'Tasks must have tag'
tags = ['productivity']
def matchtask(self, task: Dict[str, Any], file: 'Lintable' | None = None) -> Union[bool,str]:
# If the task include another task or make the playbook fail
# Don't force to have a tag
if not set(task.keys()).isdisjoint(['include','fail']):
return False
# Task should have tags
if not task.has_key('tags'):
return True
return False
The task argument to matchtask contains a number of keys - the critical one is action. The value of task action
contains the module being used, and the arguments passed, both as key-value pairs and a list of other arguments (e.g. the command used with shell).
In ansible-lint 2.0.0, task action
args
was renamed task action
module_arguments
to avoid a clash when a module actually takes args as a parameter key (e.g. ec2_tag)
In ansible-lint 3.0.0 task action module
was renamed task action __ansible_module__
to avoid a clash when a module takes a module as an argument. As a precaution, task action module_arguments
was renamed task action __ansible_arguments__
.
Packaging Custom Rules
The ansible-lint provides a sub directory named custom in its built-in rules, /usr/lib/python3.8/site-packages/ansiblelint/rules/custom/
for example, to install custom rules since v4.3.1. The custom rules, which are packaged as a Python package installed into this directory, will be loaded and enabled automatically by ansible-lint.
To make custom rules loaded automatically, you need the following:
- Packaging your custom rules as a Python package named some descriptive ones like
ansible_lint_custom_rules_foo
. - Install it into
<ansible_lint_custom_rules_dir>/custom/<your_custom_rules_subdir>
.
You may accomplish the second by adding some configurations into the [options]
section of the setup.cfg
of your custom rules python package like the following:
[options]
packages =
ansiblelint.rules.custom.<your_custom_rules_subdir>
Package_dir = ansiblelint.rules.custom.<your_custom_rules_subdir> = <your_rules_source_code_subdir>
Getting Started and Next Steps with Ansible Lint
Where is the repo?
Ansible repository is open source code, which you can find on GitHub:
https://github.com/ansible/ansible-lint
Any resources/documentation?
Full, in-depth upstream community documentation of Ansible Lint can be found at:
https://ansible-lint.readthedocs.io/
How to contribute
As ansible-lint is open source, anyone in the community can also contribute new rules to the project.
Here are the steps that everyone should follow:
- First create pull requests on a branch of your own fork.
- After creating your fork on GitHub, do the following at the command-line:
$ git clone git@github.com:your-name/ansible-lint
$ cd ansible-lint
$ git checkout -b your-branch-name
# DO SOME CODING HERE
$ git add your new files
$ git commit -v
$ git push origin your-branch-name
Über den Autor
Mehr davon
Nach Thema durchsuchen
Automatisierung
Das Neueste zum Thema IT-Automatisierung für Technologien, Teams und Umgebungen
Künstliche Intelligenz
Erfahren Sie das Neueste von den Plattformen, die es Kunden ermöglichen, KI-Workloads beliebig auszuführen
Open Hybrid Cloud
Erfahren Sie, wie wir eine flexiblere Zukunft mit Hybrid Clouds schaffen.
Sicherheit
Erfahren Sie, wie wir Risiken in verschiedenen Umgebungen und Technologien reduzieren
Edge Computing
Erfahren Sie das Neueste von den Plattformen, die die Operations am Edge vereinfachen
Infrastruktur
Erfahren Sie das Neueste von der weltweit führenden Linux-Plattform für Unternehmen
Anwendungen
Entdecken Sie unsere Lösungen für komplexe Herausforderungen bei Anwendungen
Original Shows
Interessantes von den Experten, die die Technologien in Unternehmen mitgestalten
Produkte
- Red Hat Enterprise Linux
- Red Hat OpenShift
- Red Hat Ansible Automation Platform
- Cloud-Services
- Alle Produkte anzeigen
Tools
- Training & Zertifizierung
- Eigenes Konto
- Kundensupport
- Für Entwickler
- Partner finden
- Red Hat Ecosystem Catalog
- Mehrwert von Red Hat berechnen
- Dokumentation
Testen, kaufen und verkaufen
Kommunizieren
Über Red Hat
Als weltweit größter Anbieter von Open-Source-Software-Lösungen für Unternehmen stellen wir Linux-, Cloud-, Container- und Kubernetes-Technologien bereit. Wir bieten robuste Lösungen, die es Unternehmen erleichtern, plattform- und umgebungsübergreifend zu arbeiten – vom Rechenzentrum bis zum Netzwerkrand.
Wählen Sie eine Sprache
Red Hat legal and privacy links
- Über Red Hat
- Jobs bei Red Hat
- Veranstaltungen
- Standorte
- Red Hat kontaktieren
- Red Hat Blog
- Diversität, Gleichberechtigung und Inklusion
- Cool Stuff Store
- Red Hat Summit