跳转至

Ansible模块2

一. copy模块

1. 功能

copy模块的功能是实现主控端向目标主机拷贝文件或目录,类似scp功能

2. copy模块的常用选项

backup: 在覆盖之前将原文件备份,备份文件包含时间信息。有两个选项:yes|no

content: 用于替代"src",可以直接设定文件的值

dest: 必须项。要将源文件复制到的远程主机的绝对路径。如果源文件是一个目录,那么路径也必须是一个目录

directory_mode: 递归的设定目标的权限,默认为系统默认权限

force: 如果目标主机包含该文件但内容不同,设置为yes则强制覆盖;为no则只有当目标主机的目标位置不存在该文件时才复制。默认为yes

src: 要复制到远程主机的文件在本地的地址,可以是绝对路径也可以是相对路径。如果路径是一个目录它将递归复制。在这种情况下如果路径使用"/"结尾则只复制目录内的内容,如果没有使用"/"结尾则包含目录在内的整个内容全部复制,类似于rsync

3. copy模块的应用案例

案例1

使用src把ansible主机上的/etc/hosts文件复制到主机组中机器的/tmp目录下

[root@1 ~]# ansible -m copy -a 'src=/etc/hosts dest=/tmp/ owner=root group=root mode=640 backup=yes' web_servers*
2 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": true,
    "checksum": "7335999eb54c15c67566186bdfc46f64e0d5a1aa",
    "dest": "/tmp/hosts",
    "gid": 0,
    "group": "root",
    "md5sum": "54fb6627dbaa37721048e4549db3224d",
    "mode": "0640",
    "owner": "root",
    "secontext": "unconfined_u:object_r:admin_home_t:s0",
    "size": 158,
    "src": "/root/.ansible/tmp/ansible-tmp-1786619098.3949304-5661-186575913094456/source",
    "state": "file",
    "uid": 0
}
3 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": true,
    "checksum": "7335999eb54c15c67566186bdfc46f64e0d5a1aa",
    "dest": "/tmp/hosts",
    "gid": 0,
    "group": "root",
    "md5sum": "54fb6627dbaa37721048e4549db3224d",
    "mode": "0640",
    "owner": "root",
    "secontext": "unconfined_u:object_r:admin_home_t:s0",
    "size": 158,
    "src": "/root/.ansible/tmp/ansible-tmp-1786619098.5193756-5662-227957182486214/source",
    "state": "file",
    "uid": 0
}

说明:

#src: 主控端文件位置

#dest: 被控端目标位置

#owner: 文件复制过去后的所有者

#group: 文件复制过去后的所属组

#mode: 文件的权限设定

#backup=yes: 如果目标位置存在同名文件,则在覆盖之前将源文件备份

查看目标主机是否复制成功

[root@1 ~]# ansible -m shell -a 'ls -l /tmp/hosts' web_servers*
3 | CHANGED | rc=0 >>
-rw-r-----. 1 root root 158  8月 13 19:04 /tmp/hosts
2 | CHANGED | rc=0 >>
-rw-r-----. 1 root root 158  8月 13 19:04 /tmp/hosts
案例2

使用content

# 复制
[root@1 ~]# ansible -m copy -a 'content="Hello ansible\nyou are clever!\n" dest=/tmp/ansible.txt' web_servers2
3 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": true,
    "checksum": "09c5fccf782fcdb0cfce2f1e009df8c56975b550",
    "dest": "/tmp/ansible.txt",
    "gid": 0,
    "group": "root",
    "md5sum": "cebd32f6ad7c7bff107a3d213ab38ec8",
    "mode": "0644",
    "owner": "root",
    "secontext": "unconfined_u:object_r:admin_home_t:s0",
    "size": 30,
    "src": "/root/.ansible/tmp/ansible-tmp-1786619568.4948137-5807-280842491652859/source",
    "state": "file",
    "uid": 0
}
# 查看验证
[root@1 ~]# ansible -m shell -a 'cat /tmp/ansible.txt' web_servers2
3 | CHANGED | rc=0 >>
Hello ansible
you are clever!

