警告:rm -rf
是一个高危命令,可能造成不可逆的数据丢失!
以下是关于如何在 Ansible 中安全使用 rm -rf
或类似操作的完整指南:
目录
一、为什么慎用 rm -rf
?
• 风险:递归强制删除文件/目录,无任何确认提示。
• 典型事故场景:
• 误删系统关键文件(如 /etc
、/var
)。
• 脚本路径错误导致批量删除重要数据。
二、Ansible 中安全替代方案
1. 使用 file
模块(推荐)
- name: Safely delete directory
ansible.builtin.file:
path: /path/to/delete
state: absent # 递归删除目录及内容
recurse: yes # 强制递归(等同于 rm -rf)
优势:
• 自动处理权限问题(需配合 become: yes
)。
• 清晰的任务声明,易于调试和维护。
2. 使用 shell
模块(需谨慎)
- name: Delete with rm -rf (仅限必要场景)
ansible.builtin.shell: "rm -rf /path/to/delete/*"
args:
chdir: /path/to/delete # 限制工作目录范围
become: yes # 提升权限
风险控制:
• 绝对路径:避免使用相对路径(如 ./
或 ../
)。
• 通配符限制:明确指定匹配模式(如 *.tmp
)。
• 工作目录约束:通过 chdir
限制删除范围。
三、安全增强策略
1. 删除前检查路径是否存在
- name: Check if directory exists
ansible.builtin.stat:
path: /path/to/delete
register: dir_stat
- name: Delete only if exists
ansible.builtin.file:
path: /path/to/delete
state: absent
when: dir_stat.stat.exists
2. 限制删除范围(通配符白名单)
- name: Delete specific files only
ansible.builtin.shell: |
cd /data && rm -rf *.log *.tmp
args:
chdir: /data # 严格限定当前目录
3. 日志记录与备份
- name: Backup before deletion
ansible.builtin.copy:
src: /path/to/delete
dest: /backup/{
{
inventory_hostname }}/ # 自动按主机备份
remote_src: yes # 源文件在远程主机上
- name: Delete after backup
ansible.builtin.file:
path: /path/to/delete
state: absent
四、完整 Playbook 示例
---
- name: Safe Cleanup Playbook
hosts: all
become: yes
vars:
critical_paths:
- /tmp/app_cache
- /var/log/old_logs
backup_dir: "/backup/{
{ inventory_hostname }}"
tasks:
- name: Backup directories
ansible.builtin.copy:
src: "{
{ item }}"
dest: "{
{ backup_dir }}/"
remote_src: yes
loop: "{
{ critical_paths }}"
- name: Delete cached files
ansible.builtin.file:
path: "{
{ item }}"
state: absent
loop: "{
{ critical_paths }}"
- name: Verify deletion
ansible.builtin.debug:
msg: "Deleted {
{ item }}"
loop: "{
{ critical_paths }}"
五、常见错误与修复
1. 权限不足
• 错误:Permission denied
• 解决:
- name: Fix permissions
ansible.builtin.file:
path: /protected/path
owner: root
group: root
mode: '0755'
2. 路径不存在
• 错误:No such file or directory
• 解决:添加条件判断:
• name: Conditional delete
ansible.builtin.file:
path: /optional/path
state: absent
when: lookup('file', '/optional/path')
---