Ansible Skill
name: ansible
by botond-rackhost · published 2026-03-22
$ claw add gh:botond-rackhost/botond-rackhost-ansible-skill---
name: ansible
description: "Infrastructure automation with Ansible. Use for server provisioning, configuration management, application deployment, and multi-host orchestration. Includes playbooks for OpenClaw VPS setup, security hardening, and common server configurations."
metadata: {"openclaw":{"requires":{"bins":["ansible","ansible-playbook"]},"install":[{"id":"ansible","kind":"pip","package":"ansible","bins":["ansible","ansible-playbook"],"label":"Install Ansible (pip)"}]}}
---
# Ansible Skill
Infrastructure as Code automation for server provisioning, configuration management, and orchestration.
Quick Start
Prerequisites
# Install Ansible
pip install ansible
# Or on macOS
brew install ansible
# Verify
ansible --versionRun Your First Playbook
# Test connection
ansible all -i inventory/hosts.yml -m ping
# Run playbook
ansible-playbook -i inventory/hosts.yml playbooks/site.yml
# Dry run (check mode)
ansible-playbook -i inventory/hosts.yml playbooks/site.yml --check
# With specific tags
ansible-playbook -i inventory/hosts.yml playbooks/site.yml --tags "security,nodejs"Directory Structure
skills/ansible/
├── SKILL.md # This file
├── inventory/ # Host inventories
│ ├── hosts.yml # Main inventory
│ └── group_vars/ # Group variables
├── playbooks/ # Runnable playbooks
│ ├── site.yml # Master playbook
│ ├── openclaw-vps.yml # OpenClaw VPS setup
│ └── security.yml # Security hardening
├── roles/ # Reusable roles
│ ├── common/ # Base system setup
│ ├── security/ # Hardening (SSH, fail2ban, UFW)
│ ├── nodejs/ # Node.js installation
│ └── openclaw/ # OpenClaw installation
└── references/ # Documentation
├── best-practices.md
├── modules-cheatsheet.md
└── troubleshooting.mdCore Concepts
Inventory
Define your hosts in `inventory/hosts.yml`:
all:
children:
vps:
hosts:
eva:
ansible_host: 217.13.104.208
ansible_user: root
ansible_ssh_pass: "{{ vault_eva_password }}"
plane:
ansible_host: 217.13.104.99
ansible_user: asdbot
ansible_ssh_private_key_file: ~/.ssh/id_ed25519_plane
openclaw:
hosts:
eva:Playbooks
Entry points for automation:
# playbooks/site.yml - Master playbook
---
- name: Configure all servers
hosts: all
become: yes
roles:
- common
- security
- name: Setup OpenClaw servers
hosts: openclaw
become: yes
roles:
- nodejs
- openclawRoles
Reusable, modular configurations:
# roles/common/tasks/main.yml
---
- name: Update apt cache
ansible.builtin.apt:
update_cache: yes
cache_valid_time: 3600
when: ansible_os_family == "Debian"
- name: Install essential packages
ansible.builtin.apt:
name:
- curl
- wget
- git
- htop
- vim
- unzip
state: presentIncluded Roles
1. common
Base system configuration:
2. security
Hardening following CIS benchmarks:
3. nodejs
Node.js installation via NodeSource:
4. openclaw
Complete OpenClaw setup:
Usage Patterns
Pattern 1: New VPS Setup (OpenClaw)
# 1. Add host to inventory
cat >> inventory/hosts.yml << 'EOF'
newserver:
ansible_host: 1.2.3.4
ansible_user: root
ansible_ssh_pass: "initial_password"
deploy_user: asdbot
deploy_ssh_pubkey: "ssh-ed25519 AAAA... asdbot"
EOF
# 2. Run OpenClaw playbook
ansible-playbook -i inventory/hosts.yml playbooks/openclaw-vps.yml \
--limit newserver \
--ask-vault-pass
# 3. After initial setup, update inventory to use key auth
# ansible_user: asdbot
# ansible_ssh_private_key_file: ~/.ssh/id_ed25519Pattern 2: Security Hardening Only
ansible-playbook -i inventory/hosts.yml playbooks/security.yml \
--limit production \
--tags "ssh,firewall"Pattern 3: Rolling Updates
# Update one server at a time
ansible-playbook -i inventory/hosts.yml playbooks/update.yml \
--serial 1Pattern 4: Ad-hoc Commands
# Check disk space on all servers
ansible all -i inventory/hosts.yml -m shell -a "df -h"
# Restart service
ansible openclaw -i inventory/hosts.yml -m systemd -a "name=openclaw state=restarted"
# Copy file
ansible all -i inventory/hosts.yml -m copy -a "src=./file.txt dest=/tmp/"Variables & Secrets
Group Variables
# inventory/group_vars/all.yml
---
timezone: Europe/Budapest
deploy_user: asdbot
ssh_port: 22
# Security
security_ssh_password_auth: false
security_ssh_permit_root: false
security_fail2ban_enabled: true
security_ufw_enabled: true
security_ufw_allowed_ports:
- 22
- 80
- 443
# Node.js
nodejs_version: "22.x"Vault for Secrets
# Create encrypted vars file
ansible-vault create inventory/group_vars/all/vault.yml
# Edit encrypted file
ansible-vault edit inventory/group_vars/all/vault.yml
# Run with vault
ansible-playbook site.yml --ask-vault-pass
# Or use vault password file
ansible-playbook site.yml --vault-password-file ~/.vault_passVault file structure:
# inventory/group_vars/all/vault.yml
---
vault_eva_password: "y8UGHR1qH"
vault_deploy_ssh_key: |
-----BEGIN OPENSSH PRIVATE KEY-----
...
-----END OPENSSH PRIVATE KEY-----Common Modules
| Module | Purpose | Example |
|--------|---------|---------|
| `apt` | Package management (Debian) | `apt: name=nginx state=present` |
| `yum` | Package management (RHEL) | `yum: name=nginx state=present` |
| `copy` | Copy files | `copy: src=file dest=/path/` |
| `template` | Template files (Jinja2) | `template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf` |
| `file` | File/directory management | `file: path=/dir state=directory mode=0755` |
| `user` | User management | `user: name=asdbot groups=sudo shell=/bin/bash` |
| `authorized_key` | SSH keys | `authorized_key: user=asdbot key="{{ ssh_key }}"` |
| `systemd` | Service management | `systemd: name=nginx state=started enabled=yes` |
| `ufw` | Firewall (Ubuntu) | `ufw: rule=allow port=22 proto=tcp` |
| `lineinfile` | Edit single line | `lineinfile: path=/etc/ssh/sshd_config regexp='^PermitRootLogin' line='PermitRootLogin no'` |
| `git` | Clone repos | `git: repo=https://github.com/x/y.git dest=/opt/y` |
| `npm` | npm packages | `npm: name=openclaw global=yes` |
| `command` | Run command | `command: /opt/script.sh` |
| `shell` | Run shell command | `shell: cat /etc/passwd \| grep root` |
Best Practices
1. Always Name Tasks
# Good
- name: Install nginx web server
apt:
name: nginx
state: present
# Bad
- apt: name=nginx2. Use FQCN (Fully Qualified Collection Names)
# Good
- ansible.builtin.apt:
name: nginx
# Acceptable but less clear
- apt:
name: nginx3. Explicit State
# Good - explicit state
- ansible.builtin.apt:
name: nginx
state: present
# Bad - implicit state
- ansible.builtin.apt:
name: nginx4. Idempotency
Write tasks that can run multiple times safely:
# Good - idempotent
- name: Ensure config line exists
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
regexp: '^PasswordAuthentication'
line: 'PasswordAuthentication no'
# Bad - not idempotent
- name: Add config line
ansible.builtin.shell: echo "PasswordAuthentication no" >> /etc/ssh/sshd_config5. Use Handlers for Restarts
# tasks/main.yml
- name: Update SSH config
ansible.builtin.template:
src: sshd_config.j2
dest: /etc/ssh/sshd_config
notify: Restart SSH
# handlers/main.yml
- name: Restart SSH
ansible.builtin.systemd:
name: sshd
state: restarted6. Tags for Selective Runs
- name: Security tasks
ansible.builtin.include_tasks: security.yml
tags: [security, hardening]
- name: App deployment
ansible.builtin.include_tasks: deploy.yml
tags: [deploy, app]Troubleshooting
Connection Issues
# Test SSH connection manually
ssh -v user@host
# Debug Ansible connection
ansible host -i inventory -m ping -vvv
# Check inventory parsing
ansible-inventory -i inventory --listCommon Errors
**"Permission denied"**
**"Host key verification failed"**
**"Module not found"**
Debugging Playbooks
# Verbose output
ansible-playbook site.yml -v # Basic
ansible-playbook site.yml -vv # More
ansible-playbook site.yml -vvv # Maximum
# Step through tasks
ansible-playbook site.yml --step
# Start at specific task
ansible-playbook site.yml --start-at-task="Install nginx"
# Check mode (dry run)
ansible-playbook site.yml --check --diffIntegration with OpenClaw
From OpenClaw Agent
# Run playbook via exec tool
exec command="ansible-playbook -i skills/ansible/inventory/hosts.yml skills/ansible/playbooks/openclaw-vps.yml --limit eva"
# Ad-hoc command
exec command="ansible eva -i skills/ansible/inventory/hosts.yml -m shell -a 'systemctl status openclaw'"Storing Credentials
Use OpenClaw's Vaultwarden integration:
# Get password from vault cache
PASSWORD=$(.secrets/get-secret.sh "VPS - Eva")
# Use in ansible (not recommended - use ansible-vault instead)
ansible-playbook site.yml -e "ansible_ssh_pass=$PASSWORD"Better: Store in Ansible Vault and use `--ask-vault-pass`.
References
External Resources
More tools from the same signal band
Order food/drinks (点餐) on an Android device paired as an OpenClaw node. Uses in-app menu and cart; add goods, view cart, submit order (demo, no real payment).
Sign plugins, rotate agent credentials without losing identity, and publicly attest to plugin behavior with verifiable claims and authenticated transfers.
The philosophical layer for AI agents. Maps behavior to Spinoza's 48 affects, calculates persistence scores, and generates geometric self-reports. Give your...