二. fetch模块

1. 简介

该模块与copy正好相反,从远程主机拉去文件到本地目录

2. 常见参数

dest: 设定目标文件的地址(强制选项)

flat: 允许拼接创建文件名

src: 设置源文件的地址(强制选项)

注意:

源文件与目标文件的格式最好保持一致

src为当前的版本,只允许抓群远程的单个文件

dest 支持的只能是本机的目录。抓取后的格式: "/dest/" + "目标主机/path/to/src"

3. 命令格式

fetch模块在ansible使用时,标准的写法为

ansible <目标主机> -m fetch -a '属性1=值1 属性2=值2 ... 属性n=值n'

4. 实践

1) 单文件拉取

# 先删除/tmp/的所有文件
[root@1 ~]# rm -rf /tmp/*
# 从2上拉取文件
[root@1 ~]# ansible -m fetch -a 'src=/tmp/hosts  dest=/tmp/' web_servers1
2 | CHANGED => {
    "changed": true,
    "checksum": "7335999eb54c15c67566186bdfc46f64e0d5a1aa",
    "dest": "/tmp/2/tmp/hosts",
    "md5sum": "54fb6627dbaa37721048e4549db3224d",
    "remote_checksum": "7335999eb54c15c67566186bdfc46f64e0d5a1aa",
    "remote_md5sum": null
}
# 检查效果
[root@1 ~]# tree /tmp/
/tmp/
└── 2
    └── tmp
        └── hosts

2 directories, 1 file

2) 多文件拉取

fetch默认情况下只能拉取单文件,并且不支持通配符

[root@1 ~]# ansible -m fetch -a 'src=/var/log/*.log dest=/tmp/' web_servers1
2 | FAILED! => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "msg": "the remote file does not exist, not transferring, ignored"
}

因为fetch属性原因,报错了。我们最好使用压缩包方式来实现多文件传输

# 先归档压缩
[root@1 ~]# ansible -m shell -a "tar cfz /tmp/log.tgz /var/log/*.log" web_servers1
2 | CHANGED | rc=0 >>
tar: 从成员名中删除开头的“/”
tar: 从硬连接目标中删除开头的“/”
# 再复制拉取到本地
[root@1 ~]# ansible -m fetch -a "src=/tmp/log.tgz dest=/tmp/" web_servers1
2 | CHANGED => {
    "changed": true,
    "checksum": "d3460cc635b6ef2374086814e706d00210208895",
    "dest": "/tmp/2/tmp/log.tgz",
    "md5sum": "58b271507ccfb4a06e5faeb9af91513c",
    "remote_checksum": "d3460cc635b6ef2374086814e706d00210208895",
    "remote_md5sum": null
}
# 查看验证
[root@1 ~]# tree /tmp/
/tmp/
└── 2
    └── tmp
        ├── hosts
        └── log.tgz

2 directories, 2 files
[root@1 ~]# tar tvf /tmp/2/tmp/log.tgz
-rw-r--r-- root/root     59604 2026-08-15 17:19 var/log/dnf.librepo.log
-rw-r--r-- root/root    206497 2026-08-15 17:19 var/log/dnf.log
-rw-r--r-- root/root     30634 2026-08-15 17:17 var/log/dnf.rpm.log
-rw-r--r-- root/root      1380 2026-08-15 17:17 var/log/hawkey.log
-rw------- root/root       217 2026-08-15 09:34 var/log/vmware-network.1.log
-rw------- root/root       217 2026-08-14 18:38 var/log/vmware-network.2.log
-rw------- root/root       217 2026-08-14 10:16 var/log/vmware-network.3.log
-rw------- root/root       217 2026-08-14 08:41 var/log/vmware-network.4.log
-rw------- root/root       217 2026-08-13 20:40 var/log/vmware-network.5.log
-rw------- root/root       217 2026-08-13 08:25 var/log/vmware-network.6.log
-rw------- root/root       217 2026-08-12 21:25 var/log/vmware-network.7.log
-rw------- root/root       217 2026-08-12 16:39 var/log/vmware-network.8.log
-rw------- root/root       217 2026-08-02 12:09 var/log/vmware-network.9.log
-rw------- root/root       217 2026-08-15 16:47 var/log/vmware-network.log
-rw------- root/root     51990 2026-08-15 16:47 var/log/vmware-vmsvc-root.log
-rw------- root/root      6875 2026-08-15 16:47 var/log/vmware-vmtoolsd-root.log

