Skip to main content

129. Numbered Role-Based Organization

Status: Accepted Date: 2025-07-06

Context

In Ansible, the order in which tasks are executed is critical. For example, you must configure the APT package manager before you can use it to install software. You must install chezmoi before you can run it to deploy dotfiles.

While Ansible playbooks do have an explicit execution order, relying solely on the order of roles listed in a playbook can become hard to manage as the number of roles grows. It's not immediately obvious from the directory structure what the intended order of operations is.

Decision

We will adopt a numbered, role-based organization for our Ansible project.

  1. All automation will be organized into roles. Each role will have a single, well-defined responsibility (e.g., 01_common, 02_ssh, 08_docker).
  2. Role directories will be prefixed with a two-digit number. This number explicitly defines the intended execution order. 01_common is designed to run before 02_ssh, which runs before 06_python, and so on.

This convention makes the intended execution flow immediately obvious just by looking at the roles/ directory. The main playbooks will then simply list these roles in their numerical order, reinforcing the convention.

Consequences

Positive:

  • Explicit Execution Order: The numbering system makes the dependency chain and execution order crystal clear. There is no ambiguity about what should run when. This is invaluable for debugging and for new developers trying to understand the provisioning process.
  • Enhanced Readability: A developer can understand the entire provisioning flow simply by reading the directory listing of the roles/ directory in numerical order.
  • Enforces Modularity: This structure encourages thinking about the provisioning process as a series of discrete, ordered steps, which naturally leads to well-defined, modular roles.

Negative:

  • Slightly Unconventional: This is not the default way of organizing roles suggested by the Ansible documentation.
  • Renaming Can Be Cumbersome: If we need to insert a new role between 05_... and 06_..., it requires renaming all subsequent roles (06_... becomes 07_..., etc.).

Mitigation:

  • A Known, Effective Pattern: While not the default, this numbered-prefix pattern is a well-known and effective way of managing complex Ansible projects. Its benefits in clarity far outweigh the deviation from the default.
  • Gaps in Numbering: We can leave deliberate gaps in the numbering sequence (e.g., 01, 02, 05, 06, 10) to provide space for inserting new roles in the future without requiring a full renumbering. The order is what matters, not the consecutive sequence.
  • Infrequent Changes: The foundational order of operations (e.g., configure package manager -> install core utilities -> install language runtimes -> deploy apps) is very stable. Changes to the core ordering should be rare.