Ansible模块3¶
一. lineinfile模块¶
1. 简介¶
ansible在使用sed进行替换的时候,经常会遇到需要转义的问题。这时候ansible在遇到特殊符号进行替换存在问题可能无法正常进行替换。这时候我们就需要ansible自身提供的两个模块 --- lineinfile模块和replace模块
一般来说,ansible当中修改某个文件的单行进行替换时使用lineinfile模块
2. 核心参数¶
path: 必填,要操作文件的路径
regexp: 使用正则表达式匹配对应的行。
当替换文本时,如果有多行文本都能被匹配,则只有最后面被匹配到的那行文本才能被替换
当删除文本时,如果有多行文本都能被匹配,则所有能被匹配到的行都会被替换
如果项进行多行匹配替换需要使用replace模块
line: 要写入的新行内容(替换匹配行,没匹配到就按位置插入)
state: 状态
present: 默认选项,确保行在
absent: 删除所有匹配regexp的行
insertafter/insertbefore: 没匹配到时,插到哪里(insertafter=EOF(默认)/EOF/匹配行)
create: 文件不存在时是否创建,默认为no
3. 命令格式¶
lineinfile模块在ansible使用时,标准的写法是
ansible <目标主机> -m lineinfile -a '属性1=值1' '属性2=值2' ... 属性n=值n
4. 实践¶
1) 将指定文件匹配到的内容进行行替换¶
a. 准备文件
[root@1 ~]# ansible -m copy -a "content='server {\n listen 8080;\n}' dest=/tmp/nginx_test.conf" web_servers1
2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"checksum": "3968e4d34e4490b9a1517ceca3537a1aaff23f66",
"dest": "/tmp/nginx_test.conf",
"gid": 0,
"group": "root",
"md5sum": "e03834d61c749f1ca8da4a1217bc6383",
"mode": "0644",
"owner": "root",
"secontext": "unconfined_u:object_r:admin_home_t:s0",
"size": 24,
"src": "/root/.ansible/tmp/ansible-tmp-1786879818.2770197-1623-184718525988738/source",
"state": "file",
"uid": 0
}
# 查看文件内容
[root@1 ~]# ansible -m shell -a "cat /tmp/nginx_test.conf" web_servers1
2 | CHANGED | rc=0 >>
server {
listen 8080;
}
b. 将指定文件进行"行替换"
[root@1 ~]# ansible -m lineinfile -a "path=/tmp/nginx_test.conf regexp='listen' line=' listen80'" web_servers1
2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"backup": "",
"changed": true,
"msg": "line replaced"
}
# 查看效果
[root@1 ~]# ansible -m shell -a "cat /tmp/nginx_test.conf" web_servers1
2 | CHANGED | rc=0 >>
server {
listen80
}
2) 将指定文件匹配到内容进行删除¶
[root@1 ~]# ansible -m lineinfile -a "path=/tmp/nginx_test.conf regexp='listen80' state=absent" web_servers1
2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"backup": "",
"changed": true,
"found": 1,
"msg": "1 line(s) removed"
}
查看验证
[root@1 ~]# ansible -m shell -a "cat /tmp/nginx_test.conf" web_servers1
2 | CHANGED | rc=0 >>
server {
}
二. replace模块¶
1. 简介¶
replace模块相较于lineinfile模块来说,更倾向于sed命令的操作,尤其是多行匹配进行替换
2. 命令格式¶
replace模块在ansible使用时,标准的写法是
ansible <目标主机> -m replace -a '属性1=值1 属性2=值2 ... 属性n=值n'
3. 常见参数¶
path: 文件路径
regexp: 匹配要替换的字符串本身,不会进行整行替换
replace: 指定替换后的字符
after/before: 只在指定锚点之后/之前进行替换
backup/validate: 备份/校验
4. 准备测试文件¶
准备测试文件
[root@1 ~]# ansible -m shell -a "grep default /etc/fstab >> /tmp/fstab ; cat /tmp/fstab" web_servers1
2 | CHANGED | rc=0 >>
/dev/mapper/rl-root / xfs defaults 0 0
UUID=0530d8e4-6a96-4c29-a3cd-66607d24bd3a /boot xfs defaults 0 0
/dev/mapper/rl-home /home xfs defaults 0 0
/dev/mapper/rl-swap none swap defaults 0 0
将文件内容进行多行匹配替换
[root@1 ~]# ansible -m replace -a "path=/tmp/fstab regexp='(defau.*)' replace='#\1'" web_servers1
2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"msg": "4 replacements made",
"rc": 0
}
查看效果
[root@1 ~]# ansible -m shell -a "cat /tmp/fstab" web_servers1
2 | CHANGED | rc=0 >>
/dev/mapper/rl-root / xfs #defaults 0 0
UUID=0530d8e4-6a96-4c29-a3cd-66607d24bd3a /boot xfs #defaults 0 0
/dev/mapper/rl-home /home xfs #defaults 0 0
/dev/mapper/rl-swap none swap #defaults 0 0
再替换回去
[root@1 ~]# ansible -m replace -a "path=/tmp/fstab regexp='#(defau.*)' replace='\1'" web_servers1
2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"msg": "4 replacements made",
"rc": 0
}
# 查看效果
[root@1 ~]# ansible -m shell -a "cat /tmp/fstab" web_servers1
2 | CHANGED | rc=0 >>
/dev/mapper/rl-root / xfs defaults 0 0
UUID=0530d8e4-6a96-4c29-a3cd-66607d24bd3a /boot xfs defaults 0 0
/dev/mapper/rl-home /home xfs defaults 0 0
/dev/mapper/rl-swap none swap defaults 0 0
三. yum_repository模块¶
1. 简介¶
此模块用来对远程主机上的rpm包仓库进行管理。(注:也存在dnf_repository模块,但是需要额外按照)
2. 常见参数¶
name: 必填,仓库ID
description: 仓库描述
baseurl: 仓库地址(mirrorlist二选一)
mirrorlist: 镜像列表
file: 写入的
.repo文件名(默认用name,不需要带.repo后缀)enabled: 是否启用。
yes|nogpgcheck: 是否校验GPG。
yes|nogpgkey: 公钥URL
state: present(创建/更新)/absent(删除)
3. 实践¶
1) 添加镜像仓库¶
[root@1 ~]# ansible -m yum_repository -a "name=epel description='aliyunEPEL' baseurl='https://mirrors.aliyun.com/epel/\$releasever/Everything/\$basearch/' file=aliyunepel enabled=yes gpgcheck=no state=present" web_servers1
2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"repo": "epel",
"state": "present"
}
检查效果
[root@1 ~]# ansible -m shell -a "ls -l /etc/yum.repos.d/aliyunepel.repo;cat /etc/yum.repos.d/aliyunepel.repo" web_servers1
2 | CHANGED | rc=0 >>
-rw-r--r--. 1 root root 127 8月 17 10:00 /etc/yum.repos.d/aliyunepel.repo
[epel]
baseurl = https://mirrors.aliyun.com/epel/$releasever/Everything/$basearch/
enabled = 1
gpgcheck = 0
name = aliyunEPEL
2) 更新软件源¶
[root@1 ~]# ansible -m shell -a "dnf makecache" web_servers1
2 | CHANGED | rc=0 >>
aliyunEPEL 405 kB/s | 21 MB 00:52
Rocky Linux 9 - BaseOS 1.1 kB/s | 4.3 kB 00:04
Rocky Linux 9 - BaseOS 152 kB/s | 21 MB 02:21
Rocky Linux 9 - AppStream 1.9 kB/s | 4.8 kB 00:02
Rocky Linux 9 - AppStream 361 kB/s | 19 MB 00:55
Rocky Linux 9 - Extras 676 B/s | 3.1 kB 00:04
Rocky Linux 9 - Extras 7.5 kB/s | 17 kB 00:02
元数据缓存已建立。Repository epel is listed more than once in the configuration
3) 删除镜像仓库¶
[root@1 ~]# ansible -m yum_repository -a 'file=aliyunepel name=epel state=absent' web_servers1
2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"repo": "epel",
"state": "absent"
}
查看验证
[root@1 ~]# ansible -a "ls /etc/yum.repos.d/" web_servers1
2 | CHANGED | rc=0 >>
rocky-addons.repo
rocky-devel.repo
rocky-extras.repo
rocky.repo
此时我们会发现aliyunepel.repo没了
四. service模块¶
1. 简介¶
service模块主要适用于远程客户端各种服务管理,包括启动、停止、重启、重载等
2. 详细参数¶
name参数: 此参数用于指定需要操作的服务名称。比如nginx,httpd
state参数: 此参数用于指定服务的状态。比如我们想要启动远程主机的httpd,就可以将state的值设置为started;如果想要停止远程主机中的服务,则可以将state的值设置为stopped。
started: 启动服务
stopped: 停止服务
restarted: 重启服务
reloaded: 重新加载服务
enabled参数: 此参数用于指定是否将服务设置为开机自启动。设置为yes表示将对应的服务设置为开机自启动,设置为no表示不会开机启动
runlevel参数: 服务启动级别
arguments参数: 服务命令行参数传递
注: 想使用service模块启动服务,被启动的服务必须可以使用service命令启动或者关闭
3. 命令格式¶
service模块在ansible使用时,标准的写法是
ansible <目标主机> -m servoce -a '属性1=值1 属性2=值2 ... 属性n=值n'
4. 实践¶
1) 查看已安装的软件¶
[root@1 ~]# ansible -m dnf -a "name=httpd state=present" web_servers1
2 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"msg": "Nothing to do",
"rc": 0,
"results": []
}
2) 设置开机自启动¶
[root@1 ~]# ansible -m service -a "name=httpd enabled=yes" web_servers1
2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"enabled": true,
"name": "httpd",
...
检查效果
[root@1 ~]# ansible -a "systemctl is-enabled httpd" -o web_servers1
2 | CHANGED | rc=0 | (stdout) enabled
关闭开机自启动
[root@1 ~]# ansible -m service -a "name=httpd enabled=false" web_servers1
2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"enabled": false,
"name": "httpd",
...
查看效果
[root@1 ~]# ansible -a "systemctl is-enabled httpd" web_servers1
2 | FAILED | rc=1 >>
disablednon-zero return code
3) 启动服务¶
[root@1 ~]# ansible -m service -a 'name=httpd state=started' web_servers1
2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"name": "httpd",
"state": "started",
...
检查效果
[root@1 ~]# ansible -m shell -a 'ss -tuanp|grep httpd' web_servers1
2 | CHANGED | rc=0 >>
tcp LISTEN 0 511 *:80 *:* users:(("httpd",pid=12651,fd=4),("httpd",pid=12650,fd=4),("httpd",pid=12649,fd=4),("httpd",pid=12647,fd=4))
4) 重启服务¶
[root@1 ~]# ansible -m service -a 'name=httpd state=restarted' web_servers1
2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"name": "httpd",
"state": "started",
...
5) 关闭服务¶
[root@1 ~]# ansible -m service -a 'name=httpd state=stopped' web_servers1
2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"name": "httpd",
"state": "stopped",
...
检查效果
[root@1 ~]# ansible -m shell -a 'ss -tuanp|grep httpd' web_servers1
2 | FAILED | rc=1 >>
non-zero return code
五. template模块¶
1. 简介¶
template模块用于把控制机上的Jinja2模板文件(.j2)渲染成目标主机的配置文件。适合"每台主机配置不一样"的场景(主机名、IP、端口等)。
它与copy模块的区别:
copy: 原样拷贝,所有主机内容一模一样
template: 按变量渲染,每台主机内容可以不同
注: Jinja2是Python的模板引擎库,不是ansible模块。ansible本身是Python写的,template模块内部就是调用Jinja2来渲染模板。所以我们只需要会写
{{ }}模板语法即可,不需要会写Python代码。
2. 常见参数¶
src: 必填。控制机上的
.j2模板文件路径dest: 必填。目标机上的最终文件路径
owner/group: 渲染后文件的属主/属组
mode: 渲染后文件的权限
backup: 覆盖前是否备份。默认no
validate: 渲染后先校验再落盘(如nginx写"nginx -t")
force: 内容变化时是否强制覆盖。默认yes
3. Jinja2模板语法(三种括号)¶
{{ 变量 }}: 输出变量值示例:
{{ ansible_hostname }}→ 输出该主机的主机名
{% 控制 %}: 逻辑控制(循环/判断)
{% for x in list %} ... {% endfor %}循环
{% if 条件 %} ... {% else %} ... {% endif %}判断
{# 注释 #}: 注释,不会输出过滤器
|: 对值做处理
{{ name | upper }}转大写
{{ my_var | default('默认值') }}变量为空时给默认值
{{ item | upper }}循环项转大写
模板中可以直接使用setup模块收集的facts变量
{{ ansible_hostname }}: 主机名
{{ ansible_default_ipv4.address }}: 默认网卡IP
{{ ansible_processor_cores }}: CPU核数
{{ ansible_memtotal_mb }}: 内存大小(MB)
{{ ansible_all_ipv4_addresses }}: 所有IPv4地址列表
4. 命令格式¶
template模块在ansible使用时,标准的写法是
ansible <目标主机> -m template -a 'src=模板路径 dest=目标路径 其他属性'
自定义变量用-e传递,如: ansible -m template -a "..." -e "http_port=8080"
5. 实践¶
1) 在控制机准备模板文件¶
[root@1 ~]# cat > /root/nginx_test.conf.j2 <<'EOF'
server {
listen {{ http_port }};
server_name {{ ansible_hostname }};
allow {{ ansible_default_ipv4.address }};
}
EOF
2) 使用template分发到目标主机(用-e传自定义变量http_port)¶
[root@1 ~]# ansible -m template -a "src=/root/nginx_test.conf.j2 dest=/tmp/nginx_test.conf" -e "http_port=8080" web_servers*