三. file模块

1. file模块一些概念

file模块主要是用于对远程主机上文件进行操作,如修改文件属性(权限、属主、属组)和创建文件、目录、符号链接等

2. 常见参数

force: 需要在两种情况下强制创建软连接,一种是源文件不存在但是之后会建立的情况下;另一种是目标软链接已经存在,需要先取消之前的软链接然后创建新的软链接。有两个选项: yes|no

group: 定义文件/目录的属组

mode: 定义文件/目录的属性

owner: 定义文件/目录的属主

path: 必选项,定义文件/目录的路径

recurse: 递归的设置文件属性,只对目录有效

src: 要被链接的源文件路径,只应用于state=link的情况

dest: 被连接到的路径,只应用于state=link的情况

state:

  • directory: 如果目录不存在则创建目录

  • file: 不是用于创建文件,而是检查文件是否存在。主要用于检查文件是否存在的应用场景

  • link: 创建软链接

  • hard: 创建硬链接

  • touch: 如果文件不存在则会创建一个新文件。如果文件或目录已存在,则更新其最后的修改时间

  • absent: 删除目录、文件或者取消链接文件

3. file模块应用案例

1) 修改权限

修改2,3两台主机上/tmp/hosts文件权限为777

[root@1 ~]# ansible -m file -a 'path=/tmp/hosts mode=777' web_servers*
2 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": true,
    "gid": 0,
    "group": "root",
    "mode": "0777",
    "owner": "root",
    "path": "/tmp/hosts",
    "secontext": "unconfined_u:object_r:admin_home_t:s0",
    "size": 158,
    "state": "file",
    "uid": 0
}
3 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": true,
    "gid": 0,
    "group": "root",
    "mode": "0777",
    "owner": "root",
    "path": "/tmp/hosts",
    "secontext": "unconfined_u:object_r:admin_home_t:s0",
    "size": 158,
    "state": "file",
    "uid": 0
}

查看文件权限

[root@1 ~]# ansible -a 'ls -l /tmp/hosts' web_servers*
3 | CHANGED | rc=0 >>
-rwxrwxrwx. 1 root root 158  8月 13 19:04 /tmp/hosts
2 | CHANGED | rc=0 >>
-rwxrwxrwx. 1 root root 158  8月 13 19:04 /tmp/hosts

2) 创建符号链接

将2,3上的/tmp/hosts文件创建符号链接到/opt目录下

[root@1 ~]# ansible -m file -a "src=/tmp/hosts dest=/opt/hosts state=link" web_servers*
2 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": true,
    "dest": "/opt/hosts",
    "gid": 0,
    "group": "root",
    "mode": "0777",
    "owner": "root",
    "secontext": "unconfined_u:object_r:usr_t:s0",
    "size": 10,
    "src": "/tmp/hosts",
    "state": "link",
    "uid": 0
}
3 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": true,
    "dest": "/opt/hosts",
    "gid": 0,
    "group": "root",
    "mode": "0777",
    "owner": "root",
    "secontext": "unconfined_u:object_r:usr_t:s0",
    "size": 10,
    "src": "/tmp/hosts",
    "state": "link",
    "uid": 0
}

查看验证

[root@1 ~]# ansible -i /etc/ansible/hosts -a 'ls -l /opt/hosts' web_servers*
2 | CHANGED | rc=0 >>
lrwxrwxrwx. 1 root root 10  8月 13 19:55 /opt/hosts -> /tmp/hosts
3 | CHANGED | rc=0 >>
lrwxrwxrwx. 1 root root 10  8月 13 19:55 /opt/hosts -> /tmp/hosts

