Introduction

In the world of Ansible automation, best practices and efficiency are paramount. Ansible-Lint, a popular linting tool for Ansible playbooks, comes with a variety of rules to help you follow best practices, maintain consistency, and avoid common pitfalls. One such rule, Rule 303, "command-instead-of-module", in [Ansible-Lint](/articles/ansible-lint) recommends using specific Ansible modules in place of commands for tasks where modules are a more reliable and feature-rich choice.

Understanding Rule 303

Rule 303, "command-instead-of-module", serves as a friendly reminder that, in many cases, using Ansible modules is a better approach than running raw shell commands. Modules provide various benefits, including improved reliability, better messaging, and additional features like retry capabilities. By adhering to this rule, you can enhance the quality and maintainability of your Ansible playbooks.

Problematic Code

Let's examine a common issue that Rule 303 can help identify in your playbooks:

``yaml

---

  • name: Update apt cache

hosts: all

tasks:

- name: Run apt-get update

ansible.builtin.command: apt-get update # <-- better to use ansible.builtin.apt module

`

In this code snippet, a raw command (apt-get update) is used to update the apt cache. While this approach may work, it's not the most efficient or reliable way to achieve the task.

Output:

`bash

WARNING Listing 2 violation(s) that are fatal

command-instead-of-module: apt-get used in place of apt-get module

303.yml:5 Task/Handler: Run apt-get update

no-changed-when: Commands should not change things if nothing needs doing.

303.yml:5 Task/Handler: Run apt-get update

Read documentation for instructions on how to ignore specific rule violations.

Rule Violation Summary

count tag profile rule associated tags

1 command-instead-of-module basic command-shell, idiom

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 'min'.

`

Correct Code

Here's the corrected code that aligns with Rule 303:

`yaml

---

  • name: Update apt cache

hosts: all

tasks:

- name: Run apt-get update

ansible.builtin.apt:

update_cache: true

``

In the improved version, the "ansible.builtin.apt" module is utilized to update the apt cache. This module is purpose-built for managing packages and repositories, making the playbook more predictable and easier to maintain.

Why Use Modules Over Commands

Using modules over commands is an essential best practice in Ansible automation for several reasons:

1. Reliability: Modules are designed to be idempotent, meaning they only make changes when necessary. This ensures that your playbooks will consistently produce the desired state.

2. Readability: Modules often have better error messages an