name: ansible
description: "使用 Ansible 进行基础设施自动化。适用于服务器配置、配置管理、应用部署和多主机编排。包含用于 OpenClaw VPS 设置、安全加固和常见服务器配置的 Playbook。"
metadata: {"openclaw":{"requires":{"bins":["ansible","ansible-playbook"]},"install":[{"id":"ansible","kind":"pip","package":"ansible","bins":["ansible","ansible-playbook"],"label":"安装 Ansible (pip)"}]}}
用于服务器配置、配置管理和编排的基础设施即代码自动化工具。
# 安装 Ansible
pip install ansible
# 或在 macOS 上
brew install ansible
# 验证安装
ansible --version
# 测试连接
ansible all -i inventory/hosts.yml -m ping
# 运行 Playbook
ansible-playbook -i inventory/hosts.yml playbooks/site.yml
# 模拟运行(检查模式)
ansible-playbook -i inventory/hosts.yml playbooks/site.yml --check
# 使用特定标签
ansible-playbook -i inventory/hosts.yml playbooks/site.yml --tags "security,nodejs"
skills/ansible/
├── SKILL.md # 本文档
├── inventory/ # 主机清单
│ ├── hosts.yml # 主清单文件
│ └── group_vars/ # 组变量
├── playbooks/ # 可运行的 Playbook
│ ├── site.yml # 主 Playbook
│ ├── openclaw-vps.yml # OpenClaw VPS 设置
│ └── security.yml # 安全加固
├── roles/ # 可复用的角色
│ ├── common/ # 基础系统设置
│ ├── security/ # 安全加固(SSH, fail2ban, UFW)
│ ├── nodejs/ # Node.js 安装
│ └── openclaw/ # OpenClaw 安装
└── references/ # 参考文档
├── best-practices.md
├── modules-cheatsheet.md
└── troubleshooting.md
在 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/site.yml - 主 Playbook
---
- name: 配置所有服务器
hosts: all
become: yes
roles:
- common
- security
- name: 设置 OpenClaw 服务器
hosts: openclaw
become: yes
roles:
- nodejs
- openclaw
可复用、模块化的配置单元:
# roles/common/tasks/main.yml
---
- name: 更新 apt 缓存
ansible.builtin.apt:
update_cache: yes
cache_valid_time: 3600
when: ansible_os_family == "Debian"
- name: 安装基础软件包
ansible.builtin.apt:
name:
- curl
- wget
- git
- htop
- vim
- unzip
state: present
基础系统配置:
- 系统更新
- 基础软件包
- 时区配置
- 创建用户并添加 SSH 密钥
遵循 CIS 基准的安全加固:
- SSH 加固(仅密钥登录,禁止 root)
- 使用 fail2ban 防御暴力破解
- UFW 防火墙配置
- 自动安全更新
通过 NodeSource 安装 Node.js:
- 可配置版本(默认:22.x LTS)
- npm 全局包
- pm2 进程管理器(可选)
完整的 OpenClaw 设置:
- Node.js(通过 nodejs 角色)
- 通过 npm 安装 OpenClaw
- Systemd 服务配置
- 配置文件设置
# 1. 将主机添加到清单
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. 运行 OpenClaw Playbook
ansible-playbook -i inventory/hosts.yml playbooks/openclaw-vps.yml \
--limit newserver \
--ask-vault-pass
# 3. 初始设置后,更新清单以使用密钥认证
# 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"
# 一次更新一台服务器
ansible-playbook -i inventory/hosts.yml playbooks/update.yml \
--serial 1
# 检查所有服务器的磁盘空间
ansible all -i inventory/hosts.yml -m shell -a "df -h"
# 重启服务
ansible openclaw -i inventory/hosts.yml -m systemd -a "name=openclaw state=restarted"
# 复制文件
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: 22
# 安全设置
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"
# 创建加密的变量文件
ansible-vault create inventory/group_vars/all/vault.yml
# 编辑加密文件
ansible-vault edit inventory/group_vars/all/vault.yml
# 运行 Playbook 时提供 Vault 密码
ansible-playbook site.yml --ask-vault-pass
# 或使用 Vault 密码文件
ansible-playbook site.yml --vault-password-file ~/.vault_pass
Vault 文件结构示例:
# inventory/group_vars/all/vault.yml
---
vault_eva_password: "y8UGHR1qH"
vault_deploy_ssh_key: |
-----BEGIN OPENSSH PRIVATE KEY-----
...
-----END OPENSSH PRIVATE KEY-----
| 模块 | 用途 | 示例 |
|---|---|---|
apt |
包管理(Debian) | apt: name=nginx state=present |
yum |
包管理(RHEL) | yum: name=nginx state=present |
copy |
复制文件 | copy: src=file dest=/path/ |
template |
模板文件(Jinja2) | template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf |
file |
文件/目录管理 | file: path=/dir state=directory mode=0755 |
user |
用户管理 | user: name=asdbot groups=sudo shell=/bin/bash |
authorized_key |
SSH 密钥管理 | authorized_key: user=asdbot key="{{ ssh_key }}" |
systemd |
服务管理 | systemd: name=nginx state=started enabled=yes |
ufw |
防火墙(Ubuntu) | ufw: rule=allow port=22 proto=tcp |
lineinfile |
编辑单行 | lineinfile: path=/etc/ssh/sshd_config regexp='^PermitRootLogin' line='PermitRootLogin no' |
git |
克隆仓库 | git: repo=https://github.com/x/y.git dest=/opt/y |
npm |
npm 包管理 | npm: name=openclaw global=yes |
command |
运行命令 | command: /opt/script.sh |
shell |
运行 Shell 命令 | shell: cat /etc/passwd \| grep root |
# 好
- name: 安装 nginx 网页服务器
apt:
name: nginx
state: present
# 不好
- apt: name=nginx
# 好
- ansible.builtin.apt:
name: nginx
# 可以接受,但不够清晰
- apt:
name: nginx
# 好 - 状态明确
- ansible.builtin.apt:
name: nginx
state: present
# 不好 - 状态隐式
- ansible.builtin.apt:
name: nginx
编写可以安全运行多次的任务:
# 好 - 幂等
- name: 确保配置行存在
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
regexp: '^PasswordAuthentication'
line: 'PasswordAuthentication no'
# 不好 - 非幂等
- name: 添加配置行
ansible.builtin.shell: echo "PasswordAuthentication no" >> /etc/ssh/sshd_config
# tasks/main.yml
- name: 更新 SSH 配置
ansible.builtin.template:
src: sshd_config.j2
dest: /etc/ssh/sshd_config
notify: 重启 SSH 服务
# handlers/main.yml
- name: 重启 SSH 服务
ansible.builtin.systemd:
name: sshd
state: restarted
- name: 安全任务
ansible.builtin.include_tasks: security.yml
tags: [security, hardening]
- name: 应用部署
ansible.builtin.include_tasks: deploy.yml
tags: [deploy, app]
# 手动测试 SSH 连接
ssh -v user@host
# 调试 Ansible 连接
ansible host -i inventory -m ping -vvv
# 检查清单解析
ansible-inventory -i inventory --list
"Permission denied"
- 检查 SSH 密钥权限:chmod 600 ~/.ssh/id_*
- 确认用户有 sudo 权限
- 在 Playbook 中添加 become: yes
"Host key verification failed"
- 在 ansible.cfg 中添加:host_key_checking = False
- 或添加主机密钥:ssh-keyscan -H host >> ~/.ssh/known_hosts
"Module not found"
- 使用 FQCN:ansible.builtin.apt 而非 apt
- 安装集合:ansible-galaxy collection install community.general
# 详细输出
ansible-playbook site.yml -v # 基础
ansible-playbook site.yml -vv # 更多
ansible-playbook site.yml -vvv # 最详细
# 逐步执行任务
ansible-playbook site.yml --step
# 从特定任务开始
ansible-playbook site.yml --start-at-task="安装 nginx"
# 检查模式(模拟运行)
ansible-playbook site.yml --check --diff
# 通过 exec 工具运行 Playbook
exec command="ansible-playbook -i skills/ansible/inventory/hosts.yml skills/ansible/playbooks/openclaw-vps.yml --limit eva"
# 执行临时命令
exec command="ansible eva -i skills/ansible/inventory/hosts.yml -m shell -a 'systemctl status openclaw'"
使用 OpenClaw 的 Vaultwarden 集成:
# 从 vault 缓存获取密码
PASSWORD=$(.secrets/get-secret.sh "VPS - Eva")
# 在 ansible 中使用(不推荐 - 应使用 ansible-vault)
ansible-playbook site.yml -e "ansible_ssh_pass=$PASSWORD"
更好的做法:存储在 Ansible Vault 中并使用 --ask-vault-pass。
references/best-practices.md - 详细的最佳实践指南references/modules-cheatsheet.md - 常用模块速查表references/troubleshooting.md - 扩展的故障排除指南