3) 删除链接文件

[root@1 ~]# ansible -m file -a "path=/opt/hosts state=absent" web_servers*
2 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": true,
    "path": "/opt/hosts",
    "state": "absent"
}
3 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": true,
    "path": "/opt/hosts",
    "state": "absent"
}

查看验证

[root@1 ~]# ansible -m file -a "path=/opt/hosts state=file" web_servers*
3 | FAILED! => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "msg": "file (/opt/hosts) is absent, cannot continue",
    "path": "/opt/hosts",
    "state": "absent"
}
2 | FAILED! => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "msg": "file (/opt/hosts) is absent, cannot continue",
    "path": "/opt/hosts",
    "state": "absent"
}

此时报错,因为该文件删掉了

4) 创建文件或目录

创建目录,如果它不存在

[root@1 ~]# ansible -m file -a "path=/tmp/dir1 state=directory" web_servers*
3 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": true,
    "gid": 0,
    "group": "root",
    "mode": "0755",
    "owner": "root",
    "path": "/tmp/dir1",
    "secontext": "unconfined_u:object_r:user_tmp_t:s0",
    "size": 6,
    "state": "directory",
    "uid": 0
}
2 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": true,
    "gid": 0,
    "group": "root",
    "mode": "0755",
    "owner": "root",
    "path": "/tmp/dir1",
    "secontext": "unconfined_u:object_r:user_tmp_t:s0",
    "size": 6,
    "state": "directory",
    "uid": 0
}

touch创建空文件

[root@1 ~]# ansible -m file -a "path=/tmp/testfile1 state=touch" web_servers*
3 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": true,
    "dest": "/tmp/testfile1",
    "gid": 0,
    "group": "root",
    "mode": "0644",
    "owner": "root",
    "secontext": "unconfined_u:object_r:user_tmp_t:s0",
    "size": 0,
    "state": "file",
    "uid": 0
}
2 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": true,
    "dest": "/tmp/testfile1",
    "gid": 0,
    "group": "root",
    "mode": "0644",
    "owner": "root",
    "secontext": "unconfined_u:object_r:user_tmp_t:s0",
    "size": 0,
    "state": "file",
    "uid": 0
}

查看验证

[root@1 ~]# ansible -m shell -a "ls /tmp/*1" web_servers*
3 | CHANGED | rc=0 >>
/tmp/testfile1

/tmp/dir1:
2 | CHANGED | rc=0 >>
/tmp/testfile1

/tmp/dir1:

四. stat 模块

1. 简介

stat模块的主要作用场景时查看文件状态

2. 常见参数

path: 获取文件路径,强制选项

3. 命令格式

stat模块在ansible使用时,标准写法为

ansible <目标主机> -m stat -a 'path=文件路径 属性1=值1 ... 属性n=值n'

4. 实践

查看不存在文件的效果

[root@1 ~]# ansible -m stat -a "path=/tmp/1111111" web_servers1
2 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "stat": {
        "exists": false
    }
}

查看指定存在文件的效果

[root@1 ~]# ansible -m stat -a "path=/tmp/hosts" web_servers1
2 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "stat": {
...

五. ping模块

ping模块用于测试连接可通性,没有参数,通的话返回pong

[root@1 ~]# ansible -m ping web_servers*
2 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
3 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}

六. yum模块

1. 作用

yum模块可以帮助我们在远程主机上通过yum源管理软件包

2. yum / dnf / package 模块的关系(先看这里)

模块 适用系统 说明
yum 模块 RHEL/CentOS 7(Python2) 老系统才用
dnf 模块 RHEL/Rocky 8/9(Python3) Rocky9 推荐用它
package 模块 通用(自动识别 yum/dnf/apt) 日常操作最省心
  • yum 和 dnf 模块参数几乎一样(name/state/update_cache),主要差异在平台适配:yum 基于 python2,Rocky9 没有 python2 可能报错,所以用 dnf 模块
  • package 是通用"上位"模块,能覆盖大部分日常操作(安装/卸载/升级/查询),但不能完全替代 dnf/yum 的专属参数(如 enablerepo、disablerepo、exclude、installroot 等)
  • 结论:Rocky9 上日常用 package 最省心;要精细控制仓库/排除时用 dnf 模块

