第2章 Ansible的常用模块

第2章 Ansible的常用模块

# 找出想要的模块
ansible-doc -l | grep Module_Name
# 查看此模块的用法
ansible-doc -s Module_Name

# 官方模块列表和说明
https://docs.ansible.com/ansible/latest/modules_by_category.html
  • 关于模块的使用方法,需要注意的是“state”。很多模块都会有该选项,且其值几乎都包含有“present”和“absent”,表示肯定和否定的意思。
  • ansible绝大多数模块都天然具有幂等特性,只有极少数模块,如:shell和command模块不具备幂等特性。所谓的幂等性是指多次执行同一个操作不会影响最终结果。例如,ansible的yum模块安装rpm包时,如果待安装的包已经安装过了,则再次或多次执行安装操作都不会真正的执行下去。再例如,copy模块拷贝文件时,如果目标主机上已经有了完全相同的文件,则多次执行copy模块不会真正的拷贝。ansible具有幂等性的模块在执行时,都会自动判断是否要执行。

2.1. 主机连通性测试

# 使用 ansible web -m ping 命令来进行主机连通性测试,效果如下:
[root@localhost ~]# ansible web -m ping
web2 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
web1 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
# 这样就说明我们的主机是连通状态,接下来的操作才可以正常进行。

2.2. command模块

# 这个模块可以直接在远程主机上执行命令,并将结果返回本主机。
举例如下:
[root@localhost ~]# ansible web -m command -a "ss -ntl"
web2 | CHANGED | rc=0 >>
State      Recv-Q Send-Q Local Address:Port               Peer Address:Port
LISTEN     0      128          *:111                      *:*
LISTEN     0      128          *:80                       *:*
LISTEN     0      128          *:22                       *:*
LISTEN     0      100    127.0.0.1:25                       *:*
LISTEN     0      50           *:3306                     *:*
LISTEN     0      128         :::111                     :::*
LISTEN     0      128         :::80                      :::*
LISTEN     0      128         :::22                      :::*
LISTEN     0      100        ::1:25                      :::*

web1 | CHANGED | rc=0 >>
State      Recv-Q Send-Q Local Address:Port               Peer Address:Port
LISTEN     0      128          *:111                      *:*
LISTEN     0      128          *:80                       *:*
LISTEN     0      128          *:22                       *:*
LISTEN     0      100    127.0.0.1:25                       *:*
LISTEN     0      50           *:3306                     *:*
LISTEN     0      128         :::111                     :::*
LISTEN     0      128         :::80                      :::*
LISTEN     0      128         :::22                      :::*
LISTEN     0      100        ::1:25                      :::*

注意:该命令不支持 “|” 管道命令。(shell模块可以实现这个功能)
# 该模块常用的几个命令:
chdir       # 在执行命令之前,先切换到该目录
executable  # 切换shell来执行命令,需要使用命令的绝对路径
free_from       # 要执行的linux指令,一般使用ansible的-a参数代替
creates     # 一个文件名,当这个文件存在,则该命令不执行,可以用作判断
removes     # 一个文件名,这个文件不存在,则该命令不执行
# 执行效果如下:
# 先切换到/data/ 目录,再执行ls
[root@localhost ~]# ansible web1 -m command -a 'chdir=/data/ ls'
web1 | CHANGED | rc=0 >>
app
backup


# 如果/data/1.jpg 不存在,执行ls; 如果/data/1.jpg存在,则不执行
[root@localhost ~]# ansible web1 -m command -a 'creates=/data/1.jpg ls'
web1 | CHANGED | rc=0 >>
anaconda-ks.cfg


# 如果/data/1.jpg 不存在,不执行ls
[root@localhost ~]# ansible web1 -m command -a 'removes=/data/1.jpg ls'
web1 | SUCCESS | rc=0 >>
skipped, since /data/1.jpg does not exist

# 如果/data/1.jpg 存在,执行ls
[root@localhost ~]# touch /data/1.jpg
[root@localhost ~]# ansible web1 -m command -a 'removes=/data/1.jpg ls'
web1 | CHANGED | rc=0 >>
anaconda-ks.cfg

2.3. shell模块

# shell模块可以在远程主机上调用shell解释器运行命令,支持shell的各种功能,例如管道等
[root@localhost ~]# ansible web1 -m shell -a 'cat /etc/passwd | tail -1'
web1 | CHANGED | rc=0 >>
mysql:x:27:27:MariaDB Server:/var/lib/mysql:/sbin/nologin

# 只要是shell命令,都可以通过这个模块在远程主机上运行

2.4.copy模块

