Introduction
Ansible, the renowned automation tool, simplifies the management and configuration of IT infrastructure. While Ansible empowers users with a wide range of modules to streamline tasks, it's vital to adhere to best practices for creating clean and predictable playbooks. Ansible-Lint, a popular linter for Ansible playbooks, enforces various rules to help you optimize your automation scripts. In this article, we delve into Rule 306, "risky-shell-pipe," in [Ansible-Lint](/articles/ansible-lint) which emphasizes the importance of using the bash pipefail option when employing the Ansible shell module to create pipelines. Setting pipefail ensures that tasks fail as expected if the first command in a pipeline fails.
Understanding Rule 306
Rule 306, "risky-shell-pipe," is a valuable guideline for Ansible playbook authors. It promotes the use of the pipefail option when creating pipelines with the Ansible shell module. When using pipelines to pass output from one command to another, it's crucial to set pipefail to ensure the reliability of task execution. The return status of a pipeline should reflect the exit status of the first command in the pipeline, ensuring that tasks fail if the initial command fails.
Problematic Code
Let's explore a problematic code snippet that Rule 306 can identify in your playbooks:
``yaml
---
- name: Example playbook
hosts: all
tasks:
- name: Pipeline without pipefail
ansible.builtin.shell: false | cat
`
In this code, the playbook creates a pipeline without setting the pipefail option. If the initial command (in this case, "false") fails, the task may not fail as expected, leading to unpredictable behavior.
Output:
`bash
WARNING Listing 2 violation(s) that are fatal
no-changed-when: Commands should not change things if nothing needs doing.
306.yml:5 Task/Handler: Pipeline without pipefail
risky-shell-pipe: Shells that use pipes should set the pipefail option.
306.yml:5 Task/Handler: Pipeline without pipefail
Read documentation for instructions on how to ignore specific rule violations.
Rule Violation Summary
count tag profile rule associated tags
1 risky-shell-pipe safety command-shell
1 no-changed-when shared command-shell, idempotency
Failed: 2 failure(s), 0 warning(s) on 1 files. Last profile that met the validation criteria was 'moderate'. Rating: 2/5 star
`
Correct Code
The corrected code that adheres to Rule 306 is as follows:
`yaml
---
- name: Example playbook
hosts: all
become: false
tasks:
- name: Pipeline with pipefail
ansible.builtin.shell:
cmd: set -o pipefail && false | cat
executable: /bin/bash
- name: Pipeline with pipefail, multi-line
ansible.builtin.shell:
cmd: |
set -o pipefail # <-- adding this will prevent surprises
false | cat
executable: /bin/bash
``
In the improved vers