常用参数

name参数: 必须参数,用于指定需要管理的软件包,比如nginx

state参数: 用于指定软件包的状态,默认值为present。标识确保软件包已经安装,除了present其他可用的值有installed,latest,absent,remove。其中installed与present等效,latest表示安装yum的最新版本,absent和remove等效,表示删除对应的软件包

disable_gpg_check参数: 用于禁用对rpm包公钥gpg验证。默认值为no表示不禁用验证;设置为yes表示禁用验证。即不验证包直接安装

update_cache参数: 是否更新缓存,默认值为no

enablerepo参数: 用于指定安装软件包时临时启用的yum源。假如你想要从A源中安装软件,但是你不确定A源是否启用了,你可以按照软件包时将此参数的值设置为仓库ID。这样即使A源的设置是未启用,也可以在安装软件包时临时启用A源。

disablerepo参数: 用于指定安装软件包时临时禁用的yum源。某些场景下需要此参数。比如当多个yum源中同时存在要安装的软件包时,你可以使用此参数临时禁用某个值。这样设置后在安装软件包时则不会从对应的源中选择安装包

enablerepo参数和disablerepo参数可以同时使用

3. yum模块的应用案例

2和3两台主机安装httpd服务

[root@1 ~]# ansible -m dnf -a "name=httpd state=latest" web_servers*
2 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": true,
    "msg": "",
    "rc": 0,
    "results": [
        "Installed: mod_http2-2.0.26-6.el9_8.1.x86_64",
        "Installed: mailcap-2.1.49-5.el9.0.2.noarch",
        "Installed: apr-1.7.0-12.el9_3.x86_64",
        "Installed: httpd-2.4.62-13.el9_8.5.x86_64",
        "Installed: httpd-core-2.4.62-13.el9_8.5.x86_64",
        "Installed: apr-util-1.6.1-23.el9.x86_64",
        "Installed: mod_lua-2.4.62-13.el9_8.5.x86_64",
        "Installed: apr-util-bdb-1.6.1-23.el9.x86_64",
        "Installed: rocky-logos-httpd-90.17-1.el9.noarch",
        "Installed: httpd-filesystem-2.4.62-13.el9_8.5.noarch",
        "Installed: apr-util-openssl-1.6.1-23.el9.x86_64",
        "Installed: httpd-tools-2.4.62-13.el9_8.5.x86_64"
    ]
}
3 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": true,
    "msg": "",
    "rc": 0,
    "results": [
        "Installed: mod_http2-2.0.26-6.el9_8.1.x86_64",
        "Installed: mailcap-2.1.49-5.el9.0.2.noarch",
        "Installed: apr-1.7.0-12.el9_3.x86_64",
        "Installed: httpd-2.4.62-13.el9_8.5.x86_64",
        "Installed: httpd-core-2.4.62-13.el9_8.5.x86_64",
        "Installed: apr-util-1.6.1-23.el9.x86_64",
        "Installed: mod_lua-2.4.62-13.el9_8.5.x86_64",
        "Installed: apr-util-bdb-1.6.1-23.el9.x86_64",
        "Installed: rocky-logos-httpd-90.17-1.el9.noarch",
        "Installed: httpd-filesystem-2.4.62-13.el9_8.5.noarch",
        "Installed: apr-util-openssl-1.6.1-23.el9.x86_64",
        "Installed: httpd-tools-2.4.62-13.el9_8.5.x86_64"
    ]
}

验证

[root@1 ~]# ansible -m shell -a ' rpm -q httpd' web_servers*
2 | CHANGED | rc=0 >>
httpd-2.4.62-13.el9_8.5.x86_64
3 | CHANGED | rc=0 >>
httpd-2.4.62-13.el9_8.5.x86_64

七. get_url模块