# 这个模块用于将文件复制到远程主机,同时支持给定内容生成文件和修改权限等。
相关选项如下:
src     # 被复制到远程主机的本地文件。可以是绝对路径,也可以是相对路径。如果路径是目录,则会递归复制。用法类似于“rsync”;
content # 用于替换“src”,可以直接指定文件的值;
dest        # 必选项,将源文件复制到远程主机的绝对路径;
backup  # 当文件内容发生改变后,在覆盖之前把源文件备份,备份文件包含时间信息;
directory_mode  # 递归设定目录的权限,默认为系统默认权限;
force       # 当目标主机包含该文件,但内容不同时,设为“yes”,表示强制覆盖;设为“no”,表示目标主机的目标位置不存在该文件才复制,默认为“yes”;
others  # 所有的file模块中的选项可以在这里使用;

# 用法举例:
# 复制文件
[root@localhost ~]# ansible web1 -m copy -a 'src=~/hello dest=/data/hello'
web1 | CHANGED => {
    "changed": true,
    "checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
    "dest": "/data/hello",
    "gid": 0,
    "group": "root",
    "md5sum": "d41d8cd98f00b204e9800998ecf8427e",
    "mode": "0644",
    "owner": "root",
    "size": 0,
    "src": "/root/.ansible/tmp/ansible-tmp-1582524476.5-63924773186927/source",
    "state": "file",
    "uid": 0
}


# 给定内容生成文件,并制定权限
[root@localhost ~]# ansible web1 -m copy -a 'content="I am HSLM_Z\n" dest=/data/name mode=666'
web1 | CHANGED => {
    "changed": true,
    "checksum": "395cbed50777f84b66e8f373f3ed3c1379f12149",
    "dest": "/data/name",
    "gid": 0,
    "group": "root",
    "md5sum": "06a5b899cbafbcc7615fa7eb9506bb95",
    "mode": "0666",
    "owner": "root",
    "size": 12,
    "src": "/root/.ansible/tmp/ansible-tmp-1582524610.62-273264382797847/source",
    "state": "file",
    "uid": 0
}

# 查看生成的文件及其权限
# 可以看到name文件已经生成,并且权限为666
[root@localhost ~]# ansible web1 -m shell -a 'ls -l /data'
web1 | CHANGED | rc=0 >>
total 8
-rw-rw-rw- 1 root root 12 Feb 24 14:10 name
[root@localhost ~]# ansible web1 -m shell -a 'cat /data/name'
web1 | CHANGED | rc=0 >>
I am HSLM_Z


# 把文件修改一下,然后选择覆盖,备份
[root@localhost ~]# ansible web1 -m copy -a 'content="I am HsLM_H\n" backup=yes dest=/data/name mode=666'
web1 | CHANGED => {
    "backup_file": "/data/name.62270.2020-02-24@14:32:31~",
    "changed": true,
    "checksum": "181c279d68607c348f521c9cb95ddc6430f5b2b4",
    "dest": "/data/name",
    "gid": 0,
    "group": "root",
    "md5sum": "f446acfc527b31904207035493737d78",
    "mode": "0666",
    "owner": "root",
    "size": 12,
    "src": "/root/.ansible/tmp/ansible-tmp-1582525948.51-91189713002017/source",
    "state": "file",
    "uid": 0
}

# 可以看到已经生成备份,再查看文件内容已经修改
[root@localhost ~]# ansible web1 -m shell -a 'ls -l /data/'
web1 | CHANGED | rc=0 >>
total 12
-rw-rw-rw- 1 root root 12 Feb 24 14:32 name
-rw-rw-rw- 1 root root 12 Feb 24 14:10 name.62270.2020-02-24@14:32:31~
[root@localhost ~]# ansible web1 -m shell -a 'cat /data/name'
web1 | CHANGED | rc=0 >>
I am HsLM_H

2.5. file模块

# 该模块主要用于设置文件的属性,比如创建文件,创建链接文件,删除文件等
常见命令:
force       # 需要在两种情况下强制创建软连接,一种是源文件不存在,但之后会建立的情况下;另一种是目标软链接已经存在,需要先取消之前的软链接,然后创建新的链接。有两个选项:yes|no;
group   # 定义文件/目录的属组。后面可以加上mode:定义文件/目录的权限;
owner   # 定义文件/目录的属主。后面必须跟上path:定义文件/目录的路径;
recurse # 递归设置文件的属性,只对目录有效,后面跟上src:被链接的源文件路径,只应用于state=link的情况;
dest        # 被链接到的路径,只应用于state=link的情况;
state       # 状态,有以下选项:
directory   # 如果目录不存在,就创建目录;
file        # 即使文件不存在,也不会被创建;
link        # 创建软连接;
hard        # 创建硬链接;
touch   # 如果文件不存在,则会创建一个新的文件,如果文件或目录已存在,则更新其最后修改时间;
absent  # 删除目录,文件或者取消链接文件;

# 用法举例:
# 创建目录
[root@localhost ~]# ansible web1 -m file -a 'path=/data/app state=directory'
web1 | CHANGED => {
    "changed": true,
    "gid": 0,
    "group": "root",
    "mode": "0755",
    "owner": "root",
    "path": "/data/app",
    "size": 6,
    "state": "directory",
    "uid": 0
}
[root@localhost ~]# ansible web1 -m shell -a 'ls -l /data/'
web1 | CHANGED | rc=0 >>
total 12
drwxr-xr-x 2 root root  6 Feb 24 14:40 app


