Introduction
Error 205 (playbook-extension) is an ansible-lint rule that flags playbook files using incorrect file extensions. While Ansible itself accepts multiple extensions, following consistent naming conventions improves project organization and enables proper tooling integration.
The Error
When running ansible-lint, you may see:
WARNING Listing 1 violation(s) that are fatal
playbook-extension: Use ".yml" or ".yaml" playbook extension.
deploy.YML:1
Or in newer versions:
deploy.play (playbook-extension)
Playbooks should have the ".yml" or ".yaml" extension.
Root Cause
The ansible-lint rule playbook-extension enforces that all playbook files use one of the standard YAML extensions:
.yml(preferred).yaml(acceptable)
Files that trigger this error may have:
- Uppercase extensions:
.YML,.YAML - No extension at all:
deploy(no.yml) - Non-standard extensions:
.ansible,.playbook - Mixed case:
.Yml
The Fix
Option 1: Rename the File (Recommended)
# Fix uppercase extension
mv deploy.YML deploy.yml
# Fix missing extension
mv deploy deploy.yml
# Fix non-standard extension
mv deploy.ansible deploy.yml
Option 2: Configure ansible-lint to Accept Your Convention
If your organization uses .yaml instead of .yml, both are valid. But if you want to suppress the rule entirely:
.ansible-lint:
---
skip_list:
- playbook-extension # Allow any extension
Or to warn instead of error:
---
warn_list:
- playbook-extension
Best Practices for File Extensions
Standard Convention
| File Type | Recommended Extension | Example |
|---|---|---|
| Playbooks | .yml | deploy.yml, site.yml |
| Roles tasks | .yml | tasks/main.yml |
| Variable files | .yml | vars/main.yml |
| Inventory (YAML) | .yml | inventory.yml |
| Inventory (INI) | .ini or no extension | inventory |
| Requirements | .yml | requirements.yml |
File Naming Conventions
project/
├── site.yml # Main playbook
├── webservers.yml # Host-specific playbook
├── deploy-app.yml # Task-specific playbook
├── inventory/
│ ├── production.yml
│ └── staging.yml
├── roles/
│ └── nginx/
│ ├── tasks/
│ │ └── main.yml
│ ├── handlers/
│ │ └── main.yml
│ ├── templates/
│ │ └── nginx.conf.j2
│ └── vars/
│ └── main.yml
└── group_vars/
├── all.yml
└── webservers.yml
Why .yml Over .yaml?
Both work identically, but .yml is the Ansible community standard:
- Official Ansible documentation uses
.yml ansible-galaxy initgenerates.ymlfiles- Most online examples use
.yml - Shorter (saves 1 character in hundreds of files)
Choose one and stick with it project-wide for consistency.
Configuring ansible-lint
Full .ansible-lint Configuration
---
# .ansible-lint
profile: production # or: min, basic, moderate, safety, shared
# Rules to skip entirely
skip_list:
- yaml[line-length] # Allow long lines
# Rules that warn instead of fail
warn_list:
- experimental # Experimental rules
# Exclude paths from linting
exclude_paths:
- .github/
- collections/
- molecule/
# File extensions to look for
kinds:
- playbook: "**/playbooks/*.yml"
- tasks: "**/tasks/*.yml"
- vars: "**/vars/*.yml"
- meta: "**/meta/*.yml"
Running ansible-lint
# Lint all playbooks in current directory
ansible-lint
# Lint a specific file
ansible-lint deploy.yml
# Lint with specific profile
ansible-lint -p moderate
# List all rules
ansible-lint -L
# Show rule details
ansible-lint -R -r playbook-extension
Related Ansible-lint Errors
| Rule | ID | Description |
|---|---|---|
playbook-extension | 205 | Wrong file extension |
yaml[truthy] | — | Use true/false not yes/no |
name[missing] | — | Tasks should have names |
fqcn[action-core] | — | Use fully qualified module names |
no-changed-when | — | Commands need changed_when |
risky-shell-pipe | — | Shell pipes may hide errors |
Complete Example: Correct Project Structure
# site.yml (correct extension, lowercase)
---
- name: Deploy web application
hosts: webservers
become: true
roles:
- nginx
- app
- name: Configure database
hosts: dbservers
become: true
roles:
- postgresql
# Run lint to verify
$ ansible-lint site.yml
Passed: 0 failure(s), 0 warning(s)
Bulk Rename Script
If you have many files to fix:
#!/bin/bash
# Fix all uppercase .YML extensions
find . -name "*.YML" -exec bash -c 'mv "$0" "${0%.YML}.yml"' {} \;
# Fix all .YAML extensions
find . -name "*.YAML" -exec bash -c 'mv "$0" "${0%.YAML}.yml"' {} \;
# Fix .yaml to .yml (optional, for consistency)
find . -name "*.yaml" -exec bash -c 'mv "$0" "${0%.yaml}.yml"' {} \;
Related Articles
- Ansible-lint Guide — Complete linting configuration
- Ansible FQCN Guide — Fix fqcn lint errors
- Ansible Playbook Best Practices — Writing clean playbooks
- Ansible Troubleshooting — Common errors and solutions
Conclusion
Error 205 (playbook-extension) is a simple naming convention issue. Rename your playbook files to use .yml (lowercase), which is the Ansible community standard. Configure .ansible-lint in your project root to set your team's linting standards and ensure consistency across all contributors.