1. 简介

用于将文件从http、https或ftp下载到被管理主机上

2. 常见参数

url: 下载文件的URL,支持HTTP,HTTPS和FTP协议

dest: 下载到目标路径(绝对路径)

force: 如果是yes且dest不是目录,则将每次都下载文件。如果是no,则只有当文件不存在时才会下载。

checksum: 对目标文件在下载前进行摘要计算。指定文件校验值(格式: sha256:xxx 或 md5:xxx)。本地已有文件校验不过时才重新下载,比force=yes每次都盲目重下更高效

timeout: 下载超时时间(秒),默认10秒

3. 实践

下载httpd文件

[root@1 ~]# ansible -m get_url -a 'url=https://dlcdn.apache.org/httpd/httpd-2.4.68.tar.bz2 dest=/tmp/ force=no checksum=sha256:68c74d4df38c26bed4dfbdb8f3baf1eb532f3872357becc1bba5d136f6b63c06' web_servers2
3 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": true,
    "checksum_dest": null,
    "checksum_src": "2402a2e364f103389265587a9b599c16202f6771",
    "dest": "/tmp/httpd-2.4.68.tar.bz2",
    "elapsed": 65,
    "gid": 0,
    "group": "root",
    "md5sum": "f2f3121e9f1fb4838d433dbd494543f9",
    "mode": "0644",
    "msg": "OK (7738512 bytes)",
    "owner": "root",
    "size": 7738512,
    "src": "/root/.ansible/tmp/ansible-tmp-1786794001.2085521-1738-206966130583892/tmp4gxxiogn",
    "state": "file",
    "status_code": 200,
    "uid": 0,
    "url": "https://dlcdn.apache.org/httpd/httpd-2.4.68.tar.bz2"
}

查看效果

[root@1 ~]# ansible -m shell -a 'ls -l /tmp/httpd-2.4.68.tar.bz2' web_servers2
3 | CHANGED | rc=0 >>
-rw-r--r-- 1 root root 7738512  8月 15 19:41 /tmp/httpd-2.4.68.tar.bz2

我们修改校验值第一位,使其不匹配,再次尝试

[root@1 ~]# ansible -m get_url -a 'url=https://dlcdn.apache.org/httpd/httpd-2.4.68.tar.bz2 dest=/tmp/ force=no checksum=sha256:88c74d4df38c26bed4dfbdb
8f3baf1eb532f3872357becc1bba5d136f6b63c06' web_servers2
3 | FAILED! => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "checksum_dest": "2402a2e364f103389265587a9b599c16202f6771",
    "checksum_src": "2402a2e364f103389265587a9b599c16202f6771",
    "dest": "/tmp/httpd-2.4.68.tar.bz2",
    "elapsed": 8,
    "msg": "The checksum for /tmp/httpd-2.4.68.tar.bz2 did not match 88c74d4df38c26bed4dfbdb8f3baf1eb532f3872357becc1bba5d136f6b63c06; it was 68c74d4df38c26bed4dfbdb8f3baf1eb532f3872357becc1bba5d136f6b63c06.",
    "src": "/root/.ansible/tmp/ansible-tmp-1786794248.8448346-1779-280827685915311/tmpuf09inmq",
    "url": "https://dlcdn.apache.org/httpd/httpd-2.4.68.tar.bz2"
}

可以看到 "msg": "The checksum for /tmp/httpd-2.4.68.tar.bz2 did not match这一行提示错误

八. archive模块

1. 简介

archive模块用于打包压缩保存在被管理的节点文件

2. 命令格式

archive模块再ansible使用时,标准写法是

ansible <目标主机> -m archive -a '属性1=值1 ... 属性n=值n'

3. 常见参数

path: 必选参数。要打包的源文件/目录。支持同时选择多个路径

dest: 归档文件的目标路径

format: 归档格式。分为gz(默认格式)、bz2、tar、xz、zip。不写时也会安装dest的拓展名自动判断

mode: 归档文件的权限,比如0755

owner/group: 归档文件的属主/属组

