# Name Every Ansible Task
## Rule
Every task MUST have a descriptive `name` field. Task names MUST describe WHAT the task does, not HOW. Use sentence case without trailing periods.
## Format
```yaml
- name: Install required system packages
ansible.builtin.apt:
name: "{{ packages }}"
state: present
```
## Good Examples
```yaml
- name: Install Nginx web server
ansible.builtin.apt:
name: nginx
state: present
- name: Deploy application configuration
ansible.builtin.template:
src: app.conf.j2
dest: /etc/myapp/config.yml
notify: Restart application
- name: Create application system user
ansible.builtin.user:
name: myapp
system: true
shell: /usr/sbin/nologin
- name: Ensure firewall allows HTTPS traffic
community.general.ufw:
rule: allow
port: "443"
proto: tcp
```
## Bad Examples
```yaml
# BAD: No name (output shows module name only — useless for debugging)
- ansible.builtin.apt:
name: nginx
state: present
# BAD: Name describes implementation, not intent
- name: apt install nginx
ansible.builtin.apt:
name: nginx
# BAD: Too vague
- name: Do stuff
ansible.builtin.shell: ./setup.sh
# BAD: Name is just the variable
- name: "{{ package_name }}"
ansible.builtin.apt:
name: "{{ package_name }}"
```
## Why Names Matter
```
# With names (easy to understand and debug):
TASK [Install Nginx web server] ****************************
ok: [web-01]
TASK [Deploy application configuration] ********************
changed: [web-01]
TASK [Ensure firewall allows HTTPS traffic] ****************
ok: [web-01]
# Without names (impossible to understand):
TASK [ansible.builtin.apt] *********************************
ok: [web-01]
TASK [ansible.builtin.template] ****************************
changed: [web-01]
TASK [community.general.ufw] *******************************
ok: [web-01]
```
## Enforcement
- ansible-lint rule: name[missing] (enabled by default)
- CI pipeline with ansible-lint --strict
- Code review checklist includes task naming verification