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
| Rule | Bad | Good |
|---|---|---|
| Describe the action | name: yum | name: Install nginx |
| Be specific | name: Configure | name: Configure nginx virtual host |
| Use imperative mood | name: Nginx is installed | name: Install nginx |
| Include the target | name: Start service | name: Start nginx service |
| Don't repeat the module | name: Copy file using copy | name: 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]
Related Rules
| Rule | What 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) |
Related Articles
- Ansible-Lint Guide
- literal-compare Rule (601)
- syntax-check Rule (911)
- no-tabs Rule (203)
- Ansible Best Practices Guide
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.