Skip to content
Skillv1.0.0

ansible-expert

Expert-level Ansible for configuration management, automation, and infrastructure as code. Use when the user mentions automation, configuration management, infrastructure as code, playbooks, or roles,

by personamanagmentlayer(0) 0 installs
Free
Sign in to install

Free account. Installing gives you the manifest plus copy-paste snippets.

See reviews

About

Imported from personamanagmentlayer/pcl (stdlib/devops/ansible-expert/SKILL.md) via skills.sh. Install upstream with npx skills add personamanagmentlayer/pcl --skill ansible-expert. Copyright stays with the author.

Ansible Expert

Expert guidance for Ansible - configuration management, application deployment, and IT automation using declarative YAML playbooks.

Core Concepts

Ansible Architecture

  • Control node (runs Ansible)
  • Managed nodes (target systems)
  • Inventory (hosts and groups)
  • Playbooks (YAML automation scripts)
  • Modules (units of work)
  • Roles (reusable automation units)
  • Plugins (extend functionality)

Key Features

  • Agentless (SSH-based)
  • Idempotent operations
  • Declarative syntax
  • Human-readable YAML
  • Extensible with modules
  • Push-based configuration
  • Parallel execution

Use Cases

  • Configuration management
  • Application deployment
  • Provisioning
  • Continuous delivery
  • Security automation
  • Orchestration

Installation

# Using pip
pip install ansible

# Using apt (Ubuntu/Debian)
sudo apt update
sudo apt install ansible

# Using yum (RHEL/CentOS)
sudo yum install ansible

# Verify installation
ansible --version

Inventory

Basic Inventory (INI format)

# inventory/hosts
[webservers]
web1.example.com
web2.example.com ansible_host=192.168.1.10

[databases]
db1.example.com ansible_user=dbadmin
db2.example.com

[production:children]
webservers
databases

[production:vars]
ansible_python_interpreter=/usr/bin/python3
ansible_connection=ssh

YAML Inventory

# inventory/hosts.yml
all:
  children:
    webservers:
      hosts:
        web1.example.com:
        web2.example.com:
          ansible_host: 192.168.1.10
    databases:
      hosts:
        db1.example.com:
          ansible_user: dbadmin
        db2.example.com:
    production:
      children:
        webservers:
        databases:
      vars:
        ansible_python_interpreter: /usr/bin/python3
        ansible_connection: ssh

Dynamic Inventory

#!/usr/bin/env python3
# inventory/aws_ec2.py
import json
import boto3

def get_inventory():
    ec2 = boto3.client('ec2', region_name='us-east-1')
    response = ec2.describe_instances(Filters=[
        {'Name': 'instance-state-name', 'Values': ['running']}
    ])

    inventory = {
        '_meta': {'hostvars': {}},
        'all': {'hosts': []},
        'webservers': {'hosts': []},
        'databases': {'hosts': []},
    }

    for reservation in response['Reservations']:
        for instance in reservation['Instances']:
            ip = instance['PrivateIpAddress']
            tags = {tag['Key']: tag['Value'] for tag in instance.get('Tags', [])}

            inventory['all']['hosts'].append(ip)
            inventory['_meta']['hostvars'][ip] = {
                'ansible_host': ip,
                'instance_id': instance['InstanceId'],
                'instance_type': instance['InstanceType'],
            }

            # Group by role tag
            role = tags.get('Role', '')
            if role in inventory:
                inventory[role]['hosts'].append(ip)

    return inventory

if __name__ == '__main__':
    print(json.dumps(get_inventory(), indent=2))

Templates (Jinja2)

