Introduction

Rule 502 (name[missing]) in ansible-lint requires every task and play to have a name field. Names are how you identify what happened in Ansible output, logs, AWX/Tower job reports, and debugging sessions. Without names, output looks like cryptic module calls instead of a readable execution log.

The Error

---
- hosts: all
  tasks:
    - ansible.builtin.command: touch /tmp/.placeholder
$ ansible-lint playbook.yml
name[play]: All plays should be named.
playbook.yml:2

name[missing]: All tasks should be named.
playbook.yml:4 Task/Handler: command touch /tmp/.placeholder

The Fix

---
- name: Create placeholder files
  hosts: all
  tasks:
    - name: Create placeholder file
      ansible.builtin.command: touch /tmp/.placeholder
      args:
        creates: /tmp/.placeholder

Why Names Matter

Ansible Output Without Names

TASK [command] ***************************************************************
changed: [web1]

TASK [command] ***************************************************************
changed: [web1]

TASK [copy] ******************************************************************
changed: [web1]

Which task did what? Impossible to tell.

Ansible Output With Names

TASK [Stop application service] **********************************************
changed: [web1]

TASK [Run database migration] ************************************************
changed: [web1]

TASK [Deploy application config] *********************************************
changed: [web1]

Now you can:

  • Debug failures instantly
  • Review AWX/Tower job output
  • Understand playbooks months later
  • Search logs for specific operations

Writing Good Task Names

Rules

RuleBadGood
Describe the actionname: yumname: Install nginx
Be specificname: Configurename: Configure nginx virtual host
Use imperative moodname: Nginx is installedname: Install nginx
Include the targetname: Start servicename: Start nginx service
Don't repeat the modulename: Copy file using copyname: Deploy nginx config

Examples

# ❌ Bad names
- name: Task 1
- name: Do stuff
- name: yum
- name: Run command

# ✅ Good names
- name: Install web server packages
- name: Deploy application configuration
- name: Create database backup directory
- name: Restart nginx after config change

Edge Cases

Plays Need Names Too

# ❌ Triggers name[play]
- hosts: webservers
  tasks: [...]

# ✅ Fixed
- name: Configure web servers
  hosts: webservers
  tasks: [...]

Handlers Need Names

# ✅ Handlers must be named (they're referenced by name)
handlers:
  - name: Restart nginx
    ansible.builtin.systemd:
      name: nginx
      state: restarted

Blocks Inherit Names

# The block itself can be named; inner tasks still need names
- name: Deploy application
  block:
    - name: Stop service
      ansible.builtin.systemd:
        name: myapp
        state: stopped

    - name: Update binary
      ansible.builtin.copy:
        src: myapp
        dest: /usr/local/bin/myapp

  rescue:
    - name: Rollback on failure
      ansible.builtin.command: /opt/rollback.sh

include_tasks and import_tasks

# The include/import itself should be named
- name: Include database tasks
  ansible.builtin.include_tasks: database.yml

# Tasks inside the included file also need names

Roles

Tasks in roles/*/tasks/main.yml also need names:

# roles/nginx/tasks/main.yml
- name: Install nginx
  ansible.builtin.yum:
    name: nginx
    state: present

- name: Deploy nginx configuration
  ansible.builtin.template:
    src: nginx.conf.j2
    dest: /etc/nginx/nginx.conf

Suppressing the Rule

# Per-task (not recommended)
- ansible.builtin.debug:  # noqa: name[missing]
    var: result

# In .ansible-lint (avoid globally)
skip_list:
  - name[missing]

# Better: skip only name[play] if you have single-play files
skip_list:
  - name[play]
RuleWhat It Checks
name[missing] (502)Task/handler has no name
name[play]Play has no name
name[casing]Name doesn't start with uppercase
name[template]Name contains Jinja2 templates (fragile)

Conclusion

Name every task, play, and handler with a descriptive imperative phrase: "Install nginx", "Deploy configuration", "Create backup directory". Good names make Ansible output readable, debugging faster, and playbooks maintainable. The rule is in the basic lint profile — it's considered essential for any Ansible project.