目录
一,模块帮助查询
1.ansible的基本用法
ansible是指令核心部分,其主要用于执行ad-hoc命令,即单条命令。默认后面需要跟主机和选项部分,默认不指定模块时,使用的是command模块。
ansible运行临时命令语法
#ansible host-pattern -m module [-a 'module arguments'] [-i inventory]
ansible-doc 查找关于本地系统上安装的模块信息==显示模块帮助(ansible里man命令) |
-l,--lsit 查看控制节点上可用的模块列表以及其功能的概要;列出可用模块 |
-s,--snippet 列岀某个模块支持的动作 显示模块的playbook |
ansible-doc [module name] 查看指定模块的概要、选项、详细信息、以及基本用法 |
模块文档文档网站: Ansible Documentation |
注意:帮助显示中模块维护标记
由于有些模块可能处于不同的开发阶段查看模块开发状态,是在ansible-doc输出末尾的METEDATA部分中指明
stableinterface: 模块的关键字稳定,将尽力确保不删除关键字或更改其含义
preview:模块处于阶段预览,可能不稳定
deprecated: 模块弃用
removed:模块已从发行版中移除
2,主机联通性测试
绿色:执行成功并且不需要做出任何改变
黄色:执行成功并且对目标主机做出变更
红色:执行失败
蓝色:显示详细过程
紫色:显示警告
总结
1.ansible****运行临时命令**
语法:ansible 主机或组 -m 模块名 -a '模块参数(参数为键值对模式)' -i 清单文件
2.如何获取有哪些模块
ansible-doc -l
3.模块帮助
3.1参数帮助
ansible-doc -s modname
ansible-doc user (更加全面)
二,ansible的三个命令模块
- command
- shell
- raw
应尽量避免使用这三个模块来执行命令,因为其他模块大部分都是幂等性的,可以自动进行更改跟踪。command、shell、raw不具备幂等性(一个操作执行第二次会报错)。注: 幂等性:简单来讲,就是输入相同,输出相同,无论多少次比如说,确认接口,如果传入订单号,返回确认OK,如果已经确认过了,再次调用确认接口,返回如果还是确认OK,那么这个接口就是满足幂等性.
1,command shell raw区别
command、shell模块:
相同点:要求受管主机上安装Python。
不同点:command可以在受管主机上执行shell命令,但是不支持环境变量和操作符
(例如 '|', '<','>', '&')
shell模块调用的/bin/sh指令执行。
raw模块:
不需要受管主机上安装Python,直接使用远程shell运行命令,通常用于无法安装Python的系统(例如网络设备等)。
2,command模块
1,command模块参数
名称 | 必选 | 备注 |
chdir | no | 运行command命令前先cd到这个目录 |
creates | no | 如果这个参数对应的文件存在,就不运行command |
free_form | yes | 需要执行的脚本(没有真正的参数为free_form) |
executable | no | 改变用来执行命令的shell,应该是可执行文件的绝对路径。 |
removes | no | 如果这个参数对应的文件不存在,就不运行command,与creates参数的作用相反 |
stdin(2.4后新增) | no | 将命令的stdin设置为指定的值 |
free_form参数 :必选参数,指定需要远程执行的命令。需要说明一点,free_form 参数与其他参数(如果想要使用一个参数,那么则需要为这个参数赋值,也就是name=value模式)并不相同。比如,当我们想要在远程主机上执行 ls 命令时,我们并不需要写成”free_form=ls” ,这样写反而是错误的,因为并没有任何参数的名字是 free_form,当我们想要在远程主机中执行 ls 命令时,直接写成 ls 即可。因为 command 模块的作用是执行命令,所以,任何一个可以在远程主机上执行的命令都可以被称为 free_form
2,command模块案例
(1)首先创建模块目录
[student1@server ~]$ mkdir /mod_test
(2)在/mod_test/目录下面创建主机清单文件inventory
[student1@server mod_test]$ touch inventory
编辑inventory文件
[test1]
node1
[test2]
node2
[test:children]
test1
test2
(3)在/mod_test目录下面创建ansible.cfg文件
[student1@server mod_test]$ touch ansible.cfg
编辑/mod_test目录下面的ansible.cfg文件
[defaults]
inventory=/mod_test/inventory
host_key_checking=false
#remote_user=student1
[privilege_escalation]
become=true
become_method = sudo
become_user = root
become_ask_pass=false
(4)此时默认匹配到的ansible配置文件为当前目录下的ansible.cfg文件
[student1@server mod_test]$ ansible --version
(5)以图形化的方式查看inventory文件
[student1@server mod_test]$ ansible-inventory --graph
列出指定目录下的文件
(1)chdir:执行command命令前会先cd到这个目录
在node1主机上执行ls命令的前提是切换到/目录下,即查看主机node1根目录下所有文件
[student1@server mod_test]$ ansible node1 -m command -a 'ls chdir=/'
(2)creates:如果这个参数对应的文件存在,就不运行command
如果/test存在,那么不执行ls /root命令;/test文件不存在,执行ls /root命令
显然,/test文件不存在 ls /root命令执行成功,结果如下
[student1@server mod_test]$ ansible node1 -m command -a 'ls /root creates=/test'
/root文件存在,不执行前面的ls /root命令
[student1@server mod_test]$ ansible node1 -m command -a 'ls /root creates=/root'
(3)removes:如果这个参数对应的文件不存在,就不运行command,与creates参数的作用相反
/root文件存在 执行前面的ls /root命令,执行后的结果如下所示:
[student1@server mod_test]$ ansible node1 -m command -a 'ls /root removes=/root'
/test文件不存在,不执行前面的ls /root命令
[student1@server mod_test]$ ansible node1 -m command -a 'ls /root removes=/test'
(4)command模块无法执行带有> >> | & 等符号的命令通配符,逻辑符
如果/bin文件存在,则在把123写入到文件/file中,但command命令无法识别重定向符号,只能识别echo命令,所以执行结果为打印 123 > file
[student1@server mod_test]$ ansible node1 -m command -a 'echo 123 > file chdir=/ removes=/bin'
3,shell模块
让远程主机在shell进程下执行命令,从而支持shell的特性,如管道等。与command模块几乎相同,但在执行命令的时候使用的是/bin/sh。
1,shell模块的参数
名称 | 必选 | 备注 |
chdir | no | 运行command命令前先cd到这个目录 |
creates | no | 如果这个参数对应的文件存在,就不运行command |
executable | no | 改变用来执行命令的shell,应该是可执行文件的绝对路径。 |
free_form | yes | 需要执行的脚本(没有真正的参数为free_form) |
removes | no | 如果这个参数对应的文件不存在,就不运行command,与creates参数的作用相反 |
stdin(2.4后新增) | no | 将命令的stdin设置为指定的值 |
2,shell模块案例
shell模块除了能执行和command模块相同的命令之外,还可以执行带有> >> | & 等符号的命令;通配符,逻辑符
(1)在控制端主机node1上,如果/root文件存在,切换到根目录,打印当前目录,并列出当前目录下的所有文件;可以看出/root文件存在,当前目录下的所有文件被列出。
[student1@server mod_test]$ ansible node1 -m shell -a 'pwd & ls chdir=/ removes=/root'
(2)若/bin文件存在,在node1主机上的/file文件中写入123
[student1@server mod_test]$ ansible node1 -m shell -a 'echo 123 > file chdir=/ removes=/bin'
/bin文件存在,查看node1主机上的/file文件,123被写入
[root@node1 ~]# cat /file
(3)如果/test文件不存在,则不执行前面的ls /root命令;
[student1@server mod_test]$ ansible node1 -m shell -a 'ls /root removes=/test'
(4)如果/root文件存在,则执行前面的ls /root命令,执行结果如下所示
[student1@server mod_test]$ ansible node1 -m shell -a 'ls /root removes=/root'
4,script模块
1,script模块参数
名称 | 必选 | 备注 |
chdir(2.4后新增) | no | 运行command命令前先cd到这个目录 |
creates | no | 如果这个参数对应的文件存在,就不运行command |
decrypt | no | 此选项控制使用保管库的源文件的自动解密 |
free_form | yes | 需要执行脚本的本地文件路径(没有真正的参数为free_form) |
removes | no | 如果这个参数对应的文件不存在,就不运行command,与creates参数的作用相反 |
2,script模块案例
(1)在控制端的/mod_test下创建脚本a.sh
[student1@server mod_test]$ vim a.sh
echo $SHELL
date
(2)当/root文件存在时,执行/mod_test/a.sh文件,执行结果如下图所示
[student1@server mod_test]$ ansible node1 -m script -a '/mod_test/a.sh removes=/root'
5,raw模块
- raw模块主要用于执行一些低级的,脏的SSH命令,而不是通过command模块。
- raw模块只适用于下列两种场景,第一种情况是在较老的(Python 2.4和之前的版本)主机上,另一种情况是对任何没有安装Python的设备(如路由器)。 在任何其他情况下,使用shell或command模块更为合适。
- 就像script模块一样,raw模块不需要远程系统上的python
1,raw模块参数
名称 | 必选 | 备注 |
executable | no | 改变用来执行命令的shell,应该是可执行文件的绝对路径。 |
free_form | yes | 需要执行的脚本(没有真正的参数为free_form) |
三,文件操作模块
1,file模块
1,模块参数
file模块可以帮助我们完成一些对文件的基本操作,比如,创建文件或目录、删除文件或目录、修改文件权限等
- path参数 :必须参数,用于指定要操作的文件或目录,在之前版本的ansible中,使用dest参数或者name参数指定要操作的文件或目录,为了兼容之前的版本,使用dest或name也可以。
- state参数 :Path=“路径” state= touch|directory|link|hard|absent
- 此参数非常灵活,此参数对应的值需要根据情况设定,比如,当我们需要在远程主机中创建一个目录的时候,我们需要使用path参数指定对应的目录路径,假设,我想要在远程主机上创建/testdir/a/b目录,那么我则需要设置path=/testdir/a/b,但是,我们无法从"/testdir/a/b"这个路径看出b是一个文件还是一个目录,ansible也同样无法单单从一个字符串就知道你要创建文件还是目录,所以,我们需要通过state参数进行说明
- src参数 :当state设置为link或者hard时,表示我们想要创建一个软链或者硬链,所以,我们必须指明软链或硬链链接的哪个文件,通过src参数即可指定链接源。
- force参数 : 当state=link的时候,可配合此参数强制创建链接文件,当force=yes时,表示强制创建链接文件,不过强制创建链接文件分为两种情况,情况一:当你要创建的链接文件指向的源文件并不存在时,使用此参数,可以先强制创建出链接文件。情况二:当你要创建链接文件的目录中已经存在与链接文件同名的文件时,将force设置为yes,回将同名文件覆盖为链接文件,相当于删除同名文件,创建链接文件。情况三:当你要创建链接文件的目录中已经存在与链接文件同名的文件,并且链接文件指向的源文件也不存在,这时会强制替换同名文件为链接文件。
- owner参数 :用于指定被操作文件的属主,属主对应的用户必须在远程主机中存在,否则会报错。
- group参数 :用于指定被操作文件的属组,属组对应的组必须在远程主机中存在,否则会报错。
- mode参数:用于指定被操作文件的权限,比如,如果想要将文件权限设置为"rw-r-x---",则可以使用mode=650进行设置,或者使用mode=0650,效果也是相同的,如果你想要设置特殊权限,比如为二进制文件设置suid,则可以使用mode=4700,很方便吧。
- recurse参数:当要操作的文件为目录,将recurse设置为yes,可以递归的修改目录中文件的属性。 -R
- setype: httpd_content_t
2,file模块案例:
(1)在控制端主机server的root用户创建day03目录,并在day03目录下创建mod_test目录,在mod_test目录下创建ansible.cfg文件,inventory文件
创建目录
[root@server ~]# mkdir /day03/mod_test/ -pv
创建ansible.cfg配置文件
[root@server ~]# cp /etc/ansible/ansible.cfg /day03/mod_test/
[root@server ~]# cat /day03/mod_test/ansible.cfg
修改ansible.cfg配置文件的内容
[defaults]
#指定自定义主机清单文件
inventory = /day03/mod_test/inventory
#每次指向ansible命令不需要询问ssh密码
ask_pass = False
#不需要验证主机秘钥
host_key_checking = False
编辑inventory主机清单文件
[root@server mod_test]# vim inventory
[web]
node1
[dns]
node2
[server]
node1
node2
查看此时匹配到的主机清单文件为/day03/mod_test/ansible.cfg
[root@server mod_test]# ansible --version
测试免密登录是否成功
[root@server mod_test]# ssh node1 hostname
[root@server mod_test]# ssh node2 hostname
(2)在node1主机的根目录下创建一个file.txt文件,指定文件的所属者与所属组均为redhat,权限设置为0000
[root@server mod_test]# ansible web -m file -a 'path=/file.txt state=touch owner=redhat group=redhat mode=0000'
在node1主机上查看创建的文件/file.txt,其权限为0000,属者与所属组均为redhat
[root@node1 ~]# cd /
[root@node1 /]# ls -l
再次执行上述的ansible命令,虽然file.txt文件已经存在,但并不会报错,因为file模块具有幂等性,会更新file文件的时间戳。
2,在node1主机的根目录下创建一个test目录,指定目录的所属者与所属组均为root,权限设置为777
[root@server mod_test]# ansible web -m file -a 'path=/test state=directory owner=root group=root mode=777'
在主机node1下查看创建的目录
[root@node1 /]# ls -l
再次执行ansible的命令,虽然server主机不会报错,但是node1主机上不会执行任何操作
3,在node1主机的根目录下创建一个软链接文件file.lnk,软链接的源文件为/file.txt,如果软链接已经存在,强制覆盖
[root@server mod_test]# ansible web -m file -a 'name=/file.lnk src=/file.txt state=link force=yes'
在主机node1下查看创建的软链接文件
[root@node1 /]# ll
4,在node1主机的根目录下删除软链接文件/file.lnk
[root@server mod_test]# ansible web -m file -a 'name=/file.lnk state=absent'
此时查看node1主机的根目录,软链接文件/file.lnk已经被删除
[root@node1 /]# ls -l
2,copy模块
1,copy模块参数
见名知义,copy模块的作用就是拷贝文件,它与fetch模块类似,不过,fetch模块是从远程主机中拉取文件到ansible主机,而copy模块是将ansible主机上的文件拷贝到远程主机中。
- src参数 :用于指定需要copy的文件或目录
- dest参数 :用于指定文件将被拷贝到远程主机的哪个目录中,dest为必须参数
- content参数 :当不使用src指定拷贝的文件时,可以使用content直接指定文件内容,src与content两个参数必有其一,否则会报错。
- force参数 : 当远程主机的目标路径中已经存在同名文件,并且与ansible主机中的文件内容不同时,是否强制覆盖,可选值有yes和no,默认值为yes,表示覆盖,如果设置为no,则不会执行覆盖拷贝操作,远程主机中的文件保持不变。
- backup参数 : 当远程主机的目标路径中已经存在同名文件,并且与ansible主机中的文件内容不同时,是否对远程主机的文件进行备份,可选值有yes和no,当设置为yes时,会先备份远程主机中的文件,然后再将ansible主机中的文件拷贝到远程主机。
- owner参数 : 指定文件拷贝到远程主机后的属主,但是远程主机上必须有对应的用户,否则会报错。
- group参数 : 指定文件拷贝到远程主机后的属组,但是远程主机上必须有对应的组,否则会报错。
- mode参数 : 指定文件拷贝到远程主机后的权限,如果你想将权限设置为"rw-r--r--",则可以使用mode=0644表示,如果你想要在user对应的权限位上添加执行权限,则可以使用mode=u+x表示。
2,copy模块示例:
复制(覆盖)force=yes
(1)将server主机中/a文件复制到远程主机node1的根目录下,注意,如果a文件已经存在于远程主机的根目录中,并且远程主机node1中的a文件与server主机中a文件内容不同,那么使用如下命令时,远程主机中的a文件将被覆盖。
在远程主机node1下的根目录查看文件a的内容
[root@node1 /]# cat a
在控制端主机server下的根目录查看文件a的内容
[root@server /]# cat a
将server主机的/a复制到node1主机/a,覆盖node1主机/a的内容
[root@server mod_test]# ansible web -m copy -a "src=/a dest=/a force=yes"
此时在node1主机上查看根目录下的a文件,已经被覆盖
[root@node1 /]# cat a
复制(不覆盖) force=no
(2)将server主机中/a文件复制到远程主机node1的根目录下,注意,如果a文件已经存在于远程主机的根目录中,并且远程主机node1中的a文件与server主机中a文件内容不同,那么使用如下命令时,远程主机中的a文件不会被覆盖。
远程主机node1上的a文件的内容如下所示
[root@node1 /]# cat a
控制端主机server的a文件的内容如下所示
[root@server mod_test]# cat /a
将server主机的/a复制到node1主机/a;ansible命令执行成功,但是不在node1主机上做任何改变
[root@server mod_test]# ansible web -m copy -a "src=/a dest=/a force=no"
此时在node1主机查看a文件,文件内容并没有做任何改变
[root@node1 /]# cat a
创建文件编辑内容 content
(3)在远程主机node1的根目录下生成文件file.txt,file.txt文件中有两行文本,第一行文本为aaa,第二行为bbb,当使用content指定文件内容时,dest参数对应的值必须是一个文件,而不能是一个路径。(注意:content为重定向,会覆盖,不是追加)
[root@server mod_test]# ansible web -m copy -a 'dest=/file.txt content="aaa \n bbb \n"'
此时在node1主机上查看文件file.txt的内容,与ansible命令编辑的内容一致
[root@node1 /]# cat /file.txt
文件存在备份源文件在复制 backup=yes
(4)将server主机中/a文件复制到远程主机的根目录中时,如果远程主机中已经存在/a文件,并且文件内容与server主机中的/a文件的内容不一致,会执行拷贝操作,但是在执行拷贝操作之前,会将远程主机node1中的原文件重命名,以作备份,然后再进行拷贝操作。
此时node1主机的a文件的内容如下所示
[root@node1 /]# cat a
控制端主机server的a文件的内容如下所示,与node1主机a文件内容不一致
[root@server mod_test]# cat /a
复制内容前先备份
[root@server mod_test]# ansible web -m copy -a 'dest=/ src=/a backup=yes'
此时查看,从server主机复制过去的文件为/a ;备份的文件为/a.6756.2023-03-17@10:28:19~
[root@node1 /]# ll
在node1上查看备份文件a.6756.2023-03-17@10:28:19~的内容如下所示
[root@node1 /]# cat a.6756.2023-03-17@10:28:19~
在node1上查看从server主机上拷贝过来的文件,内容与server主机上的内容一致
[root@node1 /]# cat a
复制文件指定文件属主属组权限 owner group mode
(5)把server主机上的a文件拷贝到node1主机上,指定文件的所属者与所属组,文件权限为777,
远程主机上必须存在对应的所属者与所属组
[root@server mod_test]# ansible web -m copy -a 'src=/a dest=/a force=yes owner=root group=root mode=777'
在node1主机上查看a文件的所属者与所属组以及文件权限,与ansible命令指定的一致
[root@node1 /]# ll
3,fetch 模块
1,fetch模块参数
拉取远程主机的文件,并以主机IP地址或者主机名为目录,并保留了原来的目录结构 常用选项:
- dest 目标地址
- src 源
- flat yes 不按照src的目录来创建目录,flat为no就在当前路径创建和src一样的目录路径
2,fetch模块案例
(1)按照指定的路径从被管理节点上拷贝文件到控制节点
把node1主机上的/a.6756.2023-03-17@10:28:19~拉取到server主机上的根目录下
[root@server mod_test]# ansible web -m fetch -a 'src=/a.6756.2023-03-17@10:28:19~ dest=/ flat=yes'
在主机server上的根目录下面查看拉去过来的文件
[root@server mod_test]# ll /
2,按照默认的路径从被管理节点上拷贝文件到控制节点
主机node1上的根目录下的b文件内容如下
[root@node1 ~]# cat /b
把node1主机上的/b文件拉取到server主机上的默认路径/node1/b
[root@server mod_test]# ansible web -m fetch -a 'src=/b dest=/ flat=no'
在控制端主机server上默认目录下查看从node1主机上拉取过来的文件b
[root@server mod_test]# cat /node1/b
4, synchronize 模块
1,synchroniza模块参数
synchronize 基于rsync命令批量同步文件做这个模块的时候,必须保证远程服务器上有rsync这个命令
常用选项:
- src:源文件
- dest: 目标文件
- archive : 是否采用归档模式同步,保证源文件和目标文件属性一致 rsync_opts : 使用rsync参数
- --exclude=*.log : 此处为忽略.log结尾的文件, 必须和rsync_opts使用例(rsync_opts=--exclude=.txt)
- delete: 删除不存在的文件,默认no
- Pull 拉 push 推
- 注意:mode默认为push推,要拉取到主控节点,需要配置mode为pull拉
[root@master ~]# ansible all -m yum -a 'name=rsync state=present' 如果没有rsync先安装
2,synchronize模块案例
此时在控制端主机server上的/n1目录下面有a,b,c三个文件
[root@server ~]# ll /n1
此时在控制端主机node1的目录/n1下面有1,2,3,4,5五个文件
[root@node1 ~]# ll /n1
pull拉取
(1)将node1 节点的/n1 目录下的文件复制到主控节点server的/n1 目录下
[root@server ~]# ansible node1 -m synchronize -a 'src=/n1/ dest=/n1 mode=pull'
此时查看控制端主机server的/n1目录下的文件,发现受控端主机node1下的文件已经复制到了控制端主机server的/n1目录下
[root@server ~]# ll /n1
Push 推送
(2)将控制端主机server目录下的所有文件同步到node1主机的/n1目录
此时控制端主机server/n1目录下的文件如下所示:
[root@server ~]# ll /n1
受控端主机node1/n1目录下的文件如下所示:
[root@node1 ~]# ll /n1
[root@server ~]# ansible node1 -m synchronize -a 'src=/n1/ dest=/n1 mode=push '
[root@node1 ~]# ll /n1
(3)Delete 删除同步过去不存在的文件
此时server主机/n1下的文件如下所示:
[root@server ~]# ll /n1
node1主机/n1目录下的文件如下所示:
[root@node1 ~]# ll /n1
将server主机/n1目录下的文件同步到node1主机/n1目录下
[root@server ~]# ansible node1 -m synchronize -a 'src=/n1/ dest=/n1 mode=push delete=yes archive=yes'
同步后node1主机/n1目录下的文件如下所示
[root@node1 ~]# ll /n1
5,blockinfile模块
1,blockinfile模块参数
blockinfile模块可以帮助我们在指定的文件中插入"一段文本",这段文本是被标记过的,换句话说就是,我们在这段文本上做了记号,以便在以后的操作中可以通过"标记"找到这段文本,然后修改或者删除它.
参数:
- path参数 :必须参数,指定要操作的文件。
- block参数 :此参数用于指定我们想要操作的那"一段文本",此参数有一个别名叫"content",使用content或block的作用是相同的。
- marker参数 :假如我们想要在指定文件中插入一段文本,ansible会自动为这段文本添加两个标记,一个开始标记,一个结束标记,默认情况下,开始标记为# BEGIN ANSIBLE MANAGED BLOCK,结束标记为# END ANSIBLE MANAGED BLOCK,我们可以使用marker参数自定义"标记",比如,marker=#{mark}test ,这样设置以后,开始标记变成了# BEGIN test,结束标记变成了# END test,没错,{mark}会自动被替换成开始标记和结束标记中的BEGIN和END,我们也可以插入很多段文本,为不同的段落添加不同的标记,下次通过对应的标记即可找到对应的段落。
- state参数 : state参数有两个可选值,present与absent,默认情况下,我们会将指定的一段文本"插入"到文件中,如果对应的文件中已经存在对应标记的文本,默认会更新对应段落,在执行插入操作或更新操作时,state的值为present,默认值就是present,如果对应的文件中已经存在对应标记的文本并且将state的值设置为absent,则表示从文件中删除对应标记的段落。
- insertafter参数 :在插入一段文本时,默认会在文件的末尾插入文本,如果你想要将文本插入在某一行的后面,可以使用此参数指定对应的行,也可以使用正则表达式(python正则),表示将文本插入在符合正则表达式的行的后面,如果有多行文本都能够匹配对应的正则表达式,则以最后一个满足正则的行为准,此参数的值还可以设置为EOF,表示将文本插入到文档末尾。
- insertbefore参数 :在插入一段文本时,默认会在文件的末尾插入文本,如果你想要将文本插入在某一行的前面,可以使用此参数指定对应的行,也可以使用正则表达式(python正则),表示将文本插入在符合正则表达式的行的前面,如果有多行文本都能够匹配对应的正则表达式,则以最后一个满足正则的行为准,此参数的值还可以设置为BOF,表示将文本插入到文档开头。
- backup参数 :是否在修改文件之前对文件进行备份。
- create参数 :当要操作的文件并不存在时,是否创建对应的文件。
2,blockinfile模块案例
此时受控主机node1的/file文件中有如下内容
[root@node1 ~]# cat /file
Insertbefore=BOF 文本首部
(1)在受控端主机node1的/file文件首部插入如下两行
hello world
hello china
[root@server mod_test]# ansible web -m blockinfile -a 'path=/file insertbefore=BOF block="hello world\nhello china"'
在受控端主机/node1上查看插入后的/file文件
[root@node1 ~]# cat /file
market insertafter=EOF 文本末尾
(2)在受控端主机node1的/file文件尾部插入信息Welcome to china并自定义标记new line
此时受控主机node1的/file文件中有如下内容
[root@node1 ~]# cat /file
文件末尾插入信息
[root@server mod_test]# ansible web -m blockinfile -a 'path=/file insertafter=EOF block="welcome to china" marker="#{mark} new line"'
此时在受控端主机/node1上查看file文件,内容如下
[root@node1 ~]# cat /file
(3)当文本块标记已存在,但再次编辑块内容,会对之前的块内容进行修改
在2的基础上在给受控端主机node1的/file文件尾部插入信息hi china并自定义标记message
[root@server mod_test]# ansible web -m blockinfile -a 'path=/file insertafter=EOF block="hi china" marker="#{mark} message"'
此时node1主机上的文本块的内容被更新为如下文本
[root@node1 ~]# cat /file
(4)删除对应标记文本块,把标记对应的文本块设为空
此时的文件/file如下所示
[root@node1 ~]# cat /file
删除文件/file中标记为#END new line的文本块内容
[root@server mod_test]# ansible web -m blockinfile -a 'path=/file insertafter=EOF block=" " marker="#{mark} new line"'
删除后此时查看文本内容更新如下所示:
[root@node1 ~]# cat /file
(5)删除对应标记,state=absent
[root@server mod_test]# ansible web -m blockinfile -a 'path=/file insertafter=EOF block=" " marker="#{mark} new line" state=absent'
删除后此时查看文本内容更新如下所示:
[root@node1 ~]# cat /file
(6)使用正则表达式匹配行
1,如果插入的新标记和旧标记重复,那么新插入的块内容覆盖旧块的内容
此时的/file文件如下所示:
用hi world覆盖hi china
[root@server mod_test]# ansible web -m blockinfile -a 'path=/file insertafter="^hi" block="hi world " marker="#{mark} message" '
覆盖后的文件如下所示
[root@node1 ~]# cat /file
2,正则表达式匹配时,在新标记中的块中插入内容
用正则表达式匹配以second line结尾的行并在this is first second line前面插入标记为tag的this is end lind内容
[root@server mod_test]# ansible web -m blockinfile -a 'path=/file insertbefore="second line$" block="this is end line " marker="#{mark} tag" '
更新后的文件如下所示
[root@node1 ~]# cat /file
(7)使用backup参数,可以在操作修改文件之前,对文件进行备份,备份的文件会在原文件名的基础上添加时间戳
删除标记tag以及标记tag中的块信息
[root@server mod_test]# ansible web -m blockinfile -a 'path=/file block=" " marker="#{mark} tag" state=absent backup=yes'
删除后的文件如下所示:
备份的文件如下所示:
[root@node1 ~]# cat /file.7539.2023-03-17@18:55:44~
(8)使用create参数,如果指定的文件不存在,则创建它,
受控端主机node1下面没有文件c
[root@node1 ~]# ll /
在受控端主机node1上的/c文件中打上smile的标记并在块中写入happy every day信息
[root@server mod_test]# ansible web -m blockinfile -a 'path=/c block="happy everyday " marker="#{mark} amile" create=yes'
此时在node1主机上查看/c文件,发现c文件已经被创建且有内容
[root@node1 ~]# cat /c
6,lineinfile模块
1,lineinfile模块参数
lineinfile模块,确保"某一行文本"存在于指定的文件中,或者确保从文件中删除指定的"文本"(即确保指定的文本不存在于文件中),还可以根据正则表达式,替换"某一行文本"。
- path参数 :必须参数,指定要操作的文件。
- line参数 : 使用此参数指定文本内容。
- regexp参数 :使用正则表达式匹配对应的行,当替换文本时,如果有多行文本都能被匹配,则只有最后面被匹配到的那行文本才会被替换,当删除文本时,如果有多行文本都能被匹配,这么这些行都会被删除。
基本正则表到式
- state参数:当想要删除对应的文本时,需要将state参数的值设置为absent,absent为缺席之意,表示删除,state的默认值为present
- backrefs参数:默认情况下,当根据正则替换文本时,即使regexp参数中的正则存在分组,在line参数中也不能对正则中的分组进行引用,除非将backrefs参数的值设置为yes,backrefs=yes表示开启后向引用,这样,line参数中就能对regexp参数中的分组进行后向引用了。backrefs=yes开启后向引用功能。
另一个作用,使用正则表达式替换对应行时,如果正则没有匹配到任何的行,那么line对应的内容会被插入到文本的末尾,不过,如果使用了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参数 :当要操作的文件并不存在时,是否创建对应的文件。
2, lineinfile模块案例
我们使用/c文件作为被操作的文件,c文件内容如下
[root@node1 ~]# cat /c
(1)插入内容。 判断文件中####haha####内容是否存在,不存在则在文档尾插入该内容
[root@server mod_test]# ansible web -m lineinfile -a 'path=/c line="####haha####" '
更新后的c文件如下所示
[root@node1 ~]# cat /c
如果####haha####内容已经存在,则文件c不做任何改变
[root@server mod_test]# ansible web -m lineinfile -a 'path=/c line="####haha####" '
(2)regexp支持正则符匹配可以将匹配的行进行替换,如果匹配到多行,替换最后一行
匹配以happy开始的行,如果匹配到,则用nice替换happy
[root@server mod_test]# ansible web -m lineinfile -a 'path=/c line="nice" regexp="^happy" '
匹配成功,更新后的文件c如下所示:
[root@node1 ~]# cat /c
再次匹配以happy开始的行,匹配不到,文件c不做任何改变
[root@server mod_test]# ansible web -m lineinfile -a 'path=/c line="nice" regexp="^happy" '
(3)匹配指定内容的行删除(若多行相同全部删除)
匹配####haha####行并删除
[root@server mod_test]# ansible web -m lineinfile -a 'path=/c state=absent regexp="^####haha" '
匹配成功,更新后的文件c如下所示:
[root@node1 ~]# cat /c
根据正则表达式删除对应行,如果有多行都满足正则表达式,那么所有匹配的行都会被删除
此时文件c的内容如下所示:
[root@node1 ~]# cat /c
匹配到以1开头的行并删除(regexp=^1或者line="123")
[root@server mod_test]# ansible web -m lineinfile -a 'path=/c state=absent regexp="^1" '
匹配成功,可以看到三行123都被删除
[root@node1 ~]# cat /c
7, archive模块打包压缩
1,archive模块打包压缩参数
path:表示要被压缩的文件的路径
dest:表示压缩后的文件路径
2,archive模块打包压缩案例
在控制端主机server上将受控端主机node1上的/c文件打包压缩为/c.gz格式
[root@server mod_test]# ansible web -m archive -a 'path=/c dest=/c.zip format=zip '
压缩后的文件如下所示:
8,unarchive解包解压缩
1,unarchive解包解压缩参数
参数:
- copy:1、将ansible主机上的压缩包传到远程主机后解压缩至特定目录,设置copy=yes (控制到远程)
- 2、将远程主机上的某个压缩包解压缩到指定路径下,设置copy=no(远程到远程)
- remote_src:和copy功能一样且互斥,yes表示在远程主机,不在ansible主机,no表示文件在ansible主机上
- src:源路径,可以是ansible主机上的路径,也可以是远程主机上的路径,如果是远程主机上的路径,则需要设置copy=no
- dest:远程主机上的目标路径
- mode:设置解压缩后的文件权限
- format: 设置压缩格式 bz2, gz, tar, xz, zip default=gz
2,unarchive解包解压缩案例
在控住端主机server将2.7中在node1主机上压缩的/c.zip解压在node1主机上的/unz目录下
[root@server mod_test]# ansible web -m unarchive -a 'src=/c.zip dest=/unz remote_src=yes '
解压后的文件如下所示:
[root@node1 ~]# ll /unz
四,计划任务
1,cron模块
1,cron模块参数
- backup:对远程主机上的原任务计划内容修改之前做备份
- cron_file:如果指定该选项,则用该文件替换远程主机上的cron.d目录下的用户的任务计划
- day:日(1-31,,/2,……)
- hour:小时(0-23,,/2,……)
- minute:分钟(0-59,,/2,……)
- month:月(1-12,,/2,……)
- weekday:周(0-7,*,……)
- job:要执行的任务,依赖于state=present
- name:该任务的描述
- special_time:指定什么时候执行,参数:reboot,yearly(每年),annually,(每年相当于yearly)monthly,weekly,daily,hourly
- state:确认该任务计划是创建还是删除
- user:以哪个用户的身份执行
#备份数据库脚本
2,cron模块案例
(1)#创建任务
此时的/cron文件为空
[root@node1 ~]# cat /cron
在控制端主机server操作受控端主机node1,定一个任务名为task,使其每1分钟向/cron文件输入"hello"
[root@server mod_test]# ansible node1 -m cron -a 'minute=*/1 job="echo hello >> /cron " state=present name=task'
此时在node1主机上可以查看到定时任务task
[root@node1 ~]# crontab -l
2分钟后查看/cron文件
[root@node1 ~]# cat /cron
(2)#禁用计划任务 disabled=yes
禁用任务task
[root@server mod_test]# ansible node1 -m cron -a 'minute=*/1 job="echo hello >> /cron " state=present name=task disabled=yes'
此时再次查看任务task 发现禁用后的任务前面多了一个#号,任务被注释掉,不会执行
[root@node1 ~]# crontab -l
(3)#启用计划任务 disabled=no
再次启用刚才的task任务
[root@server mod_test]# ansible node1 -m cron -a 'minute=*/1 job="echo hello >> /cron " state=present name=task disabled=no'
此时再次在受控端主机node1上查看任务,发现#消失,任务已被重新启动
[root@node1 ~]# crontab -l
查看文件/cron发现又多了几行信息,表示任务正常执行
[root@node1 ~]# cat /cron
(4) #删除任务 state=absent
(使用crontab -r 可以删除未命名的任务,不是命名为空)
删除task任务
[root@server mod_test]# ansible node1 -m cron -a 'minute=*/1 job="echo hello >> /cron " state=present name=task state=absent'
在node1主机上查看任务,发现为空,任务task成功被删除
[root@node1 ~]# crontab -l
五,用户管理
1,user模块
1,user模块选项
user模块实现用户账号管理。
常用选项:
- name=:用户名
- uid:用户的uid
- group:所属组,即私有组
- groups:附加组。
- state:状态。
- remove:是否删除家目录 yes no
- password: 给指定用户输入加密后的密码
2,user模块案例
(1)在受控端主机node1上创建用户tom,密码为123456
首先可以使用python的crypt命令来生成一个密码, 因为 ansible user 的 password 参数需要接受加密后的值
打开python,导入crypt
[root@server mod_test]# python3
>>> import crypt
给123456加密,密码要用引号引起来,exit()表示退出
>>> crypt.crypt('123456')
'$6$b1af0Q2BmI8qGrGL$8Qwuh5QouL6tpQ/y0Zr.AgQKbnoG2P4fE88Fu.UDE3fBNWbAanElxDggv6D/DuPxDVPrpAtoB0EFXRg/6J1/w/'
创建用户名为tom,密码为123456的用户
[root@server mod_test]# ansible node1 -m user -a 'name=tom password="$6$b1af0Q2BmI8qGrGL$8Qwuh5QouL6tpQ/y0Zr.AgQKbnoG2P4fE88Fu.UDE3fBNWbAanElxDggv6D/DuPxDVPrpAtoB0EFXRg/6J1/w/"'
在node1主机上对tom用户进行验证登录
[redhat@node1 ~]$ su - tom
可以看到tom用户的家目录为/home/tom
[tom@node1 root]$ cd ~
[tom@node1 ~]$ pwd
(2)删除tom用户,连同家目录一起
[root@server mod_test]# ansible node1 -m user -a 'name=tom state=absent remove=yes'
在受控端主机上查看tom用户和家目录,已经被删除
[root@node1 ~]# id tom
[root@node1 ~]# ll /home/tom
(3)创建用户bob,指定附加组为redhat
[root@server mod_test]# ansible node1 -m user -a 'name=bob groups=redhat'
查看组信息,可以看到bob的附加组为redhat
[root@node1 ~]# cat /etc/group
(4)为bob用户生成密钥对,生成的秘钥文件存储在/home/bob/.ssh/id_rsa
[root@server ~]# ansible node1 -m user -a 'name=bob generate_ssh_key=yes ssh_key_bits=2048 ssh_key_file=/home/bob/.ssh/id_rsa'
在受控端主机node1上可以查看到秘钥文件
[root@node1 ~]# cat /home/bob/.ssh/id_rsa
2,group模块
1, group 模块选项
选项:
- name参数:必须参数,用于指定要操作的组名称。
- state参数:用于指定组的状态,两个值可选,present,absent,默认为present,设置为absent 表示删除组。
- gid参数:用于指定组的gid。
- system参数:系统组。
2,group 模块案例
在受控端主机node1上创建一个组名为ansible,组id为1010的组
[root@server ~]# ansible node1 -m group -a 'name=ansible state=present gid=1010'
在受控端主机node1上查看创建的ansible组,组id为1010
[root@node1 ~]# tail -5 /etc/group