exclude_path: 排除的路径列表

remove: 归档成功后是否删除源文件。默认为no

force_archive: 单个文件时是否强制打包(否则单文件可能直接复制不压缩)。默认为no

follow: 是否跟随符号链接,默认为yes

exclusion_patterns: 归档压缩时排除内部文件

4. 实践

1) 准备临时文件

[root@1 ~]# ansible -m shell -a "mkdir -p /tmp/logs;cp /var/log/*.log /tmp/logs/" web_servers2
3 | CHANGED | rc=0 >>

[root@1 ~]# ansible -m shell -a "ls /tmp/logs" web_servers2
3 | CHANGED | rc=0 >>
dnf.librepo.log
dnf.log
dnf.rpm.log
hawkey.log
vmware-network.1.log
vmware-network.2.log
vmware-network.3.log
vmware-network.4.log
vmware-network.5.log
vmware-network.6.log
vmware-network.7.log
vmware-network.8.log
vmware-network.9.log
vmware-network.log
vmware-vmsvc-root.log
vmware-vmtoolsd-root.log

2) 将制定目录下的文件进行压缩打包。要求用户必须存在,而且也支持对应压缩格式,目录也必须存在

a. 打包

[root@1 ~]# ansible -m shell -a 'mkdir -p /data/' web_servers2
3 | CHANGED | rc=0 >>

[root@1 ~]# ansible -m archive -a "path=/tmp/logs/* dest=/data/logs.tgz format=gz mode=0755 owner=bin group=bin  exclusion_patterns=dnf.log remove=yes" web_servers2
3 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "archived": [
        "/tmp/logs/dnf.librepo.log",
        "/tmp/logs/dnf.rpm.log",
        "/tmp/logs/hawkey.log",
        "/tmp/logs/vmware-network.1.log",
        "/tmp/logs/vmware-network.2.log",
        "/tmp/logs/vmware-network.3.log",
        "/tmp/logs/vmware-network.4.log",
        "/tmp/logs/vmware-network.5.log",
        "/tmp/logs/vmware-network.6.log",
        "/tmp/logs/vmware-network.7.log",
        "/tmp/logs/vmware-network.8.log",
        "/tmp/logs/vmware-network.9.log",
        "/tmp/logs/vmware-network.log",
        "/tmp/logs/vmware-vmsvc-root.log",
        "/tmp/logs/vmware-vmtoolsd-root.log"
    ],
    "arcroot": "/tmp/logs/",
    "changed": true,
    "dest": "/data/logs.tgz",
    "dest_state": "archive",
    "expanded_exclude_paths": [],
    "expanded_paths": [
        "/tmp/logs/dnf.librepo.log",
        "/tmp/logs/dnf.log",
        "/tmp/logs/dnf.rpm.log",
        "/tmp/logs/hawkey.log",
        "/tmp/logs/vmware-network.1.log",
        "/tmp/logs/vmware-network.2.log",
        "/tmp/logs/vmware-network.3.log",
        "/tmp/logs/vmware-network.4.log",
        "/tmp/logs/vmware-network.5.log",
        "/tmp/logs/vmware-network.6.log",
        "/tmp/logs/vmware-network.7.log",
        "/tmp/logs/vmware-network.8.log",
        "/tmp/logs/vmware-network.9.log",
        "/tmp/logs/vmware-network.log",
        "/tmp/logs/vmware-vmsvc-root.log",
        "/tmp/logs/vmware-vmtoolsd-root.log"
    ],
    "gid": 1,
    "group": "bin",
    "missing": [],
    "mode": "0755",
    "owner": "bin",
    "size": 8606,
    "state": "file",
    "uid": 1
}

b. 查看验证