# 创建文件,创建链接,查看链接是否成功
[root@localhost ~]# ansible web1 -m file -a 'path=/data/aaa.jpg state=touch'
web1 | CHANGED => {
    "changed": true,
    "dest": "/data/aaa.jpg",
    "gid": 0,
    "group": "root",
    "mode": "0644",
    "owner": "root",
    "size": 0,
    "state": "file",
    "uid": 0
}
[root@localhost ~]# ansible web1 -m file -a 'path=/data/bbb.jpg src=aaa.jpg state=link'
web1 | CHANGED => {
    "changed": true,
    "dest": "/data/bbb.jpg",
    "gid": 0,
    "group": "root",
    "mode": "0777",
    "owner": "root",
    "size": 7,
    "src": "aaa.jpg",
    "state": "link",
    "uid": 0
}
[root@localhost ~]# ansible web1 -m shell -a 'ls -l /data/'
web1 | CHANGED | rc=0 >>
total 12
-rw-r--r-- 1 root root  0 Feb 24 14:55 aaa.jpg
lrwxrwxrwx 1 root root  7 Feb 24 14:56 bbb.jpg -> aaa.jpg


# 删除文件
[root@localhost ~]# ansible web1 -m file -a 'path=/data/aaa.jpg state=absent'
web1 | CHANGED => {
    "changed": true,
    "path": "/data/aaa.jpg",
    "state": "absent"
}

2.6. fetch模块

# 该模块用于从远程某主机获取(复制)文件到本地
有两个选项:
dest        # 用于存放文件的目录
src     # 在远程拉取的文件,并且必须是一个file,不能是目录

举例如下:
# 将远程web1主机上的/data/hello文件拷贝至本机的/tmp目录下
[root@localhost ~]# ansible web1 -m fetch -a 'src=/data/hello dest=/tmp'
web1 | CHANGED => {
    "changed": true,
    "checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
    "dest": "/tmp/web1/data/hello",
    "md5sum": "d41d8cd98f00b204e9800998ecf8427e",
    "remote_checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
    "remote_md5sum": null
}
# 查看文件是否复制成功。注意:文件保存的路径是我们设置的接收目录下的被控主机ip目录下:
[root@localhost ~]# ls -l /tmp/web1/data/hello
-rw-r--r-- 1 root root 0 Feb 24 15:02 /tmp/web1/data/hello

2.7. cron模块

# 该模块适用于管理cron计划任务的;
其使用的语法和我们的crontab的语法一致;
选项如下:
day=        # 日,应该运行的工作(1-31,/2);
hour=   # 小时,(0-23,/2);
minute= # 分钟,(0-59,/2);
month=  # 月,(1-12,/2);
weekday=    # 周,(0-6 for Sunday-Saturday);
job=        # 指明运行的命令是什么;
name=   # 定时任务的描述;
reboot  # 任务在重启时运行,不建议使用;建议使用special_time;
special_time    # 特殊的时间范围,参数:reboot(重启时),annually(每年),monthly(每月),weekly(每周),daily(每天),hourly(每小时);
state       # 指定状态,present表示添加定时任务,也是默认设置,absent表示删除定时任务;
user        # 以哪个用户的身份执行;

举例如下:
# 添加计划任务
[root@localhost ~]# ansible web1 -m cron -a 'name="ntp update every 5 min" minute=*/5 job="/sbin/ntpdate 172.17.0.1 &> /dev/null"'
web1 | CHANGED => {
    "changed": true,
    "envs": [],
    "jobs": [
        "ntp update every 5 min"
    ]
}

# 查看添加的计划任务
[root@localhost ~]# ansible web1 -m shell -a 'crontab -l'
web1 | CHANGED | rc=0 >>
#Ansible: ntp update every 5 min
*/5 * * * * /sbin/ntpdate 172.17.0.1 &> /dev/null



# 删除计划任务
# 先查看原有计划任务
[root@localhost ~]# ansible web1 -m shell -a 'crontab -l'
web1 | CHANGED | rc=0 >>
#Ansible: ntp update every 5 min
*/5 * * * * /sbin/ntpdate 172.17.0.1 &> /dev/null
#Ansible: HS everyday
* 15 * * * df -lh >> /tmp/disk_total &> /dev/null

# 删除计划任务
[root@localhost ~]# ansible web1 -m cron -a 'name="HS everyday" hour=15 job="df -lh >> /tmp/disk_total &> /dev/null" state=absent'
web1 | CHANGED => {
    "changed": true,
    "envs": [],
    "jobs": [
        "ntp update every 5 min"
    ]
}

