Introduction

The name[prefix] rule in Ansible Lint recommends prefixing task names with the file stem (filename without .yml) in task files that are not main.yml. This opt-in rule improves traceability — when a task fails, the prefix immediately tells you which file contains the failing task, eliminating guesswork in complex roles with multiple task files.

Why Task Naming Matters

When a playbook fails, Ansible shows the task name in the output:

TASK [webserver : Restart nginx] ***********
fatal: [web01]: FAILED! => {"changed": false, "msg": "..."}

In a simple role, this is clear enough. But in complex roles with multiple included task files:

roles/webserver/
├── tasks/
│   ├── main.yml
│   ├── install.yml
│   ├── configure.yml
│   ├── ssl.yml
│   └── monitoring.yml

If a task named "Restart nginx" fails, which file is it in? configure.yml? ssl.yml? With the name[prefix] rule, the task would be named ssl | Restart nginx, immediately identifying the source file.

The Rule

Problematic Code

File: tasks/install.yml

---
- name: Install nginx packages
  ansible.builtin.apt:
    name: nginx
    state: present

- name: Install certbot
  ansible.builtin.apt:
    name: certbot
    state: present

Lint Output

$ ansible-lint tasks/install.yml
WARNING  Listing 2 violation(s) that are fatal
name[prefix]: Task name should start with 'install | '
tasks/install.yml:2 Task/Handler: Install nginx packages

name[prefix]: Task name should start with 'install | '
tasks/install.yml:7 Task/Handler: Install certbot

Failed: 2 failure(s), 0 warning(s)

Correct Code

---
- name: install | Install nginx packages
  ansible.builtin.apt:
    name: nginx
    state: present

- name: install | Install certbot
  ansible.builtin.apt:
    name: certbot
    state: present

Enabling the Rule

The name[prefix] rule is opt-in — it's not active by default. Enable it in your .ansible-lint configuration:

# .ansible-lint
enable_list:
  - name[prefix]

Or in YAML format with other settings:

# .ansible-lint
enable_list:
  - name[prefix]

skip_list: []

warn_list:
  - experimental

How the Prefix Is Determined

The expected prefix is the file stem — the filename without the .yml or .yaml extension:

File PathExpected Prefix
tasks/install.ymlinstall |
tasks/configure.ymlconfigure |
tasks/ssl.ymlssl |
tasks/backup-db.ymlbackup-db |
handlers/main.yml(not required — main.yml is exempt)
tasks/main.yml(not required — main.yml is exempt)

Complete Role Example

Directory Structure

roles/webserver/
├── tasks/
│   ├── main.yml
│   ├── install.yml
│   ├── configure.yml
│   ├── ssl.yml
│   └── monitoring.yml
├── handlers/
│   └── main.yml
├── templates/
│   └── nginx.conf.j2
└── defaults/
    └── main.yml

tasks/main.yml (No Prefix Needed)

---
- name: Include installation tasks
  ansible.builtin.include_tasks: install.yml

- name: Include configuration tasks
  ansible.builtin.include_tasks: configure.yml

- name: Include SSL tasks
  ansible.builtin.include_tasks: ssl.yml
  when: ssl_enabled | default(false)

- name: Include monitoring tasks
  ansible.builtin.include_tasks: monitoring.yml
  when: monitoring_enabled | default(false)

tasks/install.yml

---
- name: install | Update apt cache
  ansible.builtin.apt:
    update_cache: true
    cache_valid_time: 3600

- name: install | Install nginx
  ansible.builtin.apt:
    name: nginx
    state: present

- name: install | Install supporting packages
  ansible.builtin.apt:
    name:
      - certbot
      - python3-certbot-nginx
    state: present

tasks/configure.yml

---
- name: configure | Deploy nginx.conf
  ansible.builtin.template:
    src: nginx.conf.j2
    dest: /etc/nginx/nginx.conf
    mode: "0644"
  notify: restart nginx

- name: configure | Create site directories
  ansible.builtin.file:
    path: "{{ item }}"
    state: directory
    mode: "0755"
  loop:
    - /var/www/html
    - /var/log/nginx

- name: configure | Enable nginx service
  ansible.builtin.service:
    name: nginx
    enabled: true
    state: started

tasks/ssl.yml

---
- name: ssl | Request SSL certificate
  ansible.builtin.command: >
    certbot certonly --nginx
    -d {{ server_domain }}
    --non-interactive --agree-tos
    --email {{ admin_email }}
  args:
    creates: /etc/letsencrypt/live/{{ server_domain }}/fullchain.pem

- name: ssl | Deploy SSL nginx config
  ansible.builtin.template:
    src: nginx-ssl.conf.j2
    dest: /etc/nginx/sites-enabled/{{ server_domain }}.conf
    mode: "0644"
  notify: restart nginx

- name: ssl | Set up certificate renewal cron
  ansible.builtin.cron:
    name: "ssl | Certbot renewal"
    hour: "3"
    minute: "0"
    weekday: "1"
    job: "certbot renew --quiet"

Failure Output Comparison

Without Prefix

TASK [webserver : Restart nginx] ***********
fatal: [web01]: FAILED! =>
  {"msg": "Unable to restart service nginx: ..."}

# Which file? install.yml? configure.yml? ssl.yml?

With Prefix

TASK [webserver : ssl | Restart nginx] *****
fatal: [web01]: FAILED! =>
  {"msg": "Unable to restart service nginx: ..."}

# Immediately clear: the issue is in tasks/ssl.yml

Applying to Handlers

The rule also applies to handler files that aren't main.yml:

# handlers/restart.yml
---
- name: restart | Restart nginx
  ansible.builtin.service:
    name: nginx
    state: restarted

- name: restart | Restart php-fpm
  ansible.builtin.service:
    name: php-fpm
    state: restarted

The name rule has several sub-rules:

Sub-ruleDescriptionProfile
name[play]All plays must have a nameBasic
name[casing]Task names should start with uppercaseBasic
name[prefix]Prefix task names with file stemOpt-in
name[template]Don't use Jinja2 in task namesOpt-in
name[missing]All tasks must have a nameBasic

Combining with name[casing]

# ❌ Wrong — lowercase after prefix
- name: install | install nginx
  ansible.builtin.apt:
    name: nginx

# ✅ Right — capitalize after prefix
- name: install | Install nginx
  ansible.builtin.apt:
    name: nginx

Auto-Fixing

ansible-lint can auto-add prefixes:

# Preview what would change
ansible-lint --fix --diff roles/webserver/

# Apply fixes
ansible-lint --fix roles/webserver/

Best Practices

  1. Enable the rule for complex roles — roles with 3+ task files benefit most
  2. Keep prefixes short — use the filename stem as-is; don't add extra words
  3. Use consistent separator — always prefix | Task description (pipe with spaces)
  4. Capitalize after the prefix — install | Install nginx, not install | install nginx
  5. Skip for simple roles — if your role has only main.yml, the rule adds no value
  6. Apply to handlers too — consistency across task and handler files
  7. Use descriptive filenames — the filename becomes part of the task name, so ssl.yml is better than step3.yml

Conclusion

The name[prefix] rule is an opt-in best practice that significantly improves debugging in complex roles. By prefixing task names with the file stem (install | Install nginx), you immediately know which file contains a failing task. Enable it in .ansible-lint with enable_list: [name[prefix]], and use ansible-lint --fix to auto-apply prefixes to existing task files.