[root@1 ~]# ansible -m shell -a "ls -l /tmp/logs/;echo '----------';ls -l /data/;echo '----------';tar tvf /data/logs.tgz" web_servers2
3 | CHANGED | rc=0 >>
总用量 76
-rw-r--r-- 1 root root 74101  8月 16 11:53 dnf.log
----------
总用量 12
-rwxr-xr-x 1 bin bin 8606  8月 16 11:54 logs.tgz
----------
-rw-r--r-- root/root     32831 2026-08-16 11:53 dnf.librepo.log
-rw-r--r-- root/root      2397 2026-08-16 11:53 dnf.rpm.log
-rw-r--r-- root/root        60 2026-08-16 11:53 hawkey.log
-rw------- root/root       217 2026-08-16 11:53 vmware-network.1.log
-rw------- root/root       217 2026-08-16 11:53 vmware-network.2.log
-rw------- root/root       217 2026-08-16 11:53 vmware-network.3.log
-rw------- root/root       217 2026-08-16 11:53 vmware-network.4.log
-rw------- root/root       217 2026-08-16 11:53 vmware-network.5.log
-rw------- root/root       217 2026-08-16 11:53 vmware-network.6.log
-rw------- root/root       217 2026-08-16 11:53 vmware-network.7.log
-rw------- root/root       217 2026-08-16 11:53 vmware-network.8.log
-rw------- root/root       217 2026-08-16 11:53 vmware-network.9.log
-rw------- root/root       217 2026-08-16 11:53 vmware-network.log
-rw------- root/root     56214 2026-08-16 11:53 vmware-vmsvc-root.log
-rw------- root/root      7500 2026-08-16 11:53 vmware-vmtoolsd-root.log

可以看到/tmp/logs/目录中只还有dnf.log文件在,/data/logs.tgz文件权限是755正常,而且被排除的/data/logs.tgz归档压缩文件中也没有/data/logs.tgz被正常排除了。

九. unarchive模块

1. 简介

unarchive模块主要用于压缩包解压的功能

2. 常见参数

src: 源路径。可以是ansible主机上的路径也可以是远程主机上的路径

copy: 默认值为yes

  • 当copy=yes时,拷贝的文件是从ansible主机复制到远程主机上

  • 当copy=no时,会在远程主机上寻找src源文件

remote_src: 和copy功能相同且互相排斥。

  • 当remote_src=yes时,会在远程主机寻找src源文件

  • 当remote_ser=no时,拷贝的文件是从ansible主机复制到远程主机

dest: 远程主机上的目标路径

mode: 设置解压后的文件权限

注意: 有时候会因为ansible版本文件导致无法远程解压,可以用copy+shell模块解决

3. 命令格式

unarchive模块在ansible使用的时候,标准的写法为

ansible <目标主机> -m unarchive -a '属性1=值1 属性2=值2 ... 属性n=值n'

4. 实践

a. 准备工作目录

[root@1 ~]# tar zcf passwd.tar.gz /etc/passwd
tar: 从成员名中删除开头的“/”
[root@1 ~]# ansible -m shell -a "mkdir -p /data/passwd/etc" web_servers2
3 | CHANGED | rc=0 >>

b. 将本地目录文件解压到指定位置

[root@1 ~]# ansible -m unarchive -a "src=passwd.tar.gz  remote_src=no dest=/data/passwd/etc/ mode=0642" web_servers2
3 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": true,
    "dest": "/data/passwd/etc/",
    "extract_results": {
        "cmd": [
            "/usr/bin/gtar",
            "--extract",
            "-C",
            "/data/passwd/etc",
            "-z",
            "-f",
            "/root/.ansible/tmp/ansible-tmp-1786856169.7440853-2202-225484372245780/source"
        ],
        "err": "",
        "out": "",
        "rc": 0
    },
    "gid": 0,
    "group": "root",
    "handler": "TgzArchive",
    "mode": "0755",
    "owner": "root",
    "size": 17,
    "src": "/root/.ansible/tmp/ansible-tmp-1786856169.7440853-2202-225484372245780/source",
    "state": "directory",
    "uid": 0
}

c. 查看验证

[root@1 ~]# ansible -m shell -a "ls -l /data/passwd/etc/*" web_servers2
3 | CHANGED | rc=0 >>
总用量 4
-rw-r---w- 1 root root 1127  8月 13 11:38 passwd