# 再次查看,已经被删除了
[root@localhost ~]# ansible web1 -m shell -a 'crontab -l'
web1 | CHANGED | rc=0 >>
#Ansible: ntp update every 5 min
*/5 * * * * /sbin/ntpdate 172.17.0.1 &> /dev/null

2.8. yum模块

# 该模块主要用于软件的安装。
选项如下:
name=   # 所安装的包的名称
state=  # present--->安装, latest--->安装最新的, absent---> 卸载软件。
update_cache            # 强制更新yum的缓存
conf_file   # 指定远程yum安装时所依赖的配置文件(安装本地已有的包)。
disable_pgp_check       # 是否禁止GPG checking,只用于presentor latest。
disablerepo     # 临时禁止使用yum库。 只用于安装或更新时。
enablerepo      # 临时使用的yum库。只用于安装或更新时。
[root@localhost ~]# ansible web1 -m yum -a 'name=httpd state=present'
web1 | CHANGED => {
    "ansible_facts": {
        "pkg_mgr": "yum"
    },
    "changed": true,
    "changes": {
        "installed": [
            "httpd"
        ]
    },
    "msg": "",
    "rc": 0,
    "results": [
        "Loaded plugins: fastestmirror, langpacks\nLoading mirror speeds from cached hostfile\n * base: mirrors.aliyun.com\n * epel: mirrors.tuna.tsinghua.edu.cn\n * extras: mirrors.aliyun.com\n * updates: mirrors.aliyun.com\nResolving Dependencies\n--> Running transaction check\n---> Package httpd.x86_64 0:2.4.6-90.el7.centos will be installed\n--> Processing Dependency: httpd-tools = 2.4.6-90.el7.centos for package: httpd-2.4.6-90.el7.centos.x86_64\n--> Processing Dependency: /etc/mime.types for package: httpd-2.4.6-90.el7.centos.x86_64\n--> Processing Dependency: libaprutil-1.so.0()(64bit) for package: httpd-2.4.6-90.el7.centos.x86_64\n--> Processing Dependency: libapr-1.so.0()(64bit) for package:httpd-2.4.6-90.el7.centos.x86_64\n--> Running transaction check\n---> Package apr.x86_64 0:1.4.8-5.el7 will be installed\n---> Package apr-util.x86_64 0:1.5.2-6.el7 will be installed\n---> Package httpd-tools.x86_64 0:2.4.6-90.el7.centos will be installed\n---> Package mailcap.noarch 0:2.1.41-2.el7 will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package            Arch Version                     Repository   Size\n================================================================================\nInstalling:\n httpd              x86_64        2.4.6-90.el7.centos         base    2.7 M\nInstalling for dependencies:\n apr                x86_64    1.4.8-5.el7                 base        103 k\n apr-utilx86_64        1.5.2-6.el7                 base         92 k\n httpd-tools        x86_64        2.4.6-90.el7.centos         base         91 k\n mailcap            noarch        2.1.41-2.el7                base    31 k\n\nTransaction Summary\n================================================================================\nInstall  1 Package (+4 Dependent packages)\n\nTotal download size: 3.0 M\nInstalled size: 10 M\nDownloading packages:\n--------------------------------------------------------------------------------\nTotal            2.7 MB/s | 3.0 MB  00:01     \nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n  Installing : apr-1.4.8-5.el7.x86_64        1/5 \n  Installing : apr-util-1.5.2-6.el7.x86_64                   2/5 \n  Installing : httpd-tools-2.4.6-90.el7.centos.x86_64                       3/5 \n  Installing : mailcap-2.1.41-2.el7.noarch                                  4/5 \n  Installing : httpd-2.4.6-90.el7.centos.x86_64                             5/5 \n  Verifying: apr-1.4.8-5.el7.x86_64                                       1/5 \nVerifying  : mailcap-2.1.41-2.el7.noarch   2/5 \n  Verifying  : httpd-tools-2.4.6-90.el7.centos.x86_64              3/5 \n  Verifying  : apr-util-1.5.2-6.el7.x86_64                         4/5 \n  Verifying  : httpd-2.4.6-90.el7.centos.x86_64                             5/5 \n\nInstalled:\n  httpd.x86_640:2.4.6-90.el7.centos                                            \n\nDependency Installed:\n  apr.x86_64 0:1.4.8-5.el7                     apr-util.x86_64 0:1.5.2-6.el7    \n  httpd-tools.x86_64 0:2.4.6-90.el7.centos     mailcap.noarch 0:2.1.41-2.el7    \n\nComplete!\n"
    ]
}

2.9. service模块

# 该模块用于服务程序的管理。
其主要选项如下:
arguments   # 命令行提供额外的参数
enabled # 设置开机启动。
name=   # 服务名称
runlevel    # 开机启动的级别,一般不用指定。
sleep       # 在重启服务的过程中,是否等待。如在服务关闭以后等待2秒再启动。(定义在剧本中。)
state       # 有四种状态,分别为:started--->启动服务, stopped--->停止服务, restarted--->重启服务, reloaded--->重载配置
# 开启服务并设置自启动
[root@localhost ~]# ansible web1 -m service -a 'name=nginx state=started enabled=true'
web1 | CHANGED => {
    "changed": true,
    "enabled": true,
    "name": "nginx",
    "state": "started",
    ······
}

