ansible-lint
Ansible-lint checks Ansible playbooks for practices and behavior that could potentially be improved. It's a community-backed project that helps enforce best practices and maintain high-quality Ansible code.
Key Features:
- Best Practice Validation: Checks playbooks against Ansible community best practices and conventions
- Auto-fixing: Can automatically fix some of the most common issues found in playbooks
- Extensible Rules: Comprehensive set of built-in rules with support for custom rules
- Multiple Output Formats: Supports various output formats including SARIF for integration with security tools
- Configuration Flexibility: Highly configurable with support for .ansible-lintconfiguration files
- Community Support: Supports only the last two major versions of Ansible, ensuring compatibility
Common checks include:
- YAML syntax and formatting
- Task and playbook structure validation
- Security best practices (avoiding plain text secrets)
- Proper use of Ansible modules and features
- Naming conventions and documentation standards
Ansible-lint helps teams maintain consistent, secure, and well-structured Ansible automation code.
ansible-lint documentation
- Version in MegaLinter: 25.9.2
- Visit Official Web Site
- See How to configure ansible-lint rules- If custom .ansible-lintconfig file isn't found, .ansible-lint will be used
 
- If custom 
- See How to disable ansible-lint rules in files
- See Index of problems detected by ansible-lint
Configuration in MegaLinter
- Enable ansible-lint by adding ANSIBLE_ANSIBLE_LINTin ENABLE_LINTERS variable
- Disable ansible-lint by adding ANSIBLE_ANSIBLE_LINTin DISABLE_LINTERS variable
| Variable | Description | Default value | 
|---|---|---|
| ANSIBLE_ANSIBLE_LINT_ARGUMENTS | User custom arguments to add in linter CLI call Ex: -s --foo "bar" | |
| ANSIBLE_ANSIBLE_LINT_COMMAND_REMOVE_ARGUMENTS | User custom arguments to remove from command line before calling the linter Ex: -s --foo "bar" | |
| ANSIBLE_ANSIBLE_LINT_CLI_LINT_MODE | Override default CLI lint mode ⚠️ As default value is project, overriding might not work - file: Calls the linter for each file- list_of_files: Call the linter with the list of files as argument- project: Call the linter from the root of the project | project | 
| ANSIBLE_ANSIBLE_LINT_FILE_EXTENSIONS | Allowed file extensions. "*"matches any extension,""matches empty extension. Empty list excludes all filesEx: [".py", ""] | [".yml", ".yaml"] | 
| ANSIBLE_ANSIBLE_LINT_FILE_NAMES_REGEX | File name regex filters. Regular expression list for filtering files by their base names using regex full match. Empty list includes all files Ex: ["Dockerfile(-.+)?", "Jenkinsfile"] | Include every file | 
| ANSIBLE_ANSIBLE_LINT_PRE_COMMANDS | List of bash commands to run before the linter | None | 
| ANSIBLE_ANSIBLE_LINT_POST_COMMANDS | List of bash commands to run after the linter | None | 
| ANSIBLE_ANSIBLE_LINT_UNSECURED_ENV_VARIABLES | List of env variables explicitly not filtered before calling ANSIBLE_ANSIBLE_LINT and its pre/post commands | None | 
| ANSIBLE_ANSIBLE_LINT_CONFIG_FILE | ansible-lint configuration file name Use LINTER_DEFAULTto let the linter find it | .ansible-lint | 
| ANSIBLE_ANSIBLE_LINT_RULES_PATH | Path where to find linter configuration file | Workspace folder, then MegaLinter default rules | 
| ANSIBLE_ANSIBLE_LINT_DISABLE_ERRORS | Run linter but consider errors as warnings | false | 
| ANSIBLE_ANSIBLE_LINT_DISABLE_ERRORS_IF_LESS_THAN | Maximum number of errors allowed | 0 | 
| ANSIBLE_ANSIBLE_LINT_CLI_EXECUTABLE | Override CLI executable | ['ansible-lint'] | 
MegaLinter Flavors
This linter is available in the following flavors
| Flavor | Description | Embedded linters | Info | |
|---|---|---|---|---|
|  | all | Default MegaLinter Flavor | 127 | |
| c_cpp | Optimized for pure C/C++ projects | 56 | ||
| cupcake | MegaLinter for the most commonly used languages | 88 | ||
| documentation | MegaLinter for documentation projects | 49 | ||
| dotnet | Optimized for C, C++, C# or VB based projects | 64 | ||
| dotnetweb | Optimized for C, C++, C# or VB based projects with JS/TS | 73 | ||
| go | Optimized for GO based projects | 51 | ||
| java | Optimized for JAVA based projects | 54 | ||
| javascript | Optimized for JAVASCRIPT or TYPESCRIPT based projects | 59 | ||
| php | Optimized for PHP based projects | 54 | ||
| python | Optimized for PYTHON based projects | 65 | ||
| ruby | Optimized for RUBY based projects | 50 | ||
| rust | Optimized for RUST based projects | 50 | ||
| salesforce | Optimized for Salesforce based projects | 53 | ||
| security | Optimized for security | 24 | ||
| swift | Optimized for SWIFT based projects | 50 | ||
| terraform | Optimized for TERRAFORM based projects | 54 | 
Behind the scenes
How are identified applicable files
- Activated only if one of these files is found: .ansible-lint, .ansible-lint.yml, .ansible-lint.yaml, .config/ansible-lint.yml, .config/ansible-lint.yaml
- File extensions: .yml,.yaml
- File name don't ends with: vault.yml,vault.yaml,galaxy.yml,galaxy.yaml
How the linting is performed
ansible-lint is called once on the whole project directory (project CLI lint mode)
- filtering can not be done using MegaLinter configuration variables,it must be done using ansible-lint configuration or ignore file (if existing)
- VALIDATE_ALL_CODEBASE: falsedoesn't make ansible-lint analyze only updated files
Example calls
ansible-lint -v
ansible-lint -v -c .ansible-lint
Help content
WARNING: PATH altered to expand ~ in it. Read https://stackoverflow.com/a/44704799/99834 and correct your system configuration.
usage: ansible-lint [-h] [-P | -L | -T]
                    [-f {brief,full,md,json,codeclimate,quiet,pep8,sarif}]
                    [--sarif-file SARIF_FILE] [-q]
                    [--profile {min,basic,moderate,safety,shared,production}]
                    [-p] [--project-dir PROJECT_DIR] [-r RULESDIR] [-R] [-s]
                    [--fix [WRITE_LIST]] [--show-relpath] [-t TAGS] [-v]
                    [-x SKIP_LIST] [--generate-ignore] [-w WARN_LIST]
                    [--enable-list ENABLE_LIST] [--nocolor] [--force-color]
                    [--exclude EXCLUDE_PATHS [EXCLUDE_PATHS ...]]
                    [-c CONFIG_FILE] [-i IGNORE_FILE]
                    [--yamllint-file YAMLLINT_FILE] [--offline | --no-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
  -P, --list-profiles   List all profiles.
  -L, --list-rules      List all the rules.
  -T, --list-tags       List all the tags and the rules they cover.
  -f, --format {brief,full,md,json,codeclimate,quiet,pep8,sarif}
                        stdout formatting, json being an alias for codeclimate. (default: None)
  --sarif-file SARIF_FILE
                        SARIF output file
  -q                    quieter, reduce verbosity, can be specified twice.
  --profile {min,basic,moderate,safety,shared,production}
                        Specify which rules profile to be used.
  -p, --parseable       parseable output, same as '-f pep8'
  --project-dir PROJECT_DIR
                        Location of project/repository, autodetected based on location of configuration file.
  -r, --rules-dir RULESDIR
                        Specify custom rule directories. Add -R to keep using embedded rules from /venvs/ansible-lint/lib/python3.13/site-packages/ansiblelint/rules
  -R                    Keep default rules when using -r
  -s, --strict          Return non-zero exit code on warnings as well as errors
  --fix [WRITE_LIST]    Allow ansible-lint to perform auto-fixes, including YAML reformatting. You can limit the effective rule transforms (the 'write_list') by passing a keywords 'all' or 'none' or a comma separated list of rule ids or rule tags. YAML reformatting happens whenever '--fix' or '--fix=' is used. '--fix' and '--fix=all' are equivalent: they allow all transforms to run. Presence of --fix in command overrides config file value.
  --show-relpath        Display path relative to CWD
  -t, --tags TAGS       only check rules whose id/tags match these values
  -v                    Increase verbosity level (-vv for more)
  -x, --skip-list SKIP_LIST
                        only check rules whose id/tags do not match these values.             e.g: --skip-list=name,run-once
  --generate-ignore     Generate a text file '.ansible-lint-ignore' that ignores all found violations. Each line contains filename and rule id separated by a space.
  -w, --warn-list WARN_LIST
                        only warn about these rules, unless overridden in config file. Current version default value is: experimental, jinja[spacing], fqcn[deep]
  --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 [EXCLUDE_PATHS ...]
                        path to directories or files to skip. This option is repeatable.
  -c, --config-file CONFIG_FILE
                        Specify configuration file to use. By default it will look for '.ansible-lint', '.ansible-lint.yml', '.ansible-lint.yaml', '.config/ansible-lint.yml', or '.config/ansible-lint.yaml'
  -i, --ignore-file IGNORE_FILE
                        Specify ignore file to use. By default it will look for '.ansible-lint-ignore' or '.config/ansible-lint-ignore.txt'
  --yamllint-file YAMLLINT_FILE
                        Specify yamllint config file to use. By default it will look for '.yamllint', '.yamllint.yaml', '.yamllint.yml', '~/.config/yamllint/config' or environment variables XDG_CONFIG_HOME and YAMLLINT_CONFIG_FILE.
  --offline, --no-offline
                        Disable installation of requirements.yml and schema refreshing
  --version
The following environment variables are also recognized but there is no guarantee that they will work in future versions:
ANSIBLE_LINT_CUSTOM_RULESDIR: Used for adding another folder into the lookup path for new rules.
ANSIBLE_LINT_IGNORE_FILE: Define it to override the name of the default ignore file `.ansible-lint-ignore`
ANSIBLE_LINT_WRITE_TMP: Tells linter to dump fixes into different temp files instead of overriding original. Used internally for testing.
ANSIBLE_LINT_SKIP_SCHEMA_UPDATE: Tells ansible-lint to skip schema refresh.
ANSIBLE_LINT_NODEPS: Avoids installing content dependencies and avoids performing checks that would fail when modules are not installed. Far less violations will be reported.
Installation on mega-linter Docker image
- Dockerfile commands :
# renovate: datasource=pypi depName=ansible-lint
ARG PIP_ANSIBLE_LINT_VERSION=25.9.2
- PIP packages (Python):