Default Rules

Below you can see the list of default rules Ansible Lint use to evaluate playbooks and roles:

command-instead-of-module

Using command rather than module

Executing a command when there is an Ansible module is generally a bad idea

command-instead-of-shell

Use shell only when shell functionality is required

Shell should only be used when piping, redirecting or chaining commands (and Ansible would be preferred for some of those!)

deprecated-bare-vars

Using bare variables is deprecated

Using bare variables is deprecated. Update your playbooks so that the environment value uses the full variable syntax {{ your_variable }}

deprecated-command-syntax

Using command rather than an argument to e.g. file

Executing a command when there are arguments to modules is generally a bad idea

deprecated-local-action

Do not use ‘local_action’, use ‘delegate_to: localhost’

Do not use local_action, use delegate_to: localhost

deprecated-module

Deprecated module

These are deprecated modules, some modules are kept temporarily for backwards compatibility but usage is discouraged. For more details see: https://docs.ansible.com/ansible/latest/collections/index_module.html

empty-string-compare

Don’t compare to empty string

Use when: var|length > 0 rather than when: var != "" (or conversely when: var|length == 0 rather than when: var == "")

fqcn-builtins

Use FQCN for builtin actions

Check whether the long version starting with ansible.builtin is used in the playbook

git-latest

Git checkouts must contain explicit version

All version control checkouts must point to an explicit commit or tag, not just latest

hg-latest

Mercurial checkouts must contain explicit revision

All version control checkouts must point to an explicit commit or tag, not just latest

ignore-errors

Use failed_when and specify error conditions instead of using ignore_errors

Instead of ignoring all errors, ignore the errors only when using {{ ansible_check_mode }}, register the errors using register, or use failed_when: and specify acceptable error conditions to reduce the risk of ignoring important failures.

inline-env-var

Command module does not accept setting environment variables inline

Use environment: to set environment variables or use shell module which accepts both

internal-error

Unexpected internal error

This error can be caused by internal bugs but also by custom rules. Instead of just stopping linter we generate there errors and continue processing. This allows users to add this rule to warn list until the root cause is fixed.

literal-compare

Don’t compare to literal True/False

Use when: var rather than when: var == True (or conversely when: not var)

load-failure

Failed to load or parse file

Linter failed to process a YAML file, possible not an Ansible file.

meta-incorrect

meta/main.yml default values should be changed

meta/main.yml default values should be changed for: author, description, company, license, license

meta-no-info

meta/main.yml should contain relevant info

meta/main.yml should contain: author, description, license, min_ansible_version, platforms

meta-no-tags

Tags must contain lowercase letters and digits only

Tags must contain lowercase letters and digits only, and galaxy_tags is expected to be a list

no-changed-when

Commands should not change things if nothing needs doing

Commands should either read information (and thus set changed_when) or not do something if it has already been done (using creates/removes) or only do it if another check has a particular result (when)

no-handler

Tasks that run when changed should likely be handlers

If a task has a when: result.changed setting, it is effectively acting as a handler. You could use notify and move that task to handlers. (more)

no-jinja-nesting

Nested jinja pattern

There should not be any nested jinja pattern. Example (bad): {{ list_one + {{ list_two | max }} }}, Example (good): {{ list_one + max(list_two) }}, Example (allowed): --format='{{'{{'}}.Size{{'}}'}}'

no-jinja-when

No Jinja2 in when

when is a raw Jinja2 expression, remove redundant {{ }} from variable(s).

no-log-password

password should not be logged.

When passing password argument you should have no_log configured to a non False value to avoid accidental leaking of secrets.

no-loop-var-prefix

Role loop_var should use configured prefix.

Looping inside roles has the risk of clashing with loops from user-playbooks. (more)

no-relative-paths

Doesn’t need a relative path in role

copy and template do not need to use relative path for src

no-same-owner

Owner should not be kept between different hosts

Optional rule that hihglight dangers of assuming that user/group on the remote machines may not exist on ansible controller or vice versa. Owner and group should not be preserved when transferring files between them.

This rule is not enabled by default and was inspired by Zuul execution policy. See: https://zuul-ci.org/docs/zuul-jobs/policy.html#preservation-of-owner-between-executor-and-remote

no-tabs

Most files should not contain tabs

Tabs can cause unexpected display issues, use spaces

package-latest

Package installs should not use latest

Package installs should use state=present with or without a version

parser-error

AnsibleParserError

Ansible parser fails, this usually indicate invalid file.

partial-become

become_user requires become to work as expected

become_user without become will not actually change user

playbook-extension

Use “.yml” or “.yaml” playbook extension

Playbooks should have the “.yml” or “.yaml” extension

risky-file-permissions

File permissions unset or incorrect

Missing or unsupported mode parameter can cause unexpected file permissions based on version of Ansible being used. Be explicit, like mode: 0644 to avoid hitting this rule. Special preserve value is accepted only by copy, template modules. See https://github.com/ansible/ansible/issues/71200

risky-octal

Octal file permissions must contain leading zero or be a string

Numeric file permissions without leading zero can behave in unexpected ways. See https://docs.ansible.com/ansible/latest/collections/ansible/builtin/file_module.html

risky-shell-pipe

Shells that use pipes should set the pipefail option

Without the pipefail option set, a shell command that implements a pipeline can fail and still return 0. If any part of the pipeline other than the terminal command fails, the whole pipeline will still return 0, which may be considered a success by Ansible. Pipefail is available in the bash shell.

role-name

Role name {0} does not match ^[a-z][a-z0-9_]+$ pattern

Role names are now limited to contain only lowercase alphanumeric characters, plus ‘_’ and start with an alpha character. See developing collections

syntax-check

Ansible syntax check failed

Running ansible-playbook --syntax-check ... failed.

This error cannot be disabled due to being a prerequisite for other steps. You can either exclude these files from linting or better assure they can be loaded by Ansible. This is often achieved by editing inventory file and/or ansible.cfg so ansible can load required variables.

If undefined variables are the failure reason you could use jinja default() filter in order to provide fallback values.

unnamed-task

All tasks should be named

All tasks should have a distinct name for readability and for --start-at-task to work

var-naming

All variables should be named using only lowercase and underscores

All variables should be named using only lowercase and underscores

var-spacing

Variables should have spaces before and after: {{ var_name }}

Variables should have spaces before and after: {{ var_name }}

yaml

Violations reported by yamllint

Rule violations reported by YamlLint when this is installed.

You can fully disable all of them by adding ‘yaml’ to the ‘skip_list’.

Specific tag identifiers that are printed at the end of rule name, like ‘trailing-spaces’ or ‘indentation’ can also be be skipped, allowing you to have a more fine control.

By default this rule is not used when yamllint library is missing. If you want to make its absence a runtime failure, please add ‘yaml’ to ‘enable_list’ inside the configuration file.