# 查看端口是否打开
[root@localhost ~]# ansible web1 -m shell -a 'ss -ntl'
web1 | CHANGED | rc=0 >>
State      Recv-Q Send-Q Local Address:Port               Peer Address:Port
LISTEN     0      128          *:80                       *:*


# 关闭服务
[root@localhost ~]# ansible web1 -m service -a 'name=nginx state=stopped'
web1 | CHANGED => {
    "changed": true,
    "name": "nginx",
    "state": "stopped",
    ······
}

# 查看端口,已经没有80端口了
[root@localhost ~]# ansible web1 -m shell -a 'ss -ntl | grep 80'
web1 | FAILED | rc=1 >>

2.10. user模块

# 该模块主要是用来管理用户账号。
主要选项如下:
comment     # 用户的描述信息
createhome  # 是否创建家目录
force           # 在使用state=absent时, 行为与userdel –force一致.
group       # 指定基本组
groups      # 指定附加组,如果指定为(groups=)表示删除所有组
home        # 指定用户家目录
move_home   # 如果设置为home=时, 试图将用户主目录移动到指定的目录
name        # 指定用户名
non_unique  # 该选项允许改变非唯一的用户ID值
password        # 指定用户密码
remove      # 在使用state=absent时, 行为是与userdel –remove一致
shell           # 指定默认shell
state           # 设置帐号状态,不指定为创建,指定值为absent表示删除
system      # 当创建一个用户,设置这个用户是系统用户。这个设置不能更改现有用户
uid         # 指定用户的uid
# 创建一个用户并查看
[root@localhost ~]# ansible web1 -m user -a 'name=hslm uid=11111'
web1 | CHANGED => {
    "changed": true,
    "comment": "",
    "create_home": true,
    "group": 11111,
    "home": "/home/hslm",
    "name": "hslm",
    "shell": "/bin/bash",
    "state": "present",
    "system": false,
    "uid": 11111
}

[root@localhost ~]# ansible web1 -m shell -a 'cat /etc/passwd | grep hslm'web1 | CHANGED | rc=0 >>
hslm:x:11111:11111::/home/hslm:/bin/bash


# 删除并查看
[root@localhost ~]# ansible web1 -m user -a 'name=hslm state=absent'
web1 | CHANGED => {
    "changed": true,
    "force": false,
    "name": "hslm",
    "remove": false,
    "state": "absent"
}

[root@localhost ~]# ansible web1 -m shell -a 'cat /etc/passwd | grep hslm'
web1 | FAILED | rc=1 >>

2.11. group模块

# 该模块主要用于添加或删除组。
常用的选项如下:
gid=        # 设置组的GID号
name=   # 指定组的名称
state=  # 指定组的状态,默认为创建,设置值为absent为删除
system= # 设置值为yes,表示创建为系统组
# 创建组,并查看是否创建
[root@localhost ~]# ansible web1 -m group -a 'name=sange gid=22222'
web1 | CHANGED => {
    "changed": true,
    "gid": 22222,
    "name": "sange",
    "state": "present",
    "system": false
}

[root@localhost ~]# ansible web1 -m shell -a 'cat /etc/group | grep 22222'
web1 | CHANGED | rc=0 >>
sange:x:22222:


# 删除组,并查看是否删除
[root@localhost ~]# ansible web1 -m group -a 'name=sange state=absent'
web1 | CHANGED => {
    "changed": true,
    "name": "sange",
    "state": "absent"
}

[root@localhost ~]# ansible web1 -m shell -a 'cat /etc/group | grep 22222'
web1 | FAILED | rc=1 >>

2.12. script模块

# 该模块用于将本机的脚本在被管理端的机器上运行。
该模块直接指定脚本的路径即可。
# 先写一个脚本,加上执行权限
[root@localhost ~]# vim /tmp/df.sh
#!/bin/bash
date >> /tmp/disk_total.log
df -lh >> /tmp/disk_total.log
[root@localhost ~]# chmod +x /tmp/df.sh

# 直接运行命令,实现在被管理端执行该脚本
[root@localhost ~]# ansible web1 -m script -a '/tmp/df.sh'
web1 | CHANGED => {
    "changed": true,
    "rc": 0,
    "stderr": "Shared connection to web1 closed.\r\n",
    "stderr_lines": [
        "Shared connection to web1 closed."
    ],
    "stdout": "",
    "stdout_lines": []
}

