Comprehensive toolkit for validating, linting, testing, and automating Ansible playbooks, roles, and collections. Use this skill when working with Ansible files (.yml, .yaml playbooks, roles, inventories), validating automation code, debugging playbook execution, performing dry-run testing with check mode, or working with custom modules and collections.
Overall
score
100%
Does it follow best practices?
Validation for skill structure
This directory contains test materials for validating the ansible-validator skill, including both playbooks and roles.
test/
├── README.md # This file
├── playbooks/ # Example playbooks for testing
│ ├── good-playbook.yml # Well-written playbook
│ └── bad-playbook.yml # Playbook with issues
└── roles/ # Test roles
└── geerlingguy.mysql/ # Production-quality MySQL roleA well-written Ansible playbook that follows best practices:
Expected validation results: Should pass all checks (yamllint, ansible-lint, syntax check)
A poorly-written playbook with multiple issues:
Expected validation results: Should fail multiple checks and report numerous issues
This is a well-maintained, production-quality Ansible role by Jeff Geerling for installing and configuring MySQL.
Source: https://github.com/geerlingguy/ansible-role-mysql
Features:
This role serves as an excellent example for:
# Validate good playbook (should pass)
bash ../scripts/validate_playbook.sh playbooks/good-playbook.yml
# Validate bad playbook (should fail with multiple errors)
bash ../scripts/validate_playbook.sh playbooks/bad-playbook.yml
# Extract modules from playbook
bash ../scripts/extract_ansible_info_wrapper.sh playbooks/good-playbook.yml
bash ../scripts/extract_ansible_info_wrapper.sh playbooks/bad-playbook.yml
# Individual validation steps
yamllint -c ../assets/.yamllint playbooks/good-playbook.yml
ansible-playbook --syntax-check playbooks/good-playbook.yml # if ansible installed
ansible-lint -c ../assets/.ansible-lint playbooks/good-playbook.yml # if ansible-lint installed# Comprehensive role validation
bash ../scripts/validate_role.sh roles/geerlingguy.mysql
# This checks:
# - Role directory structure
# - YAML syntax (yamllint)
# - Ansible syntax (if ansible is installed)
# - Ansible lint (if ansible-lint is installed)
# - Molecule configuration# Extract modules from role
bash ../scripts/extract_ansible_info_wrapper.sh roles/geerlingguy.mysql
# Extract modules from playbook
bash ../scripts/extract_ansible_info_wrapper.sh playbooks/good-playbook.yml# Run full molecule test suite
# Note: Molecule will be automatically installed in a temporary venv if not already installed
bash ../scripts/test_role.sh roles/geerlingguy.mysql
# Or run molecule directly (if installed)
cd roles/geerlingguy.mysql
molecule testNote: The test_role.sh script automatically handles molecule installation. If molecule is not found on your system, the script will:
No permanent installation required!
To add additional test roles for validation:
# Download from Ansible Galaxy
cd test/roles
ansible-galaxy role install namespace.rolename -p .
# Or clone from GitHub
git clone https://github.com/author/ansible-role-name.git author.rolenamePopular, well-maintained roles for testing:
# Web servers
git clone https://github.com/geerlingguy/ansible-role-apache.git geerlingguy.apache
git clone https://github.com/geerlingguy/ansible-role-nginx.git geerlingguy.nginx
# Databases
git clone https://github.com/geerlingguy/ansible-role-postgresql.git geerlingguy.postgresql
git clone https://github.com/geerlingguy/ansible-role-redis.git geerlingguy.redis
# Languages/Runtimes
git clone https://github.com/geerlingguy/ansible-role-php.git geerlingguy.php
git clone https://github.com/geerlingguy/ansible-role-nodejs.git geerlingguy.nodejs
# DevOps tools
git clone https://github.com/geerlingguy/ansible-role-docker.git geerlingguy.docker
git clone https://github.com/geerlingguy/ansible-role-kubernetes.git geerlingguy.kubernetes#!/bin/bash
# test_all_roles.sh - Validate all roles in test directory
for role in roles/*; do
if [ -d "$role" ]; then
echo "Validating $(basename $role)..."
bash ../scripts/validate_role.sh "$role"
echo ""
fi
done#!/bin/bash
# extract_all_modules.sh - Extract modules from all roles
for role in roles/*; do
if [ -d "$role" ]; then
echo "=== $(basename $role) ==="
bash ../scripts/extract_ansible_info_wrapper.sh "$role"
echo ""
fi
doneThe validation scripts can detect:
Structure Issues:
Syntax Issues:
Best Practice Violations:
Security Issues:
Documentation Issues:
The geerlingguy.mysql role includes molecule configuration:
molecule/
└── default/
├── molecule.yml # Molecule configuration
├── converge.yml # Playbook to test the role
└── verify.yml # Verification testscd roles/geerlingguy.mysql
# Full test sequence
molecule test
# Individual stages
molecule create # Create test instances
molecule converge # Run the role
molecule verify # Run verification tests
molecule destroy # Clean up
# Debug mode
molecule converge
molecule login # SSH into test instanceTo create a minimal test role:
mkdir -p test/roles/mytest/tasks
cat > test/roles/mytest/tasks/main.yml <<EOF
---
- name: Install package
apt:
name: vim
state: present
when: ansible_os_family == "Debian"
EOF
# Validate it
bash scripts/validate_role.sh test/roles/mytestThese test roles can be used in CI/CD pipelines:
# .github/workflows/validate-roles.yml
name: Validate Ansible Roles
on: [push, pull_request]
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install dependencies
run: |
pip install ansible ansible-lint yamllint
- name: Validate all roles
run: |
for role in test/roles/*; do
bash scripts/validate_role.sh "$role"
doneInstall Ansible:
pip install ansibleThe test_role.sh script will automatically install molecule in a temporary venv, but you still need Docker installed for molecule to create test containers:
# macOS
brew install docker
# Start Docker Desktop
open -a Docker
# Linux
sudo apt-get install docker.io # Debian/Ubuntu
sudo yum install docker # RHEL/CentOSNote: Molecule itself doesn't need to be installed - the script handles that automatically.
This is acceptable for readability. Adjust .yamllint if needed:
rules:
line-length:
max: 200 # Increase limit
level: warning