{# templates/app.conf.j2 #}
# Application configuration for {{ app_name }}
# Generated by Ansible on {{ ansible_date_time.iso8601 }}

[server]
host = {{ ansible_default_ipv4.address }}
port = {{ app_port }}
workers = {{ ansible_processor_vcpus }}

[database]
host = {{ db_host }}
port = {{ db_port }}
name = {{ db_name }}
user = {{ db_user }}
password = {{ db_password }}

[cache]
enabled = {{ cache_enabled | default(true) | lower }}
{% if cache_enabled | default(true) %}
backend = redis
redis_host = {{ redis_host }}
redis_port = {{ redis_port }}
{% endif %}

[features]
{% for feature, enabled in features.items() %}
{{ feature }} = {{ enabled | lower }}
{% endfor %}

{% if environment == 'production' %}
[production]
debug = false
log_level = warning
{% else %}
[development]
debug = true
log_level = debug
{% endif %}

Variables and Facts

Variable Precedence (low to high)

  1. Role defaults
  2. Inventory file/script group vars
  3. Inventory group_vars/all
  4. Playbook group_vars/all
  5. Inventory group_vars/*
  6. Playbook group_vars/*
  7. Inventory file/script host vars
  8. Inventory host_vars/*
  9. Playbook host_vars/*
  10. Host facts
  11. Play vars
  12. Play vars_prompt
  13. Play vars_files
  14. Role vars
  15. Block vars
  16. Task vars
  17. Extra vars (-e flag)

Using Variables

---
- name: Variable examples
  hosts: all
  vars:
    app_name: myapp
    app_version: 1.0.0
  vars_files:
    - vars/common.yml
    - 'vars/{{ environment }}.yml'

  tasks:
    - name: Load variables from file
      include_vars:
        file: 'vars/{{ ansible_distribution }}.yml'

    - name: Set fact
      set_fact:
        full_app_name: '{{ app_name }}-{{ app_version }}'

    - name: Register output
      command: hostname
      register: hostname_output

    - name: Use registered variable
      debug:
        msg: 'Hostname is {{ hostname_output.stdout }}'

    - name: Access facts
      debug:
        msg: |
          OS: {{ ansible_distribution }} {{ ansible_distribution_version }}
          Kernel: {{ ansible_kernel }}
          CPU: {{ ansible_processor_vcpus }} cores
          Memory: {{ ansible_memtotal_mb }} MB
          IP: {{ ansible_default_ipv4.address }}

Error Handling

---
- name: Error handling examples
  hosts: all
  tasks:
    - name: Task that might fail
      command: /bin/false
      ignore_errors: yes

    - name: Task with custom error handling
      block:
        - name: Try to start service
          systemd:
            name: myapp
            state: started
      rescue:
        - name: Log error
          debug:
            msg: 'Failed to start myapp'

        - name: Try alternative
          systemd:
            name: myapp-fallback
            state: started
      always:
        - name: This always runs
          debug:
            msg: 'Cleanup task'

    - name: Assert condition
      assert:
        that:
          - ansible_memtotal_mb >= 2048
          - ansible_processor_vcpus >= 2
        fail_msg: 'Server does not meet minimum requirements'

    - name: Fail when condition
      fail:
        msg: 'Production deployment requires version tag'
      when:
        - environment == 'production'
        - app_version == 'latest'

    - name: Changed when condition
      command: /usr/local/bin/check_status.sh
      register: result
      changed_when: "'updated' in result.stdout"
      failed_when: result.rc not in [0, 2]

Ansible Vault

# Create encrypted file
ansible-vault create secrets.yml

# Edit encrypted file
ansible-vault edit secrets.yml

# Encrypt existing file
ansible-vault encrypt vars/production.yml

# Decrypt file
ansible-vault decrypt vars/production.yml

# View encrypted file
ansible-vault view secrets.yml

# Rekey (change password)
ansible-vault rekey secrets.yml
# secrets.yml - what `ansible-vault view secrets.yml` shows you.
# On disk this file is ciphertext; it is only ever plaintext in memory and in
# your editor during `ansible-vault edit`. Never commit the decrypted form.
---
db_password: "{{ lookup('env', 'DB_PASSWORD') }}"
api_key: "{{ lookup('env', 'API_KEY') }}"
ssl_key: "{{ lookup('env', 'SSL_PRIVATE_KEY') }}"


# The same file at rest, after `ansible-vault encrypt`:
#   $ANSIBLE_VAULT;1.1;AES256
#   66386439653236336462626566653063336164663966303231363934653561363964363833313662
#   ...

# Use in playbook
---
- name: Deploy with secrets
  hosts: production
  vars_files:
    - secrets.yml
  tasks:
    - name: Configure database
      template:
        src: db.conf.j2
        dest: /etc/db.conf
      no_log: yes # Don't log sensitive data
# Run playbook with vault password
ansible-playbook playbook.yml --ask-vault-pass

# Use password file
ansible-playbook playbook.yml --vault-password-file ~/.vault_pass

# Use multiple vault IDs
ansible-playbook playbook.yml --vault-id prod@prompt --vault-id dev@~/.vault_dev

Testing

Molecule (Role Testing)

# Install molecule
pip install molecule molecule-docker

# Initialize molecule
cd roles/myapp
molecule init scenario

# Run tests
molecule test

# Test workflow
molecule create    # Create test instances
molecule converge  # Run playbook
molecule verify    # Run tests
molecule destroy   # Cleanup
# molecule/default/molecule.yml
---
dependency:
  name: galaxy
driver:
  name: docker
platforms:
  - name: ubuntu
    image: geerlingguy/docker-ubuntu2004-ansible
    pre_build_image: yes
provisioner:
  name: ansible
verifier:
  name: ansible

Anti-Patterns to Avoid

Not using roles: Organize code in reusable roles ❌ Shell commands everywhere: Use modules when available ❌ Hardcoded values: Use variables ❌ No error handling: Use blocks, rescue, always ❌ Storing secrets in plaintext: Use Ansible Vault ❌ Not testing: Use molecule for role testing ❌ Ignoring idempotency: Tasks should be safe to run multiple times ❌ Complex playbooks: Break into smaller, focused playbooks

Reference Documentation

Detailed material lives alongside this skill and is read on demand:

  • Best Practices — Playbook Organization, Idempotency, Performance, Security
  • Playbooks — Basic Playbook, Advanced Playbook, Conditionals and Loops
  • Roles — Role Structure, Example Role, Role Dependencies

Resources

Use it

Copy one of these into your project. Installing also returns the manifest and these snippets.

yaml
targets:
  - https://api.opensmartroute.ai/api/v1/registry/personamanagmentlayer-pcl-ansible-expert/manifest   # or paste the manifest below

Manifest

An Open Capability Manifest: the router reads it to know what this does, what it costs and when to pick it.

personamanagmentlayer-pcl-ansible-expert.ocm.jsonjson
{
  "ocm": "1",
  "id": "personamanagmentlayer-pcl-ansible-expert",
  "kind": "skill",
  "name": "ansible-expert",
  "description": "Expert-level Ansible for configuration management, automation, and infrastructure as code. Use when the user mentions automation, configuration management, infrastructure as code, playbooks, or roles, or when the task involves Ansible Architecture, Basic Inventory, YAML Inventory, or Dynamic Inventory.",
  "publisher": "personamanagmentlayer",
  "version": "1.0.0",
  "capabilities": {
    "domains": [
      "coding"
    ],
    "tags": [
      "skill-md",
      "ansible",
      "automation",
      "configuration-management",
      "iac",
      "playbooks",
      "roles",
      "skills-sh"
    ],
    "languages": [
      "en"
    ]
  },
  "quality_prior": 0.6,
  "examples": [
    "Expert-level Ansible for configuration management, automation, and infrastructure as code. Use when the user mentions automation, configuration management, infrastructure as code, playbooks, or roles, or when the task involves Ansible Architecture, Basic Inventory, YAML Inventory, or Dynamic Inventory."
  ],
  "primary": false,
  "metadata": {
    "source": {
      "provider": "skills.sh",
      "repository": "https://github.com/personamanagmentlayer/pcl",
      "path": "stdlib/devops/ansible-expert/SKILL.md",
      "ref": "HEAD",
      "url": "https://www.skills.sh/personamanagmentlayer/pcl/ansible-expert",
      "key": "personamanagmentlayer/pcl/stdlib/devops/ansible-expert/SKILL.md"
    },
    "allowed_tools": [
      "Read",
      "Write",
      "Edit",
      "Bash(ansible:*, ansible-playbook:*, ansible-galaxy:*)"
    ]
  },
  "instructions": "# Ansible Expert\n\nExpert guidance for Ansible - configuration management, application deployment, and IT automation using declarative YAML playbooks.\n\n## Core Concepts\n\n### Ansible Architecture\n\n- Control node (runs Ansible)\n- Managed nodes (target systems)\n- Inventory (hosts and groups)\n- Playbooks (YAML automation scripts)\n- Modules (units of work)\n- Roles (reusable automation units)\n- Plugins (extend functionality)\n\n### Key Features\n\n- Agentless (SSH-based)\n- Idempotent operations\n- Declarative syntax\n- Human-readable YAML\n- Extensible with modules\n- Push-based configuration\n- Parallel exec",
  "cost": {
    "context_tokens": 2418
  }
}

Fetch it by URL: GET /api/v1/registry/personamanagmentlayer-pcl-ansible-expert/manifest?version=1.0.0

Reviews

Star ratings from people who tried it. One review per account; edit yours any time.

No reviews yet. Install it, try it, and be the first to rate it.