[root@localhost ~]# ansible web1 -m shell -a 'cat /tmp/disk_total.log'
web1 | CHANGED | rc=0 >>
Mon Feb 24 16:06:49 CST 2020
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda3        20G  2.0G   18G  10% /
devtmpfs        483M     0  483M   0% /dev
tmpfs           493M  124K  493M   1% /dev/shm
tmpfs           493M   38M  455M   8% /run
tmpfs           493M     0  493M   0% /sys/fs/cgroup
/dev/sda1       197M  103M   95M  52% /boot
tmpfs            99M     0   99M   0% /run/user/0
Mon Feb 24 16:06:49 CST 2020
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda3        20G  2.0G   18G  10% /
devtmpfs        483M     0  483M   0% /dev
tmpfs           493M  124K  493M   1% /dev/shm
tmpfs           493M   38M  455M   8% /run
tmpfs           493M     0  493M   0% /sys/fs/cgroup
/dev/sda1       197M  103M   95M  52% /boot
tmpfs            99M     0   99M   0% /run/user/0

2.13. setup模块

该模块主要用于收集信息,是通过调用facts组件来实现的。
facts组件是ansible用于采集被控设备信息的一个功能,我们可以使用setup模块查机器的所有facts信息,可以使用filer来查看指定信息。整个facts信息被包装在一个JSON格式的数据结构中,ansible_facts是最上层的值。
facts就是变量,内建变量。每个主机的各种信息,cpu颗数,内存大小等。会存在facts中的某个变量中,调用后返回很多对应主机的信息,可以根据不同的信息来做不同的操作。如redhat系列用yum安装,而debian系列用apt来安装软件。
# 举例使用:
[root@localhost ~]# ansible web1 -m setup -a 'filter="*mem*"'
web1 | SUCCESS => {
    "ansible_facts": {
        "ansible_memfree_mb": 194,
        "ansible_memory_mb": {
            "nocache": {
                "free": 608,
                "used": 376
            },
            "real": {
                "free": 194,
                "total": 984,
                "used": 790
            },
            "swap": {
                "cached": 0,
                "free": 507,
                "total": 511,
                "used": 4
            }
        },
        "ansible_memtotal_mb": 984
    },
    "changed": false
}
# 查看信息是否一致
[root@localhost ~]# ansible web1 -m shell -a 'free -m'
web1 | CHANGED | rc=0 >>
              total        used        free      shared  buff/cache   available
Mem:            984         249         207          33         528  499
Swap:           511           4         507


# 保存信息;setup模块可以将我们筛选的信息保存至我们的主机上;
同时,文件名为被控主机的IP,方便我们知道哪台机器出的问题
[root@localhost ~]# ansible web1 -m setup -a 'filter="*mem*"' --tree /tmp/facts
web1 | SUCCESS => {
    "ansible_facts": {
        "ansible_memfree_mb": 196,
        "ansible_memory_mb": {
            "nocache": {
                "free": 610,
                "used": 374
            },
            "real": {
                "free": 196,
                "total": 984,
                "used": 788
            },
            "swap": {
                "cached": 0,
                "free": 507,
                "total": 511,
                "used": 4
            }
        },
        "ansible_memtotal_mb": 984
    },
    "changed": false
}
# 查看保存的信息
[root@localhost ~]# cat /tmp/facts/web1
{"ansible_facts": {"ansible_memfree_mb": 196, "ansible_memory_mb": {"nocache": {"free": 610, "used": 374}, "real": {"free": 196, "total": 984, "used": 788}, "swap": {"cached": 0, "free": 507, "total": 511, "used": 4}}, "ansible_memtotal_mb": 984}, "changed": false}

2.14. unarchive模块

这个模块的主要作用就是解压。模块有两种用法:
如果参数copy=yes,则把本地的压缩包拷贝到远程主机,然后执行压缩。
如果参数copy=no,则直接解压远程主机上给出的压缩包。
其他选项:
creates # 指定一个文件名,当该文件存在时,则解压指令不执行;
dest        # 远程主机上的一个路径,即文件解压的路径;
grop        # 解压后的目录或文件的属组;
list_files  # 如果为yes,则会列出压缩包里的文件,默认为no,2.0版本新增的选项;
mode    # 解压后文件的权限;
src     # 如果copy为yes,则需要指定压缩文件的源路径;
owner   # 解压后文件或目录的属主
# 
[root@localhost ~]# ansible web1 -m unarchive -a 'src=/root/etc.tar.gz dest=/data/ copy=no'
web1 | CHANGED => {
    "changed": true,
    "dest": "/data/",
    "extract_results": {
        "cmd": [
            "/usr/bin/gtar",
            "--extract",
            "-C",
            "/data/",
            "-f",
            "/root/etc.tar.gz"
        ],
        "err": "",
        "out": "",
        "rc": 0
    },
    "gid": 0,
    "group": "root",
    "handler": "TarArchive",
    "mode": "0755",
    "owner": "root",
    "size": 174,
    "src": "/root/etc.tar.gz",
    "state": "directory",
    "uid": 0
}


