### Setup and Test Workflow for Ansible-lint Contribution Source: https://github.com/ansible/ansible-lint/blob/main/docs/contributing.md This sequence of commands sets up a development environment for ansible-lint. It includes cloning the repository, installing dependencies, running initial tests with tox, and preparing for development and commits. ```shell git clone --recursive git@github.com:your-name/ansible-lint cd ansible-lint # Recommended: Initialize and activate a Python virtual environment pip install --upgrade pip pip install -e '.[test]' # Install testing dependencies tox run -e lint,pkg,docs,py # Ensure subset of tox tests work in clean checkout git checkout -b your-branch-name # DO SOME CODING HERE tox run -e lint,pkg,docs,py # Ensure subset of tox tests work with your changes git add your new files git commit -v git push origin your-branch-name ``` -------------------------------- ### List available profiles Source: https://github.com/ansible/ansible-lint/blob/main/docs/usage.md Displays all available linting profiles supported by the current installation. ```bash ansible-lint --list-profiles ``` -------------------------------- ### Install Ansible-lint from source code Source: https://github.com/ansible/ansible-lint/blob/main/docs/installing.md Installs Ansible-lint directly from its GitHub repository using pip. Ensure pip is updated to version 22.3.1 or newer. ```bash pip3 install git+https://github.com/ansible/ansible-lint ``` -------------------------------- ### Problematic package installation with state: latest Source: https://github.com/ansible/ansible-lint/blob/main/docs/rules/package-latest.md Avoid using `state: latest` as it installs the newest version, potentially causing updates and installing additional packages. This can lead to performance degradation or service loss. ```yaml --- - name: Example playbook hosts: localhost tasks: - name: Install Ansible ansible.builtin.dnf: name: ansible state: latest # <- Installs the latest package. - name: Install Ansible-lint ansible.builtin.pip: name: ansible-lint args: state: latest # <- Installs the latest package. - name: Install some-package ansible.builtin.package: name: some-package state: latest # <- Installs the latest package. - name: Install sudo with update_only to false ansible.builtin.dnf: name: sudo state: latest update_only: false # <- Updates and installs packages. - name: Install sudo with only_upgrade to false ansible.builtin.apt: name: sudo state: latest only_upgrade: false # <- Upgrades and installs packages ``` -------------------------------- ### Correct galaxy.yml version Source: https://github.com/ansible/ansible-lint/blob/main/docs/rules/galaxy-version-incorrect.md This example demonstrates a 'galaxy.yml' file with a 'version' key that meets the semantic versioning standard (>= '1.0.0'). ```yaml description: "description" namespace: "namespace_name" name: "collection_name" version: "1.0.0" # <- version key is greater than or equal to '1.0.0'. readme: "README.md" authors: - "Author1" - "Author2 (https://author2.example.com)" - "Author3 " dependencies: "other_namespace.collection1": ">=1.0.0" "other_namespace.collection2": ">=2.0.0,<3.0.0" "anderson55.my_collection": "*" # note: "*" selects the highest version available license: - "MIT" tags: - demo - collection repository: "https://www.github.com/my_org/my_collection" ``` -------------------------------- ### Correct Ignore Entry Source: https://github.com/ansible/ansible-lint/blob/main/docs/rules/sanity.md This example shows a correctly formatted and permitted ignore entry in the `ignore-x.x.txt` file. The `import-2.7!skip` entry is allowed. ```text # tests/sanity/ignore-x.x.txt plugins/module_utils/ansible_example_module.py import-2.7!skip ``` -------------------------------- ### Problematic YAML Code Examples Source: https://github.com/ansible/ansible-lint/blob/main/docs/rules/yaml.md Illustrates common YAML issues including implicit octal values, duplicate keys, and incorrect comment indentation. These examples highlight areas that yamllint will flag. ```yaml # Missing YAML document start. foo: 0777 # <-- yaml[octal-values] foo2: 0o777 # <-- yaml[octal-values] foo2: ... # <-- yaml[key-duplicates] bar: ... # <-- yaml[comments-indentation] ``` -------------------------------- ### Problematic Ignore Entry Source: https://github.com/ansible/ansible-lint/blob/main/docs/rules/sanity.md This example shows a disallowed ignore entry in the `ignore-x.x.txt` file. The `import-3.6!skip` entry is not permitted. ```text # tests/sanity/ignore-x.x.txt plugins/module_utils/ansible_example_module.py import-3.6!skip ``` -------------------------------- ### Install Ansible-lint using pip3 Source: https://github.com/ansible/ansible-lint/blob/main/docs/installing.md Installs the latest version of Ansible-lint using the pip3 package manager. This command also installs ansible-core if it's not already present. ```bash pip3 install ansible-lint ``` -------------------------------- ### Packaging Custom Rules with `setup.cfg` Source: https://github.com/ansible/ansible-lint/blob/main/docs/custom-rules.md Configuration example for `setup.cfg` to package custom Ansible-lint rules as a Python package. This specifies how to map custom rule subdirectories for automatic loading. ```yaml [options] packages = ansiblelint.rules.custom. package_dir = ansiblelint.rules.custom. = ``` -------------------------------- ### Corrected package installation with pinned versions or specific update flags Source: https://github.com/ansible/ansible-lint/blob/main/docs/rules/package-latest.md Pin package versions using `state: present` and `version` or use `update_only: true` / `only_upgrade: true` with `state: latest` to update without installing additional packages. ```yaml --- - name: Example playbook hosts: localhost tasks: - name: Install Ansible ansible.builtin.dnf: name: ansible-2.12.7.0 state: present # <- Pins the version to install with dnf. - name: Install Ansible-lint ansible.builtin.pip: name: ansible-lint args: state: present version: 5.4.0 # <- Pins the version to install with pip. - name: Install some-package ansible.builtin.package: name: some-package state: present # <- Ensures the package is installed. - name: Update sudo with update_only to true ansible.builtin.dnf: name: sudo state: latest update_only: true # <- Updates but does not install additional packages. - name: Install sudo with only_upgrade to true ansible.builtin.apt: name: sudo state: latest only_upgrade: true # <- Upgrades but does not install additional packages. ``` -------------------------------- ### Configure Ansible Lint GitHub Action Source: https://github.com/ansible/ansible-lint/blob/main/docs/installing.md Example configuration for using Ansible-lint as a GitHub Action. Create a file named .github/workflows/ansible-lint.yml with this content. ```yaml name: Ansible Lint on: [push, pull_request] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 with: ref: ${{ github.event.pull_request.head.sha }} fetch-depth: 0 - name: Run ansible-lint uses: ansible/ansible-lint-action@main id: lint with: targets: "./" ``` -------------------------------- ### Install Ansible-lint with locked dependencies Source: https://github.com/ansible/ansible-lint/blob/main/docs/installing.md Installs Ansible-lint along with the exact versions of its dependencies used for testing. This requires Python 3.10 or newer and should be done within a virtual environment. ```bash pip3 install "ansible-lint[lock]" ``` -------------------------------- ### Correct code without run_once Source: https://github.com/ansible/ansible-lint/blob/main/docs/rules/run-once.md This is a correct example that avoids the use of `run_once`, thus bypassing the linting rule. ```yaml - name: "Example without run_once" hosts: all gather_facts: false tasks: - name: Task without run_once ansible.builtin.debug: msg: "Test" ``` -------------------------------- ### Correct template with path from templates/ directory Source: https://github.com/ansible/ansible-lint/blob/main/docs/rules/no-relative-paths.md This example shows the recommended way to use the ansible.builtin.template module by specifying a path relative to the 'templates/' directory. ```yaml --- - name: Example playbook hosts: all tasks: - name: Template a file to /etc/file.conf ansible.builtin.template: src: foo.j2 # <- Uses a path from inside templates/ directory. dest: /etc/file.conf owner: bin group: wheel mode: "0644" ``` -------------------------------- ### Correct Code Without Tabs Source: https://github.com/ansible/ansible-lint/blob/main/docs/rules/no-tabs.md This example shows the correct way to write the code, avoiding tab characters to comply with the no-tabs rule. ```yaml --- - name: Example playbook hosts: all tasks: - name: Do not trigger the no-tabs rule ansible.builtin.debug: msg: "Using space characters avoids formatting issues." ``` -------------------------------- ### Avoid Ignoring All Errors Source: https://github.com/ansible/ansible-lint/blob/main/docs/rules/ignore-errors.md This example shows the problematic use of `ignore_errors: true`, which hides actual failures and can lead to unexpected behavior. ```yaml --- - name: Example playbook hosts: all tasks: - name: Run apt-get update ansible.builtin.command: apt-get update ignore_errors: true # <- Ignores all errors, including important failures. ``` -------------------------------- ### Ansible command module usage Source: https://github.com/ansible/ansible-lint/blob/main/src/ansiblelint/rules/command_instead_of_shell.md This example shows the correct way to execute a simple echo command using the `command` module, which is more efficient than `shell` for basic operations. ```yaml --- - name: Correct example hosts: localhost tasks: - name: Echo a message ansible.builtin.command: echo hello changed_when: false ``` -------------------------------- ### Avoid run_once with free strategy Source: https://github.com/ansible/ansible-lint/blob/main/docs/rules/run-once.md This example demonstrates the problematic use of `strategy: free` at the play level when `run_once: true` is used at the task level. It is recommended to avoid this combination. ```yaml --- - name: "Example with run_once" hosts: all strategy: free # <-- avoid use of strategy as free gather_facts: false tasks: - name: Task with run_once ansible.builtin.debug: msg: "Test" run_once: true # <-- avoid use of strategy as free at play level when using run_once at task level ``` -------------------------------- ### Correct Ansible Version Requirement Source: https://github.com/ansible/ansible-lint/blob/main/docs/rules/meta-runtime.md This example shows the correct, explicit version format for `requires_ansible` that is accepted by the linter. ```yaml --- requires_ansible: ">=2.17.0" ``` -------------------------------- ### Correct copy with path from files/ directory variable Source: https://github.com/ansible/ansible-lint/blob/main/docs/rules/no-relative-paths.md This example demonstrates the correct usage of the ansible.builtin.copy module with a variable pointing to a file within the 'files/' directory. ```yaml - name: Example playbook hosts: all vars: source_path: foo.j2 # <- Uses a path from inside files/ directory. tasks: - name: Copy a file to /etc/file.conf ansible.builtin.copy: src: "{{ source_path }}" # <- Uses the variable in the src argument. dest: /etc/foo.conf owner: foo group: foo mode: "0644" ``` -------------------------------- ### Jinja Spacing and Validity Example Source: https://github.com/ansible/ansible-lint/blob/main/docs/rules/jinja.md Demonstrates problematic Jinja2 syntax with spacing issues and invalid templates, alongside their corrected versions. This rule can be automatically fixed. ```yaml --- - name: Some task vars: foo: "{{some|dict2items}}" # <-- jinja[spacing] bar: "{{ & }}" # <-- jinja[invalid] when: "{{ foo | bool }}" # <-- jinja[spacing] - 'when' has implicit templating ``` ```yaml --- - name: Some task vars: foo: "{{ some | dict2items }}" bar: "{{ '&' }}" when: foo | bool ``` -------------------------------- ### Pipeline with pipefail using set -o pipefail Source: https://github.com/ansible/ansible-lint/blob/main/docs/rules/risky-shell-pipe.md This example demonstrates how to correctly use the `pipefail` option in a shell command pipeline by prefixing the command with `set -o pipefail`. ```yaml --- - name: Example playbook hosts: localhost become: false tasks: - name: Pipeline with pipefail ansible.builtin.shell: cmd: set -o pipefail && false | cat executable: /bin/bash ``` -------------------------------- ### Correct Ansible Role Metadata Tags Source: https://github.com/ansible/ansible-lint/blob/main/docs/rules/meta-no-tags.md This example demonstrates metadata tags using only lowercase letters and numbers, adhering to the rule's requirements. ```yaml --- # Metadata tags contain only lowercase letters and numbers. galaxy_info: galaxy_tags: [mytag1, mytag2] ``` -------------------------------- ### Correct Code without Tabs Source: https://github.com/ansible/ansible-lint/blob/main/src/ansiblelint/rules/no_tabs.md This example shows the correct way to write a playbook task without using tab characters, adhering to the no-tabs linting rule. ```yaml --- - name: Example playbook hosts: all tasks: - name: Do not trigger the no-tabs rule ansible.builtin.debug: msg: "Using space characters avoids formatting issues." ``` -------------------------------- ### Problematic ini_file usage Source: https://github.com/ansible/ansible-lint/blob/main/docs/rules/risky-file-permissions.md This example shows an unsafe usage of the `ini_file` module where `create` is set to `true` without specifying permissions, potentially leading to insecure file creation. ```yaml --- - name: Unsafe example of using ini_file community.general.ini_file: path: foo create: true ``` -------------------------------- ### Corrected YAML Code Examples Source: https://github.com/ansible/ansible-lint/blob/main/docs/rules/yaml.md Shows the corrected versions of the problematic YAML code, demonstrating how to properly handle octal values by quoting them and ensuring correct comment indentation. ```yaml --- foo: "0777" # <-- Explicitly quoting octal is less risky. foo2: "0o777" # <-- Explicitly quoting octal is less risky. bar: ... # Correct comment indentation. ``` -------------------------------- ### Valid Ansible Role Names Source: https://github.com/ansible/ansible-lint/blob/main/docs/rules/role-name.md Shows examples of role names that adhere to the required format: starting with an alphabetic character and containing only lowercase alphanumeric characters and underscores. ```yaml --- - name: Example playbook hosts: localhost roles: - myrole1 # <- Starts with an alphabetic character. - myrole2 # <- Contains only alphanumeric characters. - myrole_3 # <- Contains only lowercase alphabetic characters. ``` -------------------------------- ### Display Ansible-lint help Source: https://github.com/ansible/ansible-lint/blob/main/docs/usage.md Run this command to view all available options and command-line arguments. ```console $ ansible-lint --help ``` -------------------------------- ### Using run_once with a non-free strategy Source: https://github.com/ansible/ansible-lint/blob/main/docs/rules/run-once.md This example shows how to correctly use `run_once` by employing a strategy other than `free`, such as `linear`. It also demonstrates how to suppress the `run-once[play]` warning using a `noqa` comment if `strategy: free` is intentionally used. ```yaml - name: "Example of using run_once with strategy other than free" hosts: all strategy: linear # strategy: free # noqa: run-once[play] (if using strategy: free can skip it this way) gather_facts: false tasks: # <-- use noqa to disable rule violations for specific tasks - name: Task with run_once # noqa: run-once[task] ansible.builtin.debug: msg: "Test" run_once: true ``` -------------------------------- ### Build Documentation with Tox Source: https://github.com/ansible/ansible-lint/blob/main/docs/contributing.md Use tox to build the project's documentation. This command is essential for verifying that documentation changes, including new rules, are displayed correctly. ```bash tox -e docs ``` -------------------------------- ### Recommended delegate_to: localhost Usage Source: https://github.com/ansible/ansible-lint/blob/main/docs/rules/deprecated-local-action.md This snippet demonstrates the recommended way to run a task on the localhost control node using `delegate_to: localhost`. ```yaml - name: Task example ansible.builtin.debug: delegate_to: localhost # <-- recommended way to run on localhost ``` -------------------------------- ### Install Ansible-lint on Fedora/RHEL using dnf Source: https://github.com/ansible/ansible-lint/blob/main/docs/installing.md Installs Ansible-lint on Fedora or Red Hat Enterprise Linux (RHEL) using the dnf package manager. On RHEL, this package is part of the Red Hat Ansible Automation Platform subscription. ```bash dnf install ansible-lint ``` -------------------------------- ### Ansible Playbook Syntax Check Example Source: https://github.com/ansible/ansible-lint/blob/main/src/ansiblelint/rules/syntax_check.md This example demonstrates a common cause of syntax errors: using an undefined variable in the `hosts` block. It shows how to use the Jinja `default()` filter to provide a fallback value, preventing the error. ```yaml --- - name: Bad use of variable inside hosts block (wrong assumption of it being defined) hosts: "{{ my_hosts }}" tasks: [] ``` ```yaml --- - name: Good use of variable inside hosts, without assumptions hosts: "{{ my_hosts | default([]) }}" tasks: [] ``` -------------------------------- ### Safe ini_file usage with create: false Source: https://github.com/ansible/ansible-lint/blob/main/docs/rules/risky-file-permissions.md This example demonstrates a safe way to use the `ini_file` module by setting `create: false`, which prevents the module from creating a new file with default, potentially insecure permissions. ```yaml --- - name: Safe example of using ini_file (1st solution) community.general.ini_file: path: foo create: false # prevents creating a file with potentially insecure permissions ``` -------------------------------- ### Yamllint Configuration Error Message Source: https://github.com/ansible/ansible-lint/blob/main/src/ansiblelint/rules/yaml.md Example of an error message from ansible-lint when custom yamllint configuration is incompatible. ```shell CRITICAL Found incompatible custom yamllint configuration (.yamllint), please either remove the file or edit it to comply with: - comments.min-spaces-from-content must be 1 - braces.min-spaces-inside must be 0 - braces.max-spaces-inside must be 1 - octal-values.forbid-implicit-octal must be true - octal-values.forbid-explicit-octal must be true Read https://docs.ansible.com/projects/lint/rules/yaml/ for more details regarding why we have these requirements. ``` -------------------------------- ### Correct Playbook: Explicit become and become_user Source: https://github.com/ansible/ansible-lint/blob/main/docs/rules/partial-become.md These examples demonstrate correct usage where `become: true` is explicitly defined alongside `become_user`, either at the task level or the play level. This ensures clarity and prevents potential issues. ```yaml - name: Example playbook hosts: localhost tasks: - name: Start the httpd service as the apache user ansible.builtin.service: name: httpd state: started become: true # <- Activates privilege escalation. become_user: apache # <- Changes the user with the desired privileges. # Stand alone playbook alternative, applies to all tasks - name: Example playbook hosts: localhost become: true # <- Activates privilege escalation. become_user: apache # <- Changes the user with the desired privileges. tasks: - name: Start the httpd service as the apache user ansible.builtin.service: name: httpd state: started ``` -------------------------------- ### Correct Playbook with Included Tasks Source: https://github.com/ansible/ansible-lint/blob/main/docs/rules/partial-become.md This demonstrates the correct way to handle privilege escalation with included tasks. `become: true` is explicitly defined within the scope where `become_user` is used, ensuring the action is performed with the intended privileges. ```yaml --- - name: Example playbook 1 hosts: localhost tasks: - name: Include a task file ansible.builtin.include_tasks: tasks.yml ``` ```yaml --- - name: Example playbook 2 hosts: localhost tasks: - name: Include a task file ansible.builtin.include_tasks: tasks.yml ``` ```yaml # tasks.yml - name: Start the httpd service as the apache user ansible.builtin.service: name: httpd state: started become: true # <- Activates privilege escalation. become_user: apache # <- Changes the user with the desired privileges. ``` -------------------------------- ### Ignore Rules for Specific Files Source: https://github.com/ansible/ansible-lint/blob/main/docs/configuring.md Define rules to ignore for specific files in an `.ansible-lint-ignore` file. Comments start with '#'. ```yaml # this is just a comment playbook.yml package-latest # disable package-latest rule for playbook.yml playbook.yml deprecated-module ``` -------------------------------- ### Problematic template with relative path Source: https://github.com/ansible/ansible-lint/blob/main/docs/rules/no-relative-paths.md This example shows a relative path used in the 'src' argument of the ansible.builtin.template module, which is discouraged. ```yaml --- - name: Example playbook hosts: all tasks: - name: Template a file to /etc/file.conf ansible.builtin.template: src: ../my_templates/foo.j2 # <- Uses a relative path in the src argument. dest: /etc/file.conf owner: bin group: wheel mode: "0644" ``` -------------------------------- ### Safe ini_file usage with explicit mode Source: https://github.com/ansible/ansible-lint/blob/main/docs/rules/risky-file-permissions.md This example shows a safe usage of the `ini_file` module by explicitly defining the desired file permissions using the `mode` argument, ensuring predictable and secure file creation. ```yaml --- - name: Safe example of using ini_file (2nd solution) community.general.ini_file: path: foo mode: "0600" # explicitly sets the desired permissions, to make the results predictable ``` -------------------------------- ### Invalid Ansible Version Format Source: https://github.com/ansible/ansible-lint/blob/main/docs/rules/meta-runtime.md This example demonstrates an invalid version format for `requires_ansible` which will trigger a `meta-runtime[invalid-version]` warning. ```yaml --- requires_ansible: "2.17" ``` -------------------------------- ### List available rule tags Source: https://github.com/ansible/ansible-lint/blob/main/docs/usage.md Displays all available tags for rules. ```bash ansible-lint -T 2>/dev/null ``` -------------------------------- ### Unsupported Ansible Version Requirement Source: https://github.com/ansible/ansible-lint/blob/main/docs/rules/meta-runtime.md This example shows an unsupported short version format for `requires_ansible` which will trigger a `meta-runtime[unsupported-version]` warning. ```yaml --- requires_ansible: ">=2.9" ``` -------------------------------- ### Problematic galaxy.yml version Source: https://github.com/ansible/ansible-lint/blob/main/docs/rules/galaxy-version-incorrect.md This example shows a 'galaxy.yml' file with a 'version' key that is less than '1.0.0', violating the semantic versioning standard. ```yaml description: "description" namespace: "namespace_name" name: "collection_name" version: "0.0.1" # <- version key is not greater than or equal to '1.0.0'. readme: "README.md" authors: - "Author1" - "Author2 (https://author2.example.com)" - "Author3 " dependencies: "other_namespace.collection1": ">=1.0.0" "other_namespace.collection2": ">=2.0.0,<3.0.0" "anderson55.my_collection": "*" # note: "*" selects the highest version available license: - "MIT" tags: - demo - collection repository: "https://www.github.com/my_org/my_collection" ``` -------------------------------- ### Correct Code: Using FQCN for builtin shell module Source: https://github.com/ansible/ansible-lint/blob/main/docs/rules/fqcn.md This example demonstrates the correct usage of the 'shell' module with its FQCN from the 'ansible.builtin' collection. This is the preferred method for standard Ansible operations. ```yaml --- - name: Example playbook (2nd solution) hosts: all tasks: - name: Create an SSH connection # Use the FQCN for the builtin shell module. ansible.builtin.shell: ssh ssh_user@{{ ansible_ssh_host }} ``` -------------------------------- ### Correct Role Structure: Standalone Argument Spec File Source: https://github.com/ansible/ansible-lint/blob/main/src/ansiblelint/rules/role_argument_spec.md This demonstrates the correct structure for a role using a standalone `meta/argument_specs.yml` file to define its arguments. ```yaml # Option 1: Standalone file (meta/argument_specs.yml or .yaml) roles/ my_role/ tasks/ main.yml meta/ main.yml argument_specs.yml # <-- role argument specification ``` -------------------------------- ### JSON Schema Validation Error Example Source: https://github.com/ansible/ansible-lint/blob/main/test/schemas/negative_test/playbooks/gather_subset3.yml.md Illustrates a common JSON schema validation error where a value is expected to be a string but is found to be an integer. ```json { "message": "1 is not of type 'string'" } ``` -------------------------------- ### Problematic copy with relative path variable Source: https://github.com/ansible/ansible-lint/blob/main/docs/rules/no-relative-paths.md This example demonstrates using a variable that holds a relative path for the 'src' argument in the ansible.builtin.copy module. ```yaml - name: Example playbook hosts: all vars: source_path: ../../my_templates/foo.j2 # <- Sets a variable to a relative path. tasks: - name: Copy a file to /etc/file.conf ansible.builtin.copy: src: "{{ source_path }}" # <- Uses the variable in the src argument. dest: /etc/foo.conf owner: foo group: foo mode: "0644" ``` -------------------------------- ### Correct Video Link Formatting Source: https://github.com/ansible/ansible-lint/blob/main/docs/rules/meta-video-links.md Shows the correct way to format video links in metadata, using a dictionary with 'url' and 'title' keys, and a supported shared link. Ensure URLs are from YouTube, Vimeo, or Google Drive. ```yaml --- galaxy_info: video_links: - url: https://www.youtube.com/watch?v=aWmRepTSFKs&feature=youtu.be # <- Uses a supported shared link with the url key. title: Correctly formatted video link. ``` -------------------------------- ### Problematic Ansible Role Metadata Tags Source: https://github.com/ansible/ansible-lint/blob/main/docs/rules/meta-no-tags.md This example shows metadata tags containing uppercase letters and special characters, which are not allowed by the rule. ```yaml --- # Metadata tags contain upper-case letters and special characters. galaxy_info: galaxy_tags: [MyTag#1, MyTag&^-] ``` -------------------------------- ### Multi-line pipeline with pipefail Source: https://github.com/ansible/ansible-lint/blob/main/docs/rules/risky-shell-pipe.md This example shows a multi-line shell command pipeline where `pipefail` is enabled using `set -o pipefail` on a separate line, ensuring robust error handling. ```yaml --- - name: Example playbook hosts: localhost become: false tasks: - name: Pipeline with pipefail, multi-line ansible.builtin.shell: cmd: | set -o pipefail # <-- adding this will prevent surprises false | cat executable: /bin/bash ``` -------------------------------- ### Ajv Error Structure Example Source: https://github.com/ansible/ansible-lint/blob/main/test/schemas/negative_test/playbooks/ignore-unreachable.yml.md Illustrates the typical structure of an error object returned by Ajv. Includes instancePath, keyword, message, params, and schemaPath. ```json [ { "instancePath": "/0", "keyword": "oneOf", "message": "must match exactly one schema in oneOf", "params": { "passingSchemas": null }, "schemaPath": "#/items/oneOf" } ] ``` -------------------------------- ### Problematic Code with Tabs Source: https://github.com/ansible/ansible-lint/blob/main/src/ansiblelint/rules/no_tabs.md This example demonstrates how tab characters can be used in playbook tasks, triggering the no-tabs linting rule. Note the exception for `ansible.builtin.lineinfile`. ```yaml --- - name: Example playbook hosts: all tasks: - name: Do not trigger the rule ansible.builtin.lineinfile: path: some.txt regexp: '^\t$' line: 'string with \t inside' - name: Trigger the rule with a debug message ansible.builtin.debug: msg: "Using the \t character can cause formatting issues." # <- Includes the tab character. ``` -------------------------------- ### Correct Variable Names Source: https://github.com/ansible/ansible-lint/blob/main/docs/rules/var-naming.md Examples of variable names that comply with the naming rules, using only lowercase characters, underscores, and avoiding reserved or special names. ```yaml --- - name: Example playbook hosts: localhost vars: lowercase: true # <- Contains only lowercase characters. no_caps: bar # <- Does not contains uppercase characters. variable: baz # <- Does not contain special characters. my_hosts: [] # <- Does not use a reserved names. my_role_name: boo ``` -------------------------------- ### Specify Configuration File with CLI Source: https://github.com/ansible/ansible-lint/blob/main/docs/configuring.md Use the `-c` flag to specify a custom configuration file for Ansible-lint. ```bash ansible-lint -c path/to/ansible-lint-dev.yml ``` -------------------------------- ### Ansible shell module usage Source: https://github.com/ansible/ansible-lint/blob/main/src/ansiblelint/rules/command_instead_of_shell.md This example demonstrates the incorrect use of the `shell` module for a simple echo command. The `command` module is preferred for such tasks. ```yaml --- - name: Problematic example hosts: localhost tasks: - name: Echo a message ansible.builtin.shell: echo hello # <-- command is better in this case changed_when: false ``` -------------------------------- ### Correct Environment Variable Setting with 'environment' Keyword Source: https://github.com/ansible/ansible-lint/blob/main/src/ansiblelint/rules/inline_env_var.md This snippet shows the recommended method for setting environment variables using the 'environment' keyword. This approach ensures compatibility and avoids conflicts, making tasks more robust. ```yaml --- - name: Example playbook hosts: all tasks: - name: Set environment variable ansible.builtin.command: printenv MY_ENV_VAR environment: MY_ENV_VAR: my_value # <- Sets an environment variable with the environment keyword. ``` -------------------------------- ### Incorrectly Formatted Ignore Entry Source: https://github.com/ansible/ansible-lint/blob/main/docs/rules/sanity.md This example demonstrates an incorrectly formatted ignore entry. The file extension `.oops-3.6!skip` is not a valid format for an ignore entry. ```text # tests/sanity/ignore-x.x.txt plugins/module_utils/ansible_example_module.oops-3.6!skip ```