Ansible
Infrastructure automation with Ansible. Use for server provisioning, configuration management, application deployment, and multi-host orchestration. Includes playbooks for OpenClaw VPS setup, security
Infrastructure automation with Ansible. Use for server provisioning, configuration management, application deployment, and multi-host orchestration. Includes playbooks for OpenClaw VPS setup, security
Real data. Real impact.
Emerging
Developers
Per week
Open source
Skills give you superpowers. Install in 30 seconds.
Infrastructure as Code automation for server provisioning, configuration management, and orchestration.
# Install Ansible pip install ansibleOr on macOS
brew install ansible
Verify
ansible --version
# Test connection ansible all -i inventory/hosts.yml -m pingRun 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"
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.md
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_planeopenclaw: hosts: eva:
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
openclaw
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: present
Base system configuration:
Hardening following CIS benchmarks:
Node.js installation via NodeSource:
Complete OpenClaw setup:
# 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" EOF2. Run OpenClaw playbook
ansible-playbook -i inventory/hosts.yml playbooks/openclaw-vps.yml
--limit newserver
--ask-vault-pass3. After initial setup, update inventory to use key auth
ansible_user: asdbot
ansible_ssh_private_key_file: ~/.ssh/id_ed25519
ansible-playbook -i inventory/hosts.yml playbooks/security.yml \ --limit production \ --tags "ssh,firewall"
# Update one server at a time ansible-playbook -i inventory/hosts.yml playbooks/update.yml \ --serial 1
# 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/"
# inventory/group_vars/all.yml --- timezone: Europe/Budapest deploy_user: asdbot ssh_port: 22Security
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"
# Create encrypted vars file ansible-vault create inventory/group_vars/all/vault.ymlEdit 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_pass
Vault file structure:
# inventory/group_vars/all/vault.yml --- vault_eva_password: "y8UGHR1qH" vault_deploy_ssh_key: | -----BEGIN OPENSSH PRIVATE KEY----- ... -----END OPENSSH PRIVATE KEY-----
| Module | Purpose | Example |
|---|---|---|
| Package management (Debian) | |
| Package management (RHEL) | |
| Copy files | |
| Template files (Jinja2) | |
| File/directory management | |
| User management | |
| SSH keys | |
| Service management | |
| Firewall (Ubuntu) | |
| Edit single line | |
| Clone repos | |
| npm packages | |
| Run command | |
| Run shell command | |
# Good - name: Install nginx web server apt: name: nginx state: presentBad
apt: name=nginx
# Good - ansible.builtin.apt: name: nginxAcceptable but less clear
apt:
name: nginx
# Good - explicit state - ansible.builtin.apt: name: nginx state: presentBad - implicit state
ansible.builtin.apt:
name: nginx
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_config
# tasks/main.yml - name: Update SSH config ansible.builtin.template: src: sshd_config.j2 dest: /etc/ssh/sshd_config notify: Restart SSHhandlers/main.yml
name: Restart SSH
ansible.builtin.systemd:
name: sshd
state: restarted
- name: Security tasks ansible.builtin.include_tasks: security.yml tags: [security, hardening]
name: App deployment
ansible.builtin.include_tasks: deploy.yml
tags: [deploy, app]
# Test SSH connection manually ssh -v user@hostDebug Ansible connection
ansible host -i inventory -m ping -vvv
Check inventory parsing
ansible-inventory -i inventory --list
"Permission denied"
chmod 600 ~/.ssh/id_*become: yes to playbook"Host key verification failed"
host_key_checking = Falsessh-keyscan -H host >> ~/.ssh/known_hosts"Module not found"
ansible.builtin.apt instead of aptansible-galaxy collection install community.general# Verbose output ansible-playbook site.yml -v # Basic ansible-playbook site.yml -vv # More ansible-playbook site.yml -vvv # MaximumStep 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 --diff
# 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'"
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/best-practices.md - Detailed best practices guidereferences/modules-cheatsheet.md - Common modules quick referencereferences/troubleshooting.md - Extended troubleshooting guideNo automatic installation available. Please visit the source repository for installation instructions.
View Installation Instructions1,500+ AI skills, agents & workflows. Install in 30 seconds. Part of the Torly.ai family.
© 2026 Torly.ai. All rights reserved.