2.15. archive压缩模块
[root@localhost ~]# ansible web1 -m archive -a 'path=/root/test/* format=gz dest=/data/test.tar.gz'
web1 | CHANGED => {
    "archived": [
        "/root/test/1.txt",
        "/root/test/2.txt"
    ],
    "arcroot": "/root/test/",
    "changed": true,
    "dest": "/data/test.tar.gz",
    "expanded_exclude_paths": [],
    "expanded_paths": [
        "/root/test/1.txt",
        "/root/test/2.txt"
    ],
    "gid": 0,
    "group": "root",
    "missing": [],
    "mode": "0644",
    "owner": "root",
    "size": 135,
    "state": "file",
    "uid": 0
}
[root@localhost ~]# ansible web1 -m shell -a 'ls -l /data/test.tar.gz'
web1 | CHANGED | rc=0 >>
-rw-r--r-- 1 root root 135 Feb 24 17:45 /data/test.tar.gz

2.16. replace模块

# 这个模块可以根据我们指定的正则表达式替换文件的匹配的内容;
 - name: change the start script
   # shell: sed -i "s/^datadir=/datadir=\/data\/mysql/" /etc/init.d/mysqld
   replace: path=/etc/init.d/mysqld replace="datadir={{ datadir_name }}" regexp="^datadir=" backup=yes
#安装MySQL的时候,需要修改MySQL的启动脚本,配置datadir参数, \
这里两行的作用是一样的。只是在执行playbook的时候, \
使用shell模块会报出警告说建议使用replcae模块。\ 
#模块参数如下:path: 指定远程主机要替换的文件的路径。\
regexp: 指定在文件中匹配的正则表达式,上面匹配以“datadir=” \
开头的行replace: 指定替换的文件,就是把上面正则匹配到的文件, \
替换成这里的内容。backup:表示在对文件操作之前是否备份文件。

2.17. lineinfile模块

# 这个模块遍历文本中每一行,然后对其中的行进行操作
path参数  # 必须参数,指定要操作的文件。
line参数  # 使用此参数指定文本内容。
regexp参数  # 使用正则表达式匹配对应的行,当替换文本时,如果有多行文本都能被匹配,则只有最后面被匹配到的那行文本才会被替换,当删除文本时,如果有多行文本都能被匹配,这么这些行都会被删除。
state参数   # 当想要删除对应的文本时,需要将state参数的值设置为absent,absent为缺席之意,表示删除,state的默认值为present。
backrefs参数 # 默认情况下,当根据正则替换文本时,即使regexp参数中的正则存在分组,在line参数中也不能对正则中的分组进行引用,除非将backrefs参数的值设置为yes。      backrefs=yes表示开启后向引用,这样,line参数中就能对regexp参数中的分组进行后向引用了,这样说不太容易明白,可以参考后面的示例命令理解。backrefs=yes      除了能够开启后向引用功能,还有另一个作用,默认情况下,当使用正则表达式替换对应行时,如果正则没有匹配到任何的行,那么line对应的内容会被插入到文本的末尾,      不过,如果使用了backrefs=yes,情况就不一样了,当使用正则表达式替换对应行时,同时设置了backrefs=yes,那么当正则没有匹配到任何的行时,      则不会对文件进行任何操作,相当于保持原文件不变。
insertafter参数  # 借助insertafter参数可以将文本插入到“指定的行”之后,insertafter参数的值可以设置为EOF或者正则表达式,EOF为End Of File之意,表示插入到文档的末尾,      默认情况下insertafter的值为EOF,如果将insertafter的值设置为正则表达式,表示将文本插入到匹配到正则的行之后,如果正则没有匹配到任何行,则插入到文件末尾,      当使用backrefs参数时,此参数会被忽略。
insertbefore参数 # 借助insertbefore参数可以将文本插入到“指定的行”之前,insertbefore参数的值可以设置为BOF或者正则表达式,BOF为Begin Of File之意,      表示插入到文档的开头,如果将insertbefore的值设置为正则表达式,表示将文本插入到匹配到正则的行之前,如果正则没有匹配到任何行,则插入到文件末尾,      当使用backrefs参数时,此参数会被忽略。
backup参数  # 是否在修改文件之前对文件进行备份。
create参数  # 当要操作的文件并不存在时,是否创建对应的文件。


在远程主机上创建一个测试文件:
[root@localhost ~]# cat mysqld 
[mysqld]
skip-grant-tables
datadir=/data/mysql

datadir is test

[mysqld]
apped this row


# 在ansible主机上进行测试:
[root@localhost ~]# cat test.yml 
---
 - hosts: master
   remote_user: root
   gather_facts: no
 
   tasks:
     - name: test the lineinfile module
       lineinfile:
          path=/test/mysqld
          regexp="^\[mysqld\]$"               #匹配以datadir开头的行
          line="test the row..."              #替换为指定的内容


执行上边的剧本:
[root@localhost ~]# ansible-playbook -i hosts test.yml 
 
PLAY [master] *******************************************************************************************************************************************************************************************
 
TASK [test the lineinfile module] ***********************************************************************************************************************************************************************
changed: [10.0.102.162]
 
PLAY RECAP **********************************************************************************************************************************************************************************************
10.0.102.162               : ok=1    changed=1    unreachable=0    failed=0   
 
#查看内容
#这里可以看到只有最后一个匹配的才被替换。
[root@localhost ~]# cat mysqld
[mysqld]
skip-grant-tables
datadir=/data/mysql
 
datadir is test
 
test the row...
apped this row<span class="cnblogs_code_copy"><a title="复制代码"><img id="__LEANOTE_D_IMG_1553660315011" src="/api/file/getImage?fileId=5c9b0c3bdd302f0359000075" alt="复制代码" data-mce-src="/api/file/getImage?fileId=5c9b0c3bdd302f0359000075"></a></span>


# 继续测试,在[mysqld]下面添加一行logbin=master;匹配删除已datadir开头的行;
[root@localhost ~]# cat test.yml 
---
 - hosts: master
   remote_user: root
   gather_facts: no
 
   tasks:
     - name: test the lineinfile module
       lineinfile:
          path=/test/mysqld
          line="log-bin=master"#设为正则表达式,表示文本插入到匹配行之后。
          insertafter="^\[mysqld\]$"          

[root@localhost ~]# ansible-playbook -i hosts test.yml 
 
PLAY [master] *******************************************************************************************************************************************************************************************
 
TASK [test the lineinfile module] ***********************************************************************************************************************************************************************
changed: [10.0.102.162]
 
PLAY RECAP **********************************************************************************************************************************************************************************************
10.0.102.162               : ok=1    changed=1    unreachable=0    failed=0   #查看结果如下:[root@docker4 test]# cat mysqld [mysqld]log-bin=masterskip-grant-tablesdatadir=/data/mysqldatadir is testtest the row...apped this row<span class="cnblogs_code_copy"><a title="复制代码"><img id="__LEANOTE_D_IMG_1553660315013" src="/api/file/getImage?fileId=5c9b0c3bdd302f0359000075" alt="复制代码" data-mce-src="/api/file/getImage?fileId=5c9b0c3bdd302f0359000075"></a></span>

2.18. template的用法

#  template模块用法和copy模块用法基本一致,它主要用于复制配置文件。
选项如下:
backup  # 拷贝的同时也创建一个包含时间戳信息的备份文件,默认为no dest=(目标路径)
force   # 设置为yes (默认)时,将覆盖远程同名文件;设置为no时,忽略同名文件的拷贝group(设置远程文件的所属组)
owner   # 设置远程文件的所有者
mode    # 设置远程文件的权限。使用数值表示时不能省略第一位,如0644;也可以使用 'u+rwx' or 'u=rw,g=r,o=r'等方式设置
src=        # ansible控制器上Jinja2格式的模板所在位置,可以是相对或绝对路径validate       #在复制到目标主机后但放到目标位置之前,执行此选项指定的命令。
    # 一般用于检查配置文件语法,语法正确则保存到目标位置。
 # 如果要引用目标文件名,则使用%s,下面的示例中的s%即表示目标机器上的/etc/nginx/nginx.conf

虽然template模块可以按需求修改配置文件内容来复制模板到被控主机上,但是有一种情况它是不能解决的:不同被控节点所需的配置文件差异很大,并非修改几个变量就可以满足。例如在centos 6和centos 7上通过yum安装的nginx,它们的配置文件内容相相差非常大,且centos 6上的nginx的默认就有一个/etc/nginx/conf .d/def ault.conf 。如果直接复制同一个模板的nginx配置文件到centos 6和centos 7上,很可能导致某一版本的nginx不能启动。
ansible centos -m template -a "src=/tmp/nginx.conf.j2 dest=/etc/nginx/nginx.conf mode=0770 owner=root group=root ba ckup=yes validate='nginx -t -c %s'" -o -f 6


这时就有必要在复制模板时挑选对应发行版的模板文件进行配对复制,例如要复制到 centos6上的源模板是nginx6.conf .j2,复制到cent os 7上的源模板是nginx7 .conf .j2。这种行为可以称之为"基于变量选择文件或模板"。
---
    - tasks:
    - name: template file based var
      template: src=/templates/nginx{{ ansible_distribution_major_version }}.conf.j2 dest=/etc/nginx/nginx.conf va lidate="/usr/sbin/nginx -t -c %s"


还可以在文件内容中指定jinja2的替代变量,在ansible执行时首先会根据变量内容进行渲染,渲染后再执行相关模块。例如,此处的template模块,复制某个基于发行版本号的yum源配置文件。以下是某个repo文件模板base.repo.j2的内容。
[epel] 
name=epel
baseurl=http://mirrors.aliyun.com/epel/{{ ansible_distribution_major_version }}Server/x86_64/ 
enable=1
gpgcheck=0


再复制即可。

猜你喜欢

转载自www.cnblogs.com/HsLM/p/12360508.html