一、概述
1. 概念
Ansible是基于Python开发的自动化运维软件工具,基于SSH远程管理服务实现以并行的方式对主机进行批量管理;
2. 功能组成
- ansible主机清单(Inventory)
- ansible功能模块(Module)
- ansible剧本编写(Playbook)
3. 主要功能
- 实现批量系统操作配置
- 实现批量软件服务部署
- 实现批量分发数据文件
- 实现批量采集系统信息
4. 特点
- 管理端不需要启动服务程序(no server)
- 管理端不需要编写配置文件(/etc/ansible/ansible.cfg)
- 受控端不需要安装软件程序(libselinux-python)
- 受控端不需要启动服务程序(no agent)
- 服务程序管理操作模块众多(module)
- 利用剧本编写可实现自动化(playbook)
5. 意义
- 提高工作效率
- 提高工作准确度
- 减少维护成本
- 减少重复性工作
二、ansible安装与配置
1. 安装ansible
step 01 管理端分发公钥至被管理端
[root@ansible-manager ~]# yum install -y sshpass.x86_64
Loaded plugins: fastestmirror
......
Complete!
[root@ansible-manager ~]# ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
......
[root@ansible-manager ~]# ssh-copy-id -i ~/.ssh/id_rsa.pub -o StrictHostKeyChecking=no -p 22 root@10.0.0.15
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
......
[root@ansible-manager ~]# ssh root@10.0.0.15
Last login: Tue Nov 9 13:29:52 2021 from 10.0.0.2
[root@web01 ~]# logout
Connection to 10.0.0.15 closed.
[root@ansible-manager ~]# for i in {16,17}; do sshpass -p 123456 ssh-copy-id -i ~/.ssh/id_rsa.pub -o StrictHostKeyChecking=no -p 22 root@10.0.0.$i &>/dev/null; done
[root@ansible-manager ~]# ssh root@10.0.0.16
Last login: Tue Nov 9 13:29:52 2021 from 10.0.0.2
[root@web02 ~]# logout
Connection to 10.0.0.16 closed.
[root@ansible-manager ~]# ssh root@10.0.0.17
Last login: Tue Nov 9 13:29:51 2021 from 10.0.0.2
[root@web03 ~]# logout
Connection to 10.0.0.17 closed.
step 02 管理端安装ansible服务
ansible依赖EPEL源
[root@ansible-manager ~]# yum install -y ansible
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
......
Complete!
[root@ansible-manager ~]# rpm -qa ansible
ansible-2.9.25-1.el7.noarch
2. ansible核心文件
[root@ansible-manager ~]# rpm -ql ansible | grep /etc/ansible/
/etc/ansible/ansible.cfg
/etc/ansible/hosts
/etc/ansible/roles
- /etc/ansible/ansibel.cfg 默认配置文件
- /etc/ansible/hosts 主机清单(Inventory)
- /etc/ansible/roles 角色目录
3. ansible核心命令
/usr/bin/anisble |
ansible 主机信息1,主机信息2,... 批量管理主机执行同一任务
-m 模块名称 指定调用的功能模块
-a "指令" 指定完成的指令信息
-i /目录/文件名称 指定临时调用主机清单文件
--version 查看ansible版本
注意: 1. ansible命令后面指定的主机信息,必须添加到主机清单中;否则无法管理成功; 2. 主机信息可以使用all用以管理所有主机; |
# 未添加主机清单
[root@ansible-manager ~]# ansible 10.0.0.15 -m command -a hostname
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit
localhost does not match 'all'
[WARNING]: Could not match supplied host pattern, ignoring: 10.0.0.15
# 管理特定一台主机
[root@ansible-manager ~]# ansible 10.0.0.15 -m command -a hostname
10.0.0.15 | CHANGED | rc=0 >>
web01
/usr/bin/anisble-playbook |
ansible-playbook 剧本名称 执行ansible剧本
--syntax-check 检查剧本语法
-C 模拟执行剧本(不会对远程主机造成更改)
-e 变量名=值 指定变量执行剧本
-t 标记点 仅执行指定标记的模块(项目)
--skip-tags=标记点 运行剧本并跳过标记点的模块
ansible-doc #查看ansible本机帮助文档 ansible-doc 模块名称 #查看ansible指定模块的具体用法 |
-l 查看ansible所有模块信息
-s 模块名称 查看指定模块详细说明
[root@ansible-manager ~]# ansible-doc -l | wc -l
3387
[root@ansible-manager ~]# ansible-doc -l
fortios_router_community_list Configure community lists in Fortin...
azure_rm_devtestlab_info Get Azure DevTest Lab facts
ecs_taskdefinition register a task definition in ecs
avi_alertscriptconfig Module for setup of AlertScriptConf...
......
4. 配置主机清单文件
方式一:简单配置
/etc/ansible/hosts 主机IP地址 |
[root@ansible-manager ~]# grep -Ev '^$|#' /etc/ansible/hosts
10.0.0.15
10.0.0.16
10.0.0.17
[root@ansible-manager ~]# ansible all -m command -a "hostname"
10.0.0.15 | CHANGED | rc=0 >>
web01
10.0.0.17 | CHANGED | rc=0 >>
web03
10.0.0.16 | CHANGED | rc=0 >>
web02
[root@ansible-manager ~]# ansible 10.0.0.15,10.0.0.16 -m command -a "hostname"
10.0.0.15 | CHANGED | rc=0 >>
web01
10.0.0.16 | CHANGED | rc=0 >>
web02
方式二:分组配置
/etc/ansible/hosts [组名1] 主机IP地址1 主机IP地址2 [组名2] 主机IP地址1 ...... |
[root@ansible-manager ~]# grep -Ev '^$|#' /etc/ansible/hosts
[web]
10.0.0.15
10.0.0.16
[db]
10.0.0.17
[root@ansible-manager ~]# ansible web -m command -a "hostname"
10.0.0.16 | CHANGED | rc=0 >>
web02
10.0.0.15 | CHANGED | rc=0 >>
web01
[root@ansible-manager ~]# ansible db -m command -a "hostname"
10.0.0.17 | CHANGED | rc=0 >>
web03
方式三:符号匹配信息配置
/etc/ansible/hosts 主机地址[起始:结束] 主机名称[起始:结束] |
[root@ansible-manager ~]# grep -Ev '^$|#' /etc/ansible/hosts
[web]
10.0.0.[15:18]
[root@ansible-manager ~]# ansible web -m command -a "hostname"
10.0.0.16 | CHANGED | rc=0 >>
web02
10.0.0.15 | CHANGED | rc=0 >>
web01
10.0.0.17 | CHANGED | rc=0 >>
web03
#因为不存在10.0.0.18主机,所以执行报错;
10.0.0.18 | UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh: ssh: connect to host 10.0.0.18 port 22: No route to host",
"unreachable": true
}
方式四:特殊变量信息配置
/etc/ansible/hosts 主机地址 参数名1=参数值 参数名2=参数值 ... |
参数必须是ansible自身支持的参数,不支持自定义参数; ansible内置参数 |
[root@ansible-manager ~]# grep -Ev '^$|#' /etc/ansible/hosts
[web]
10.0.0.15
[data]
10.0.0.16
[db]
10.0.0.17 ansible_user=root ansible_password=123456 ansible_port=22
[root@ansible-manager ~]# ssh root@10.0.0.17 'rm -rf /root/.ssh/authorized_keys'
[root@ansible-manager ~]# ssh root@10.0.0.16 'rm -rf /root/.ssh/authorized_keys'
[root@ansible-manager ~]# ssh root@10.0.0.16
root@10.0.0.16's password:
[root@ansible-manager ~]# ssh root@10.0.0.17
root@10.0.0.17's password:
[root@ansible-manager ~]# ansible data -m command -a "hostname"
10.0.0.16 | UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh: Permission denied (publickey,password).",
"unreachable": true
}
[root@ansible-manager ~]# ansible db -m command -a "hostname"
web03 | CHANGED | rc=0 >>
web03
利用变量参数,实现ansible用户身份切换 |
/etc/ansible/hosts ansible_user=用户名 #指定登录用户名 ansible_password=用户名密码 #指定登录用户名密码 ansible_port=端口号 #指定SSH连接端口 ansible_become=yes #开启用户身份切换 ansible_become_method=su #指定转换方法为su(也可以是sudo) ansible_become_user=root #指定切换用户名 ansible_become_pass=123456 #指定切换用户密码 |
[root@ansible-manager ~]# grep -Ev '^$|#' /etc/ansible/hosts
[nfs:children]
nfs_server
nfs_client
[nfs_server]
10.0.0.15
[nfs_server:vars]
ansible_user=Young
ansible_password=123456
[nfs_client]
10.0.0.16
10.0.0.17
[root@ansible-manager /etc/ansible]# ansible nfs_server -m copy -a "content='testing txt' dest=/home/Young/test2.txt "
10.0.0.15 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "d77d1759eb57e64717a0d2e71a5df62e3ea2631c",
"dest": "/home/Young/test2.txt",
"gid": 1001,
"group": "Aspen",
"md5sum": "f5a2007be791b68e4d2fabadd41436fe",
"mode": "0644",
"owner": "Young",
"size": 11,
"src": "/home/Young/.ansible/tmp/ansible-tmp-1638318982.17-7865-240639660263401/source",
"state": "file",
"uid": 1001
[root@ansible-manager ~]# grep -Ev '^$|#' /etc/ansible/hosts
[nfs:children]
nfs_server
nfs_client
[nfs_server]
10.0.0.15
[nfs_server:vars]
ansible_user=Young
ansible_password=123456
ansible_become=yes
ansible_become_method=su
ansible_become_user=root
ansible_become_pass=123456
[nfs_client]
10.0.0.16
10.0.0.17
[root@ansible-manager /etc/ansible]# ansible nfs_server -m copy -a "content='testing txt' dest=/home/Young/test.txt "
10.0.0.15 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "d77d1759eb57e64717a0d2e71a5df62e3ea2631c",
"dest": "/home/Young/test.txt",
"gid": 0,
"group": "root",
"md5sum": "f5a2007be791b68e4d2fabadd41436fe",
"mode": "0644",
"owner": "root",
"size": 11,
"src": "/home/Young/.ansible/tmp/ansible-tmp-1638318875.0-7814-240027464307441/source",
"state": "file",
"uid": 0
}
[root@ansible-manager ~]# ansible nfs_server -a "ls -l"
10.0.0.15 | CHANGED | rc=0 >>
total 8
-rw-r--r-- 1 Young Aspen 11 Dec 1 08:36 test2.txt
-rw-r--r-- 1 root root 11 Dec 1 08:34 test.txt
方式五:嵌入式配置
- 嵌入子组
/etc/ansible/hosts [父组名称:children] 组名1 组名2 ...... [组名1] 主机IP地址1 主机IP地址2 [组名2] 主机IP地址1 ...... |
[root@ansible-manager ~]# grep -Ev '^$|#' /etc/ansible/hosts
[nfs:children]
nfs_server
nfs_client
[nfs_server]
10.0.0.15
[nfs_client]
10.0.0.16
10.0.0.17
[root@ansible-manager ~]# ansible nfs_server -m command -a "hostname"
10.0.0.15 | CHANGED | rc=0 >>
web01
[root@ansible-manager ~]# ansible nfs_client -m command -a "hostname"
10.0.0.17 | CHANGED | rc=0 >>
web03
10.0.0.16 | CHANGED | rc=0 >>
web02
[root@ansible-manager ~]# ansible nfs -m command -a "hostname"
10.0.0.16 | CHANGED | rc=0 >>
web02
10.0.0.15 | CHANGED | rc=0 >>
web01
10.0.0.17 | CHANGED | rc=0 >>
web03
- 嵌入变量
嵌入式变量配置主机清单的方式,常与ansible的playbook配合使用; |
/etc/ansible/hosts [组名] 主机地址 [组名:vars] 变量名1=值 变量名2=值 ...... |
[root@ansible-manager ~]# grep -Ev '^$|#' /etc/ansible/hosts
[nfs:children]
nfs_server
nfs_client
[nfs_server]
10.0.0.15
[nfs_client]
10.0.0.16
10.0.0.17
[nfs_client:vars]
ansible_user=root
ansible_password=123456
ansible_port=22
[root@ansible-manager ~]# ssh root@10.0.0.16 "rm -rf /root/.ssh/authorized_keys"
[root@ansible-manager ~]# ssh root@10.0.0.17 "rm -rf /root/.ssh/authorized_keys"
[root@ansible-manager ~]# ssh root@10.0.0.17
root@10.0.0.17's password:
[root@ansible-manager ~]# ssh root@10.0.0.16
root@10.0.0.16's password:
[root@ansible-manager ~]# ansible nfs_client -m command -a "hostname"
10.0.0.17 | CHANGED | rc=0 >>
web03
10.0.0.16 | CHANGED | rc=0 >>
web02
[root@ansible-manager ~]# grep -Ev '^$|#' /etc/ansible/hosts
[nfs:children]
nfs_server
nfs_client
[nfs_server]
10.0.0.15
[nfs_client]
10.0.0.16
10.0.0.17
[root@ansible-manager ~]# ansible nfs_client -m command -a "hostname"
10.0.0.16 | UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh: Permission denied (publickey,password).",
"unreachable": true
}
10.0.0.17 | UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh: Permission denied (publickey,password).",
"unreachable": true
}
5. ansible执行返回结果字体颜色含义
- 绿色:命令执行成功,并对远程主机进行任何修改;
- 黄色:命令执行成功,并对远程主机进行修改(大部分情况);
- 红色:命令执行失败;
- 粉色:警告信息;一般是给出官方建议的操作方法;
- 蓝色:显示命令或剧本的执行的过程;
三、功能模块
ansible常用模块: command(默认模块), shell(万能模块), copy, fetch, file, script, yum, rpm, apt-get, pip, service, cron, user, mount, ping, setup, debug, mysql(相关), archive, unarchive |
1. command模块
作用: 批量管理主机执行命令;
command模块局限性:该模块不能以Shell方式进行指令处理,因此变量和参数将不能识别; 变量:如$HOME; 参数:如:"<", ">", "|", ";", "&" ... |
语法:
ansible 主机地址 -m command -a "参数 命令" |
核心参数:
-
chdir
chdir=目录名称 #执行指令操作前进行目录切换; [root@ansible-manager ~]# ansible 10.0.0.15 -m command -a "chdir=/tmp pwd" 10.0.0.15 | CHANGED | rc=0 >> /tmp [root@ansible-manager ~]# ansible 10.0.0.15 -m command -a "pwd" 10.0.0.15 | CHANGED | rc=0 >> /root
-
creates
creates=/目录/文件名称 #若creates文件存在,则跳过后续命令执行(文件存在即不执行) [root@ansible-manager ~]# ansible 10.0.0.15 -m command -a "creates=/root/anaconda-ks.cfg touch /root/testing.txt" 10.0.0.15 | SUCCESS | rc=0 >> skipped, since /root/anaconda-ks.cfg exists [root@ansible-manager ~]# ansible 10.0.0.15 -m command -a "ls" 10.0.0.15 | CHANGED | rc=0 >> anaconda-ks.cfg [root@ansible-manager ~]# ansible 10.0.0.15 -m command -a "creates=/root/testing.txt touch /root/testing.txt" [WARNING]: Consider using the file module with state=touch rather than running 'touch'. If you need to use command because file is insufficient you can add 'warn: false' to this command task or set 'command_warnings=False' in ansible.cfg to get rid of this message. 10.0.0.15 | CHANGED | rc=0 >> [root@ansible-manager ~]# ansible 10.0.0.15 -m command -a "ls" 10.0.0.15 | CHANGED | rc=0 >> anaconda-ks.cfg testing.txt
-
removes
removes=/目录/文件名称 #若removes文件不存在,则跳过后续命令执行(文件存在即执行) [root@ansible-manager ~]# ansible 10.0.0.15 -m command -a "removes=/root/testing.txt rm -f anaconda-ks.cfg" [WARNING]: Consider using the file module with state=absent rather than running 'rm'. If you need to use command because file is insufficient you can add 'warn: false' to this command task or set 'command_warnings=False' in ansible.cfg to get rid of this message. 10.0.0.15 | CHANGED | rc=0 >> [root@ansible-manager ~]# ansible 10.0.0.15 -m command -a "ls" 10.0.0.15 | CHANGED | rc=0 >> testing.txt [root@ansible-manager ~]# ansible 10.0.0.15 -m command -a "removes=anaconda-ks.cfg.txt rm -f testing.txt" 10.0.0.15 | SUCCESS | rc=0 >> skipped, since anaconda-ks.cfg.txt does not exist [root@ansible-manager ~]# ansible 10.0.0.15 -m command -a "ls" 10.0.0.15 | CHANGED | rc=0 >> testing.txt
2. shell模块
作用: 批量管理主机执行命令;
shell模块:与command模块功能类似,但是可以识别变量和一些特殊字符; shell模块:又被称为万能模块; |
语法:
ansible 主机地址 -m shell -a "参数 命令" |
核心参数:
-
chdir
chdir=目录名称 #执行指令操作前进行目录切换; [root@ansible-manager ~]# ansible 10.0.0.15 -m shell -a "chdir=/etc/sysconfig/network-scripts/ pwd" 10.0.0.15 | CHANGED | rc=0 >> /etc/sysconfig/network-scripts [root@ansible-manager ~]# ansible 10.0.0.15 -m shell -a "pwd" 10.0.0.15 | CHANGED | rc=0 >> /root
-
creates
creates=/目录/文件名称 #若creates文件存在,则跳过后续命令执行(文件存在即不执行) [root@ansible-manager ~]# ansible 10.0.0.15 -m shell -a "creates=/etc/sysconfig/network-scripts/ifcfg-eth0 touch /root/Young.txt" 10.0.0.15 | SUCCESS | rc=0 >> skipped, since /etc/sysconfig/network-scripts/ifcfg-eth0 exists [root@ansible-manager ~]# ansible 10.0.0.15 -m shell -a "ls" 10.0.0.15 | CHANGED | rc=0 >> testing.txt [root@ansible-manager ~]# ansible 10.0.0.15 -m shell -a "creates=/etc/sysconfig/network-scripts/ifcfg-eth5 touch /root/Young.txt" [WARNING]: Consider using the file module with state=touch rather than running 'touch'. If you need to use command because file is insufficient you can add 'warn: false' to this command task or set 'command_warnings=False' in ansible.cfg to get rid of this message. 10.0.0.15 | CHANGED | rc=0 >> [root@ansible-manager ~]# ansible 10.0.0.15 -m shell -a "ls" 10.0.0.15 | CHANGED | rc=0 >> testing.txt Young.txt
-
removes
removes=/目录/文件名称 #若removes文件不存在,则跳过后续命令执行(文件存在即执行) [root@ansible-manager ~]# ansible 10.0.0.15 -m shell -a "removes=/etc/sysconfig/network-scripts/ifcfg-eth5 rm -rf /root/Young.txt" 10.0.0.15 | SUCCESS | rc=0 >> skipped, since /etc/sysconfig/network-scripts/ifcfg-eth5 does not exist [root@ansible-manager ~]# ansible 10.0.0.15 -m shell -a "ls" 10.0.0.15 | CHANGED | rc=0 >> testing.txt Young.txt [root@ansible-manager ~]# ansible 10.0.0.15 -m shell -a "removes=/etc/sysconfig/network-scripts/ifcfg-eth0 rm -rf /root/Young.txt" [WARNING]: Consider using the file module with state=absent rather than running 'rm'. If you need to use command because file is insufficient you can add 'warn: false' to this command task or set 'command_warnings=False' in ansible.cfg to get rid of this message. 10.0.0.15 | CHANGED | rc=0 >> [root@ansible-manager ~]# ansible 10.0.0.15 -m shell -a "ls" 10.0.0.15 | CHANGED | rc=0 >> testing.txtshell模块
3. script模块
作用: 批量管理主机执行脚本信息;
script模块可以让受控主机直接执行保存在控制端的脚本,节省了分发脚本和授权的步骤; |
语法:
ansible 主机地址 -m script -a "/目录/脚本" |
[root@ansible-manager ~]# cat test.sh
#!/bin/bash
stat . | awk -F "[ /(]" 'NR==4 {print $3}'
stat /tmp | awk -F "[ /(]" 'NR==4 {print $3}'
[root@ansible-manager ~]# ansible nfs_server -m script -a "./test.sh"
10.0.0.15 | CHANGED => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 10.0.0.15 closed.\r\n",
"stderr_lines": [
"Shared connection to 10.0.0.15 closed."
],
"stdout": "0550\r\n1777\r\n",
"stdout_lines": [
"0550",
"1777"
]
}
[root@ansible-manager ~]# ansible nfs_server -m shell -a "./test.sh"
10.0.0.15 | FAILED | rc=127 >>
/bin/sh: ./test.sh: No such file or directorynon-zero return code
4. yum模块
作用: 批量管理主机部署软件;
语法:
ansible 主机地址 -m yum -a "参数" |
核心参数:
-
name
name=软件名称 #指定目标软件名称; -
state
state=操作方式 #选择安装目标软件或卸载目标软件; 安装参数:installed, latest, present;
卸载参数:absent, removed;[root@ansible-manager ~]# ansible nfs_server -m yum -a "name=nginx state=installed" 10.0.0.15 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "changes": { "installed": [ "nginx" ] }, "msg": "", "rc": 0, "results": [...... ] }
5. service模块
作用: 批量管理主机部署软件;
语法:
ansible 主机地址 -m service -a "参数" |
核心参数:
-
name
name=服务名称 #指定目标服务名称; -
state
state=操作方式 #选择目标服务的工作方式; started #启动指定服务
restarted #重启指定服务
reloaded #平滑重启指定服务
stopped #停止指定服务 -
enabled
enabled=操作方式 #选择目标服务的开启启动状态; yes #指定服务开机自启动
no #停止服务开启自启动[root@ansible-manager ~]# ansible nfs_server -m shell -a "systemctl status sshd" | head -4 10.0.0.15 | CHANGED | rc=0 >> ● sshd.service - OpenSSH server daemon Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: enabled) Active: active (running) since Wed 2021-11-10 08:44:41 CST; 5h 18min ago [root@ansible-manager ~]# ansible nfs_server -m service -a "name=sshd state=stopped enabled=no" 10.0.0.15 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, ...... [root@ansible-manager ~]# ansible nfs_server -m shell -a "systemctl status sshd" | head -4 10.0.0.15 | FAILED | rc=3 >> ● sshd.service - OpenSSH server daemon Loaded: loaded (/usr/lib/systemd/system/sshd.service; disabled; vendor preset: enabled) Active: inactive (dead) [root@ansible-manager ~]# ansible nfs_server -m service -a "name=sshd state=started enabled=yes" 10.0.0.15 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "enabled": true, "name": "sshd", "state": "started", ...... [root@ansible-manager ~]# ansible nfs_server -m shell -a "systemctl status sshd" | head -4 10.0.0.15 | CHANGED | rc=0 >> ● sshd.service - OpenSSH server daemon Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: enabled) Active: active (running) since Wed 2021-11-10 14:39:45 CST; 27s ago
6. copy模块
作用:
- 分发文件;将管理端主机的数据文件分发至受控端主机中;
- 移动文件;将受控端某一目录中的数据移动至本机的其他目录中;
语法:
ansible 主机地址 -m copy -a "参数" |
核心参数:
-
src
src=/目录/文件名称 #指定管理端源文件; -
dest
dest=/目录 #指定受控端文件存放位置; -
owner
owner=受控端用户名 #文件完成后,修改文件属主为参数指定用户; -
group
group=受控端用户组名 #文件完成后,修改文件属组为参数指定用户组; -
mode
mode=权限位 #指定文件权限;(可直接修改目标文件的12位权限位) [root@ansible-manager ~]# ansible nfs_server -m copy -a "src=/etc/sysconfig/network-scripts/ifcfg-eth0 dest=/opt owner=Young group=Aspen mode=1666" 10.0.0.15 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "checksum": "4b012dda109a9bf006925c5ebc6536122293f643", "dest": "/opt/ifcfg-eth0", "gid": 1001, "group": "Aspen", "md5sum": "844f6f76b88a3f434e7b4a100a33e5f6", "mode": "01666", "owner": "Young", "size": 124, "src": "/root/.ansible/tmp/ansible-tmp-1636528273.42-9514-35710178891211/source", "state": "file", "uid": 1001 } [root@ansible-manager ~]# ansible nfs_server -m shell -a "ls -l /opt" 10.0.0.15 | CHANGED | rc=0 >> total 4 -rw-rw-rwT 1 Young Aspen 124 Nov 10 15:11 ifcfg-eth0
-
backup
使用backup备份时,备份文件名称具有随机性,不利于文件恢复;不建议使用;备份文件建议使用remote_src参数
backup=状态 #分发文件之前,将受控端源文件按照时间信息备份;(backup参数仅对文件内容发生更改的文件生效备份) yes #开启备份功能
no #关闭备份功能(默认参数)[root@ansible-manager ~]# ansible nfs_client -m copy -a "src=/etc/hosts dest=/opt owner=Young group=Aspen mode=0555" 10.0.0.17 | CHANGED => { ...... [root@ansible-manager ~]# >/etc/hosts [root@ansible-manager ~]# ansible nfs_client -m copy -a "src=/etc/hosts dest=/opt owner=Young group=Aspen mode=0555 backup=yes" 10.0.0.16 | CHANGED => { [root@ansible-manager ~]# ansible nfs_client -m shell -a "ls -l /opt" 10.0.0.16 | CHANGED | rc=0 >> total 4 -r-xr-xr-x 1 Young Aspen 0 Nov 10 15:24 hosts -r-xr-xr-x 1 Young Aspen 349 Nov 10 15:23 hosts.8686.2021-11-10@15:24:46~ 10.0.0.17 | CHANGED | rc=0 >> total 4 -r-xr-xr-x 1 Young Aspen 0 Nov 10 15:24 hosts -r-xr-xr-x 1 Young Aspen 349 Nov 10 15:23 hosts.8650.2021-11-10@15:24:46~
-
remote_src
remote_src=状态 #指定分发文件源地址; yes #指定源文件在受控端
no #指定源文件在管理端(默认参数)[root@ansible-manager ~]# ansible nfs_server -m copy -a "src=/etc/sysconfig/network-scripts/ifcfg-eth0 dest=/opt owner=Young group=Aspen mode=1777 remote_src=yes" 10.0.0.15 | CHANGED => { "ansible_facts": { ....... } [root@ansible-manager ~]# ansible nfs_server -m copy -a "src=/etc/sysconfig/network-scripts/ifcfg-eth0 dest=/opt/ifcfg-eth0.txt owner=Young group=Aspen mode=1777" 10.0.0.15 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" ...... } [root@ansible-manager ~]# ansible nfs_server -m shell -a "cat /opt/ifcfg-*" 10.0.0.15 | CHANGED | rc=0 >> TYPE=Ethernet BOOTPROTO=none NAME=eth0 DEVICE=eth0 ONBOOT=yes IPADDR=10.0.0.15 PREFIX=24 GATEWAY=10.0.0.254 DNS1=10.0.0.254 -------------------------------------------#手动分割线#----------------------------------------------- TYPE=Ethernet BOOTPROTO=none NAME=eth0 DEVICE=eth0 ONBOOT=yes IPADDR=10.0.0.12 PREFIX=24 GATEWAY=10.0.0.254 DNS1=10.0.0.254
-
content
content=内容 #指定内容作为文件分发;(仅能指定简单内容) [root@ansible-manager ~]# ansible nfs_server -m copy -a "content=aspenhan.com dest=/opt/young.txt mode=600" 10.0.0.15 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "checksum": "a19091186a872f390ed7b22b2a2112e2c4c0c475", "dest": "/opt/young.txt", "gid": 0, "group": "root", "md5sum": "78d6eafa109f8aa6643efa3ce4222efc", "mode": "0600", "owner": "root", "size": 12, "src": "/root/.ansible/tmp/ansible-tmp-1636532016.71-10097-212988197816126/source", "state": "file", "uid": 0 } [root@ansible-manager ~]# ansible nfs_server -m shell -a "cat /opt/young.txt" 10.0.0.15 | CHANGED | rc=0 >> aspenhan.com
7. fetch模块
作用: 拉取远程受控端主机数据至本地;
fetch模块不仅拉取目标文件,为了区分多台主机同时拉取,会连同对应文件的目录结构一起拉取至本地指定目录下的IP地址目录中
语法:
ansible 主机地址 -m fetch -a "参数" |
核心参数:
-
src
src=/目录/文件名称 #指定被控端被拉取文件; -
dest
dest=/目录 #指定管理端文件存放位置; [root@ansible-manager ~]# ansible nfs_client -m fetch -a "src=/etc/sysconfig/network-scripts/ifcfg-eth0 dest=/opt" 10.0.0.16 | CHANGED => { "changed": true, "checksum": "4a166ce4f2ceae28e4a6ad5400f969b3442cf2ca", "dest": "/opt/10.0.0.16/etc/sysconfig/network-scripts/ifcfg-eth0", "md5sum": "ffc518fe7818892473a062abf9143a02", "remote_checksum": "4a166ce4f2ceae28e4a6ad5400f969b3442cf2ca", "remote_md5sum": null } 10.0.0.17 | CHANGED => { "changed": true, "checksum": "dfdb59c07cd37c844c90d884680376b214fe6b10", "dest": "/opt/10.0.0.17/etc/sysconfig/network-scripts/ifcfg-eth0", "md5sum": "b4c7dbf25c5edbffafa736c969e57027", "remote_checksum": "dfdb59c07cd37c844c90d884680376b214fe6b10", "remote_md5sum": null } [root@ansible-manager ~]# tree /opt/ /opt/ ├── 10.0.0.16 │ └── etc │ └── sysconfig │ └── network-scripts │ └── ifcfg-eth0 └── 10.0.0.17 └── etc └── sysconfig └── network-scripts └── ifcfg-eth0 8 directories, 2 files
8. file模块
作用:
- 修改文件属性信息
- 创建数据信息,如创建目录,创建文件,创建链接文件;
- 删除数据信息
语法:
ansible 主机地址 -m file -a "参数" |
核心参数:
-
path
path=/目录/文件 #指定处理数据路径信息 -
owner
owner=受控端用户名 #文件完成后,修改文件属主为参数指定用户; -
group
group=受控端用户组名 #文件完成后,修改文件属组为参数指定用户组; -
mode
mode=权限位 #指定文件权限;(可直接修改目标文件的12位权限位) -
state
state=状态 #指定文件执行的操作 touch #创建文件
directory #创建目录(默认支持递归创建多级目录)
hard #创建硬链接
link #创建软连接
absent #删除数据信息(默认支持递归删除)[root@ansible-manager ~]# ansible 10.0.0.15 -a "warn=false rm -rf /opt/* " 10.0.0.15 | CHANGED | rc=0 >> # 创建目录 [root@ansible-manager ~]# ansible 10.0.0.15 -m file -a "path=/opt/young state=directory owner=Young group=Aspen mode=1777" 10.0.0.15 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "gid": 1001, "group": "Aspen", "mode": "01777", "owner": "Young", "path": "/opt/young", "size": 6, "state": "directory", "uid": 1001 } [root@ansible-manager ~]# ansible 10.0.0.15 -a "ls -l /opt" 10.0.0.15 | CHANGED | rc=0 >> total 0 drwxrwxrwt 2 Young Aspen 6 Nov 11 10:40 young # 创建文件 [root@ansible-manager ~]# ansible 10.0.0.15 -m file -a "path=/opt/young/aspen.txt state=touch" 10.0.0.15 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "dest": "/opt/young/aspen.txt", "gid": 0, "group": "root", "mode": "0644", "owner": "root", "size": 0, "state": "file", "uid": 0 } [root@ansible-manager ~]# ansible 10.0.0.15 -a "ls -l /opt/young" 10.0.0.15 | CHANGED | rc=0 >> total 0 -rw-r--r-- 1 root root 0 Nov 11 10:41 aspen.txt # 创建软连接与硬链接 [root@ansible-manager ~]# ansible 10.0.0.15 -m file -a "src=/opt/young/aspen.txt path=/opt/young/aspen_hardlink.txt state=hard" 10.0.0.15 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "dest": "/opt/young/aspen_hardlink.txt", "gid": 0, "group": "root", "mode": "0644", "owner": "root", "size": 0, "src": "/opt/young/aspen.txt", "state": "hard", "uid": 0 } [root@ansible-manager ~]# ansible 10.0.0.15 -m file -a "src=/opt/young/aspen.txt path=/opt/young/aspen_softlink.txt state=link" 10.0.0.15 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "dest": "/opt/young/aspen_softlink.txt", "gid": 0, "group": "root", "mode": "0777", "owner": "root", "size": 20, "src": "/opt/young/aspen.txt", "state": "link", "uid": 0 } [root@ansible-manager ~]# ansible 10.0.0.15 -a "ls -li /opt/young" 10.0.0.15 | CHANGED | rc=0 >> total 0 3098 -rw-r--r-- 2 root root 0 Nov 11 10:41 aspen_hardlink.txt 17748 lrwxrwxrwx 1 root root 20 Nov 11 11:13 aspen_softlink.txt -> /opt/young/aspen.txt 3098 -rw-r--r-- 2 root root 0 Nov 11 10:41 aspen.txt # 删除文件 [root@ansible-manager ~]# ansible 10.0.0.15 -m file -a "path=/opt/young/aspen_softlink.txt state=absent" 10.0.0.15 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "path": "/opt/young/aspen_softlink.txt", "state": "absent" } [root@ansible-manager ~]# ansible 10.0.0.15 -m file -a "path=/opt/young/aspen_hardlink.txt state=absent" 10.0.0.15 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "path": "/opt/young/aspen_hardlink.txt", "state": "absent" } [root@ansible-manager ~]# ansible 10.0.0.15 -a "ls -li /opt/young" 10.0.0.15 | CHANGED | rc=0 >> total 0 3098 -rw-r--r-- 1 root root 0 Nov 11 10:41 aspen.txt
9. mount模块
作用: 批量管理主机完成挂载操作;
语法:
ansible 主机地址 -m mount -a "参数" |
核心参数:
-
src
src=设备目录 #指定被挂载的设备目录 -
path
path=挂载点 #指定挂载点目录 -
fstype
fstype=文件系统类型 #指定挂载的文件系统类型 -
state
state=操作方式 #选择安装目标软件或卸载目标软件; 挂载参数:mounted(永久挂载、立即挂载), present(永久挂载);
卸载参数:unmounted(临时卸载), absent(永久卸载、立即卸载);# 准备环境 [root@web01 ~]# dd if=/dev/zero of=/tmp/testing_block bs=1M count=1024 1024+0 records in 1024+0 records out 1073741824 bytes (1.1 GB) copied, 29.9253 s, 35.9 MB/s [root@web01 ~]# mkfs.xfs /tmp/testing_block meta-data=/tmp/testing_block isize=512 agcount=4, agsize=65536 blks = sectsz=512 attr=2, projid32bit=1 = crc=1 finobt=0, sparse=0 data = bsize=4096 blocks=262144, imaxpct=25 = sunit=0 swidth=0 blks naming =version 2 bsize=4096 ascii-ci=0 ftype=1 log =internal log bsize=4096 blocks=2560, version=2 = sectsz=512 sunit=0 blks, lazy-count=1 realtime =none extsz=4096 blocks=0, rtextents=0
# mount挂载 [root@ansible-manager ~]# ansible 10.0.0.15 -m mount -a "src=/tmp/testing_block path=/mnt state=mounted fstype=xfs" 10.0.0.15 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "dump": "0", "fstab": "/etc/fstab", "fstype": "xfs", "name": "/mnt", "opts": "defaults", "passno": "0", "src": "/tmp/testing_block" } [root@ansible-manager ~]# ansible 10.0.0.15 -a "df -Th" |tail -1 /dev/loop0 xfs 1014M 33M 982M 4% /mnt [root@ansible-manager ~]# ansible 10.0.0.15 -a "cat /etc/fstab" | tail -1 /tmp/testing_block /mnt xfs defaults 0 0 # absent卸载 [root@ansible-manager ~]# ansible 10.0.0.15 -m mount -a "src=/tmp/testing_block path=/mnt state=absent" 10.0.0.15 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "dump": "0", "fstab": "/etc/fstab", "name": "/mnt", "opts": "defaults", "passno": "0", "src": "/tmp/testing_block" } [root@ansible-manager ~]# ansible 10.0.0.15 -a "cat /etc/fstab" | tail -1 UUID=42eaa7c4-975b-4c3a-8301-1e4543eb730e swap swap defaults 0 0 [root@ansible-manager ~]# ansible 10.0.0.15 -a "df -Th" | tail -1 tmpfs tmpfs 199M 0 199M 0% /run/user/0 # present挂载 [root@ansible-manager ~]# ansible 10.0.0.15 -m mount -a "src=/tmp/testing_block path=/mnt state=present fstype=xfs" 10.0.0.15 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "dump": "0", "fstab": "/etc/fstab", "fstype": "xfs", "name": "/mnt", "opts": "defaults", "passno": "0", "src": "/tmp/testing_block" } [root@ansible-manager ~]# ansible 10.0.0.15 -a "df -Th" | tail -1 tmpfs tmpfs 199M 0 199M 0% /run/user/0 [root@ansible-manager ~]# ansible 10.0.0.15 -a "cat /etc/fstab" | tail -1 /tmp/testing_block /mnt xfs defaults 0 0 # 准备环境 [root@ansible-manager ~]# ansible 10.0.0.15 -m mount -a "src=/tmp/testing_block path=/mnt state=absent fstype=xfs" 10.0.0.15 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "dump": "0", "fstab": "/etc/fstab", "fstype": "xfs", "name": "/mnt", "opts": "defaults", "passno": "0", "src": "/tmp/testing_block" [root@ansible-manager ~]# ansible 10.0.0.15 -a "cat /etc/fstab" | tail -1 UUID=42eaa7c4-975b-4c3a-8301-1e4543eb730e swap swap defaults 0 0 [root@ansible-manager ~]# ansible 10.0.0.15 -a "df -Th" | tail -1 tmpfs tmpfs 199M 0 199M 0% /run/user/0 [root@ansible-manager ~]# ansible 10.0.0.15 -m mount -a "src=/tmp/testing_block path=/mnt state=mounted fstype=xfs" 10.0.0.15 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "dump": "0", "fstab": "/etc/fstab", "fstype": "xfs", "name": "/mnt", "opts": "defaults", "passno": "0", "src": "/tmp/testing_block" # unmounted卸载 [root@ansible-manager ~]# ansible 10.0.0.15 -m mount -a "src=/tmp/testing_block path=/mnt state=unmounted" 10.0.0.15 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "dump": "0", "fstab": "/etc/fstab", "name": "/mnt", "opts": "defaults", "passno": "0", "src": "/tmp/testing_block" } [root@ansible-manager ~]# ansible 10.0.0.15 -a "df -Th" | tail -1 tmpfs tmpfs 199M 0 199M 0% /run/user/0 [root@ansible-manager ~]# ansible 10.0.0.15 -a "cat /etc/fstab" | tail -1 /tmp/testing_block /mnt xfs defaults 0 0
10. cron模块
作用: 批量设置管理主机的定时任务;
语法:
ansible 主机地址 -m cron -a "参数" |
核心参数:
-
name
name=注释内容 #定义定时任务注释信息; -
minute
minute=数字 #定义定时任务分钟信息 -
hour
hour=数字 #定义定时任务小时信息 -
day
day=数字 #定义定时任务日期信息 -
month
month=数字 #定义定时任务月份信息 -
weekday
weekday=数字 #定义定时任务星期信息 -
job
job=任务 #定义定时任务执行的指令信息 -
state
state=状态 #指定定时任务的状态 present #创建定时任务(默认参数)
absent #删除定时任务(仅能删除由ansible创建的定时任务) -
disabled
disabled=状态 #指定定时任务的启用 no #启用定时任务
yes #注释定时任务# 设置定时任务 [root@ansible-manager ~]# ansible 10.0.0.16 -m cron -a "name='syne time every 10 minutes' minute=*/10 job='ntpdate ntp1.aliyun.com &>/dev/null'" 10.0.0.16 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "envs": [], "jobs": [ "syne time every 10 minutes" ] } [root@ansible-manager ~]# ansible 10.0.0.16 -m shell -a "crontab -l" 10.0.0.16 | CHANGED | rc=0 >> #sync time by Aspen 20190511 */5 * * * * /usr/sbin/ntpdate ntp1.aliyun.com >/dev/null 2>&1 #Ansible: syne time every 10 minutes */10 * * * * ntpdate ntp1.aliyun.com &>/dev/null # 删除定时任务 [root@ansible-manager ~]# ansible 10.0.0.16 -m cron -a "name='syne time every 10 minutes' state=absent" 10.0.0.16 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "envs": [], "jobs": [] } [root@ansible-manager ~]# ansible 10.0.0.16 -m shell -a "crontab -l" 10.0.0.16 | CHANGED | rc=0 >> #sync time by Aspen 20190511 */5 * * * * /usr/sbin/ntpdate ntp1.aliyun.com >/dev/null 2>&1 # 注释定时任务并启用 [root@ansible-manager ~]# ansible 10.0.0.16 -m cron -a "name='syne time every 10 minutes' minute=*/10 job='ntpdate ntp1.aliyun.com &>/dev/null' disabled=yes" 10.0.0.16 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "envs": [], "jobs": [ "syne time every 10 minutes" ] } [root@ansible-manager ~]# ansible 10.0.0.16 -m shell -a "crontab -l" 10.0.0.16 | CHANGED | rc=0 >> #sync time by Aspen 20190511 */5 * * * * /usr/sbin/ntpdate ntp1.aliyun.com >/dev/null 2>&1 #Ansible: syne time every 10 minutes #*/10 * * * * ntpdate ntp1.aliyun.com &>/dev/null [root@ansible-manager ~]# ansible 10.0.0.16 -m cron -a "name='syne time every 10 minutes' job='ntpdate ntp1.aliyun.com &>/dev/null' disabled=no" 10.0.0.16 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "envs": [], "jobs": [ "syne time every 10 minutes" ] } [root@ansible-manager ~]# ansible 10.0.0.16 -m shell -a "crontab -l" 10.0.0.16 | CHANGED | rc=0 >> #sync time by Aspen 20190511 */5 * * * * /usr/sbin/ntpdate ntp1.aliyun.com >/dev/null 2>&1 #Ansible: syne time every 10 minutes * * * * * ntpdate ntp1.aliyun.com &>/dev/null
11. user模块
作用: 批量管理主机创建用户;
语法:
ansible 主机地址 -m user -a "参数" |
核心参数:
-
name
name=用户名 #指定用户名称 -
uid
uid=数字 #指定用户UID信息 -
group
group=用户组名 #指定用户的所属组信息 -
groups
groups=用户组名 #指定用户的附加组信息 -
password
password=密码 #指定用户的密码信息(必须是密文的密码信息) -
shell
shell=用户名 #指定用户的所使用的命令解释器 -
create_home
create_home=no #不创建家目录 -
state
state=状态 #指定用户状态 present #创建用户(默认参数)
absent #删除用户# 创建虚拟用户 [root@ansible-manager ~]# ansible 10.0.0.16 -m user -a "name=aspen uid=1010 group=Aspen groups=oldboy shell=/sbin/nologin create_home=no" 10.0.0.16 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "comment": "", "create_home": false, "group": 1001, "groups": "oldboy", "home": "/home/aspen", "name": "aspen", "shell": "/sbin/nologin", "state": "present", "system": false, "uid": 1010 } [root@ansible-manager ~]# ansible 10.0.0.16 -m shell -a "id aspen" 10.0.0.16 | CHANGED | rc=0 >> uid=1010(aspen) gid=1001(Aspen) groups=1001(Aspen),1000(oldboy) [root@ansible-manager ~]# ansible 10.0.0.16 -m shell -a "ls /home" 10.0.0.16 | CHANGED | rc=0 >> oldboy Young # 删除用户 [root@ansible-manager ~]# ansible 10.0.0.16 -m user -a "name=aspen state=absent" 10.0.0.16 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "force": false, "name": "aspen", "remove": false, "state": "absent" } [root@ansible-manager ~]# ansible 10.0.0.16 -m shell -a "id aspen" 10.0.0.16 | FAILED | rc=1 >> id: aspen: no such usernon-zero return code # 创建用户 [root@ansible-manager ~]# ansible 10.0.0.16 -m user -a 'name=aspen uid=1010 group=Aspen groups=oldboy password="$6$Young$XtmxodFMen47.aEj8/RWo/2Z/VQSJF9hHWonQI1CebNDNVe2WHw9kzlEC3RiypHgre/LZMuXoHbOf4A5knpdi/"' 10.0.0.16 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "comment": "", "create_home": true, "group": 1001, "groups": "oldboy", "home": "/home/aspen", "name": "aspen", "password": "NOT_LOGGING_PASSWORD", "shell": "/bin/bash", "state": "present", "stderr": "Creating mailbox file: File exists\n", "stderr_lines": [ "Creating mailbox file: File exists" ], "system": false, "uid": 1010 } [root@ansible-manager ~]# ssh aspen@10.0.0.16 aspen@10.0.0.16's password: [aspen@web02 ~]$ pwd /home/aspen [aspen@web02 ~]$ logout Connection to 10.0.0.16 closed.
创建密文密码
-
方式一:利用ansible的模块功能
ansible all -i localhost, -m debug -a msg={{ '明文密码' | password_hash('sha512', '辅助密钥') }}" #生成用户密码密码 [root@ansible-manager ~]# ansible all -i localhost, -m debug -a "msg={{ '123456' | password_hash('sha512', 'Young') }}" localhost | SUCCESS => { "msg": "$6$Young$XtmxodFMen47.aEj8/RWo/2Z/VQSJF9hHWonQI1CebNDNVe2WHw9kzlEC3RiypHgre/LZMuXoHbOf4A5knpdi/" }
-
方式二:利用python的模块功能
第一步:安装pip命令
yum install -y python-pip |
[root@ansible-manager ~]# yum install python-pip -y
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
......
Installed:
python2-pip.noarch 0:8.1.2-14.el7
Complete!
第二步:安装对应模块
pip install passlib |
[root@ansible-manager ~]# pip install passlib
Collecting passlib
Using cached https://files.pythonhosted.org/packages/3b/a4/ab6b7589382ca3df236e03faa71deac88cae040af60c071a78d254a62172/passlib-1.7.4-py2.py3-none-any.whl
Installing collected packages: passlib
Successfully installed passlib-1.7.4
You are using pip version 8.1.2, however version 21.3.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
第三步:生成密码
python -c "from passlib.hash import sha512_crypt; import getpass; print(sha512_crypt.using(rounds=5000).hash(getpass.getpass()))" |
[root@ansible-manager ~]# python -c "from passlib.hash import sha512_crypt; import getpass; print(sha512_crypt.using(rounds=5000).hash(getpass.getpass()))"
Password:
$6$fIR9.6Jm3xUtwLqT$jOnUQPZjKPPw.A4YLg131TwnouiN60gZeypqtDooq.9c8YRu28rQ6ekep9yPQvWOu8m//EfCKpOUsUPsYkdK8.
12. setup模块
作用: 批量获取主机信息;
语法:
ansible 主机地址 -m setup -a "filter=项目" |
常用项目:
项目名称 | 含义 |
---|---|
ansible_all_ipv4_addresses: | 仅显示IPv4的信息 |
ansible_devices: | 仅显示磁盘设备信息 |
ansible_distribution: | 显示系统发行类型(CentOS/SUSE/Ubuntu...) |
ansible_distribution_major_version: | 显示系统主版本 |
ansible_distribution_version: | 仅显示系统版本(32位/64位) |
ansible_machine: | 显示系统类型 |
ansible_eth0: | 仅显示eth0的信息 |
ansible_hostname: | 仅显示主机名称 |
ansible_kernal: | 仅显示系统内核版本 |
ansible_lvm: | 显示lvm相关信息 |
ansible_memtotal_mb: | 显示系统总内存 |
ansible_memfree_mb: | 显示系统可用内存 |
ansible_memory_mb: | 详细显示内存情况 |
ansible_swaptotal_mb: | 显示swap内存的总内存 |
ansible_swapfree_mb: | 显示swap内存的可用内存 |
ansible_mounts: | 显示系统磁盘挂载情况 |
ansible_processor: | 显示CPU个数(具体显示每个CPU的型号) |
ansible_processor_vcpus: | 显示CPU个数(只显示总的个数) |
[root@ansible-manager /etc/ansible/ansible-playbook]# ansible 10.0.0.15 -m setup
10.0.0.15 | SUCCESS => {
"ansible_facts": {
"ansible_all_ipv4_addresses": [
"172.16.1.15",
"10.0.0.15"
],
......
[root@ansible-manager /etc/ansible/ansible-playbook]# ansible 10.0.0.15 -m setup | wc -l
659
[root@ansible-manager /etc/ansible/ansible-playbook]# ansible 10.0.0.15 -m setup -a "filter=ansible_hostname"
10.0.0.15 | SUCCESS => {
"ansible_facts": {
"ansible_hostname": "web01",
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false
}
[root@ansible-manager /etc/ansible/ansible-playbook]# ansible 10.0.0.15 -m setup -a "filter=ansible_all_ipv4_addresses"
10.0.0.15 | SUCCESS => {
"ansible_facts": {
"ansible_all_ipv4_addresses": [
"172.16.1.15",
"10.0.0.15"
],
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false
}
四、ansible-playbook(剧本)
剧本的作用 1. 将多个模块操作功能进行整合; 2. 实现重复工作简单化(提高工作效率) 3. 实现批量管理特殊需求 |
1. 剧本组成
- hosts: 主机IP地址 定义角色信息
tasks: 定义任务信息
- 模块名称: 参数1 参数2
|
2. 剧本编写规范(YAML)
1.缩进 - 2个空格表示1个缩进关系;
2.冒号 - 创建键值对信息;在正文中(非在描述和注释信息中),非以冒号结尾情况下,冒号后面必须有空格;
3.短横线 - 短横线用以标识多个列表;列表表示相同的信息/类别多次出现;在正文中(非在描述和注释信息中),短横线后必须有空格;
3. 编写实践
rsync服务一键自动化部署
- hosts: rsync_server
tasks:
- name: Install rsyncd service
yum: name=rsync state=installed
- name: Backup source configuration File
copy: src=/etc/rsyncd.conf dest=/etc/rsyncd.conf.bak remote_src=yes
- name: Delivery configuration file to target
copy: src=/etc/ansible/ansible-playbook/rsync/rsyncd.conf dest=/etc/rsyncd.conf
- name: Create group
group: name=rsync
- name: Create User
user: name=rsync group=rsync shell=/sbin/nologin create_home=no
- name: Create backup directory
file: path=/backup owner=rsync group=rsync state=directory
- name: Delivery password file to target
copy: content='rsync_backup:123456' mode=600 dest=/etc/rsync_server.password
- name: Start rsyncd service
service: name=rsyncd state=started enabled=yes
- hosts: rsync_client
tasks:
- name: Delivery Password File
copy: content='123456' mode=600 dest=/etc/rsync_client.password
[root@ansible-manager ~]# mkdir /etc/ansible/ansible-playbook/rsync -p && cd /etc/ansible/ansible-playbook
[root@ansible-manager /etc/ansible/ansible-playbook]# ls rsync/rsyncd.conf
rsync/rsyncd.conf
[root@ansible-manager /etc/ansible/ansible-playbook]# grep -Ev '^$|#' ../hosts
[rsync:children]
rsync_server
rsync_client
[rsync_server]
10.0.0.15
[rsync_client]
10.0.0.16
10.0.0.17
[root@ansible-manager /etc/ansible/ansible-playbook]# ansible-playbook --syntax-check rsync_deploy.yaml
playbook: rsync_deploy.yaml
[root@ansible-manager /etc/ansible/ansible-playbook]# ansible-playbook -C rsync_deploy.yaml | head -5
PLAY [rsync_server] **********************************************************************************
TASK [Gathering Facts] *******************************************************************************
ok: [10.0.0.15]
[root@ansible-manager /etc/ansible/ansible-playbook]# ansible-playbook rsync_deploy.yaml
PLAY [rsync_server] **********************************************************************************
......
[root@web02 ~]# rsync -av /etc/fstab rsync_backup@172.16.1.15::backup --password-file=/etc/rsync_client.password
sending incremental file list
fstab
sent 596 bytes received 43 bytes 1,278.00 bytes/sec
[root@web02 ~]# ssh root@172.16.1.15 'ls /backup'
root@172.16.1.15's password:
fstab
[root@web03 ~]# rsync -av /etc/sysconfig/network-scripts/ifcfg-eth0 rsync_backup@172.16.1.15::backup --password-file=/etc/rsync_client.password
sending incremental file list
ifcfg-eth0
sent 224 bytes received 43 bytes 534.00 bytes/sec
total size is 124 speedup is 0.46
[root@web03 ~]# ssh root@172.16.1.15 'ls /backup'
root@172.16.1.15's password:
fstab
ifcfg-eth0
nfs服务一键自动化部署
[root@ansible-manager /etc/ansible/ansible-playbook]# cat nfs_deploy.yaml
- hosts: nfs_server
tasks:
- name: Install rpcbind and nfs service
yum:
name:
- rpcbind
- nfs-utils
state: installed
- name: Create group
group: name=www gid=2000
- name: Create user
user: name=www uid=2000 group=www shell=/sbin/nologin create_home=no
- name: Create shared directory
file: path=/backup/www/uploads state=directory owner=www group=www
- name: Delivery configuration file
copy: content='/backup/www/uploads 172.16.1.0/24(rw,sync,anonuid=2000,anongid=2000)' dest=/etc/exports
- name: Start rpcbind service
service: name=rpcbind state=started enabled=yes
- name: Start nfs service
service: name=nfs state=started enabled=yes
- hosts: nfs_client
tasks:
- name: Install nfs service
yum: name=nfs-utils state=installed
- name: Create group
group: name=www gid=2000
- name: Create user
user: name=www uid=2000 group=www shell=/sbin/nologin create_home=no
- name: Create mount point
file: path=/var/www/images state=directory
- name: Mount NFS service
mount: src=172.16.1.15:/backup/www/uploads path=/var/www/images fstype=nfs state=mounted
[root@ansible-manager /etc/ansible/ansible-playbook]# grep -Ev '^$|#' ../hosts
[nfs:children]
nfs_server
nfs_client
[nfs_server]
10.0.0.15
[nfs_client]
10.0.0.16
10.0.0.17
[root@ansible-manager /etc/ansible/ansible-playbook]# ansible-playbook --syntax-check nfs_deploy.yaml
playbook: nfs_deploy.yaml
[root@ansible-manager /etc/ansible/ansible-playbook]# ansible-playbook -C nfs_deploy.yaml | head -2
PLAY [nfs_server] ************************************************************************************
[root@ansible-manager /etc/ansible/ansible-playbook]# ansible-playbook nfs_deploy.yaml
PLAY [nfs_server] ************************************************************************************
TASK [Gathering Facts] *******************************************************************************
ok: [10.0.0.15]
......
[root@web02 ~]# cd /var/www/images/
[root@web02 /var/www/images]# df -Th |tail -1
172.16.1.15:/backup/www/uploads nfs4 99G 2.7G 97G 3% /var/www/images
[root@web02 /var/www/images]# tail -1 /etc/fstab
172.16.1.15:/backup/www/uploads /var/www/images nfs defaults 0 0
[root@web02 /var/www/images]# cp /etc/hostname .
[root@web02 /var/www/images]# ls
hostname
[root@web03 ~]# cd /var/www/images/
[root@web03 /var/www/images]# df -Th | tail -1
172.16.1.15:/backup/www/uploads nfs4 99G 2.7G 97G 3% /var/www/images
[root@web03 /var/www/images]# tail -1 /etc/fstab
172.16.1.15:/backup/www/uploads /var/www/images nfs defaults 0 0
[root@web03 /var/www/images]# ls
hostname
[root@web03 /var/www/images]# cp /etc/hostname ./hostname_web03
[root@web01 ~]# ls /backup/www/uploads/ -l
total 8
-rw-r--r-- 1 www www 6 Nov 17 13:40 hostname
-rw-r--r-- 1 www www 6 Nov 17 13:41 hostname_web03
[root@web01 ~]# cat /backup/www/uploads/hostname
web02
[root@web01 ~]# cat /backup/www/uploads/hostname_web03
web03
五、ansible-playbook进阶
1. 设置变量
变量设置方式优先级: 命令行 > 剧本文件 > 主机配置清单 |
方式一:剧本中设置变量
- hosts: 主机IP地址
vars: #定义变量
变量名1: 变量值
变量名2: 变量值
...
tasks:
- 模块名称: 参数={{ 变量名 }} 参数={{ 变量名 }} ... #引用变量
|
- hosts: 10.0.0.15
vars:
var1: 0
dir_info: /etc/
second_dir: sysconfig/network-scripts/
dest_dir: /tmp/
dest_file: ifcfg-eth{{ var1 }}
tasks:
- name: Delivery file to test vars
copy: src={{ dir_info }}{{ second_dir }}{{ dest_file }} dest={{ dest_dir }}{{ dest_file }}
[root@ansible-manager /etc/ansible/ansible-playbook]# ansible-playbook vars_test.yaml
PLAY [10.0.0.15]
......
[root@ansible-manager /etc/ansible/ansible-playbook]# ssh root@10.0.0.15 'cat /tmp/ifcfg-eth0|sed -n 6p'
IPADDR=10.0.0.12
[root@ansible-manager /etc/ansible/ansible-playbook]# ssh root@10.0.0.15 'ls -l /tmp/ifcfg-eth0'
-rw-r--r-- 1 root root 124 Nov 17 15:56 /tmp/ifcfg-eth0
方式二:命令行中设置变量
anisble-playbook -e 变量名1=值 -e 变量名2=值 ... 剧本名 |
- hosts: 10.0.0.15
vars:
dir_info: /etc/
second_dir: sysconfig/network-scripts/
dest_dir: /tmp/
dest_file: ifcfg-eth{{ var1 }}
tasks:
- name: Delivery file to test vars
copy: src={{ dir_info }}{{ second_dir }}{{ dest_file }} dest={{ dest_dir }}{{ dest_file }}
[root@ansible-manager /etc/ansible/ansible-playbook]# ansible-playbook vars_test.yaml -e var1=1
PLAY [10.0.0.15]
......
[root@ansible-manager /etc/ansible/ansible-playbook]# ssh root@10.0.0.15 'ls -l /tmp/ifcfg-eth1'
-rw-r--r-- 1 root root 94 Nov 17 16:26 /tmp/ifcfg-eth1
[root@ansible-manager /etc/ansible/ansible-playbook]# ssh root@10.0.0.15 'sed -n 6p /tmp/ifcfg-eth1'
IPADDR=172.16.1.12
方式三:在主机清单文件中定义变量
/etc/ansible/hosts [组名] 主机地址 [组名:vars] 变量名1=值 变量名2=值 ...... |
[root@ansible-manager /etc/ansible/ansible-playbook]# grep -Ev '#' vars_test.yaml
- hosts: 10.0.0.15
tasks:
- name: Delivery file to test vars
copy: src={{ dir_info }}{{ second_dir }}{{ dest_file }} dest={{ dest_dir }}{{ dest_file }}
[root@ansible-manager /etc/ansible/ansible-playbook]# grep -Ev '#|^$' ../hosts
[nfs:children]
nfs_server
nfs_client
[nfs_server]
10.0.0.15
[nfs_server:vars]
dir_info=/etc/
second_dir=sysconfig/network-scripts/
dest_dir=/tmp/
dest_file=ifcfg-eth{{ var1 }}
[nfs_client]
10.0.0.16
10.0.0.17
[root@ansible-manager /etc/ansible/ansible-playbook]# ssh root@10.0.0.15 'rm -rf /tmp/*'
[root@ansible-manager /etc/ansible/ansible-playbook]# ansible-playbook vars_test.yaml -e var1=0
PLAY [10.0.0.15] *************************************************************************************
......
[root@ansible-manager /etc/ansible/ansible-playbook]# ssh root@10.0.0.15 'ls -l /tmp/'
total 4
-rw-r--r-- 1 root root 124 Nov 17 16:46 ifcfg-eth0
[root@ansible-manager /etc/ansible/ansible-playbook]# ssh root@10.0.0.15 'sed -n 6p /tmp/ifcfg-eth0'
IPADDR=10.0.0.12
2. 注册信息
- hosts: 主机IP地址
tasks:
- 模块名称: 参数
register: 变量名 #将指令结果注册至变量
- 模块名称: 参数
debug: msg={{ 变量名.stdout_lines }} #显示变量信息(stdout_lines表示按行标准化输出)
|
stdout_lines参数在使用时,ansible-playbook -C模拟运行会报错; |
- hosts: 10.0.0.15
vars:
user_name: www
tasks:
- name: Display user info
command: id {{ user_name }}
register: user_info
- name: Display result
debug:
msg:
- "{{ user_info.stdout_lines }}"
[root@ansible-manager /etc/ansible/ansible-playbook]# ansible-playbook register.yaml
PLAY [10.0.0.15] *************************************************************************************
TASK [Gathering Facts] *******************************************************************************
ok: [10.0.0.15]
TASK [Display user info] *****************************************************************************
changed: [10.0.0.15]
TASK [Display result] ********************************************************************************
ok: [10.0.0.15] => {
"msg": [
[
"uid=2000(www) gid=2000(www) groups=2000(www)"
]
]
}
PLAY RECAP *******************************************************************************************
10.0.0.15 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
3.循环功能
使用循环功能可以实现一个模块,完成多个操作; |
循环方式1
- hosts: 主机IP地址
tasks:
- 模块名称: 参数={{ item }}
with_items:
- 循环值1
- 循环值2
....
|
- hosts: 10.0.0.15
tasks:
- name: Create_User
user:
name: "{{ item }}"
shell: /sbin/nologin
create_home: no
with_items:
- Young01
- Young02
- Young03
[root@ansible-manager /etc/ansible/ansible-playbook]# cat cycle_test1.yaml
[root@ansible-manager /etc/ansible/ansible-playbook]# ansible-playbook --syntax-check cycle_test1.yaml
playbook: cycle_test1.yaml
[root@ansible-manager /etc/ansible/ansible-playbook]# ansible-playbook -C cycle_test1.yaml
PLAY [10.0.0.15] *************************************************************************************
TASK [Gathering Facts] *******************************************************************************
ok: [10.0.0.15]
TASK [Create_User] ***********************************************************************************
changed: [10.0.0.15] => (item=Young01)
changed: [10.0.0.15] => (item=Young02)
changed: [10.0.0.15] => (item=Young03)
PLAY RECAP *******************************************************************************************
10.0.0.15 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
循环方式2
- hosts: 主机IP地址
tasks:
- 模块名称: 参数1={{ item.变量名1 }} 参数2={{ item.变量名2 }} 参数3={{ item.变量名3 }}
with_items:
- {变量名1: '变量值', 变量名2: '变量值', 变量名3: '变量值'}
- {变量名1: '变量值', 变量名2: '变量值', 变量名3: '变量值'}
- {变量名1: '变量值', 变量名2: '变量值', 变量名3: '变量值'}
...
|
- hosts: 10.0.0.15
tasks:
- name: Create_User
user:
name: "{{ item.name }}"
shell: "{{ item.shell }}"
create_home: "{{ item.home }}"
with_items:
- {name: 'Young01', shell: '/sbin/nologin', home: 'no'}
- {name: 'Young02', shell: '/bin/bash', home: 'no'}
- {name: 'Young03', shell: '/sbin/nologin', home: 'yes'}
- {name: 'Young04', shell: '/bin/bash', home: 'yes'}
[root@ansible-manager /etc/ansible/ansible-playbook]# cat cycle_test2.yaml
[root@ansible-manager /etc/ansible/ansible-playbook]# ansible-playbook --syntax-check cycle_test2.yaml
playbook: cycle_test2.yaml
[root@ansible-manager /etc/ansible/ansible-playbook]# ansible-playbook -C cycle_test2.yaml
PLAY [10.0.0.15] *************************************************************************************
TASK [Gathering Facts] *******************************************************************************
ok: [10.0.0.15]
TASK [Create_User] ***********************************************************************************
changed: [10.0.0.15] => (item={u'home': u'no', u'shell': u'/sbin/nologin', u'name': u'Young01'})
changed: [10.0.0.15] => (item={u'home': u'no', u'shell': u'/bin/bash', u'name': u'Young02'})
changed: [10.0.0.15] => (item={u'home': u'yes', u'shell': u'/sbin/nologin', u'name': u'Young03'})
changed: [10.0.0.15] => (item={u'home': u'yes', u'shell': u'/bin/bash', u'name': u'Young04'})
PLAY RECAP *******************************************************************************************
10.0.0.15 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
4. 判断功能
- hosts: 主机IP地址
tasks:
- 模块名称: 参数
when: (条件 == "值") #条件为真执行
- 模块名称: 参数
when: (条件 != "值") #条件为假执行
|
- hosts: nfs
tasks:
- name: Create File For web01
copy:
content: "Young test ansible_playbook condition function for web01"
dest: /opt/test.txt
mode: 755
when: (ansible_hostname == "web01")
- name: Create File For Others
copy:
content: "Young test ansible_playbook condition function for Others"
dest: /opt/test.txt
mode: 755
when: (ansible_hostname != "web01")
[root@ansible-manager /etc/ansible/ansible-playbook]# cat condition_test.yaml
[root@ansible-manager /etc/ansible/ansible-playbook]# ansible-playbook condition_test.yaml
PLAY [nfs] *******************************************************************************************
TASK [Gathering Facts] *******************************************************************************
ok: [10.0.0.15]
ok: [10.0.0.16]
ok: [10.0.0.17]
TASK [Create File For web01] *************************************************************************
skipping: [10.0.0.16]
skipping: [10.0.0.17]
changed: [10.0.0.15]
TASK [Create File For Others] ************************************************************************
skipping: [10.0.0.15]
changed: [10.0.0.16]
changed: [10.0.0.17]
PLAY RECAP *******************************************************************************************
10.0.0.15 : ok=2 changed=1 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
10.0.0.16 : ok=2 changed=1 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
10.0.0.17 : ok=2 changed=1 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
[root@ansible-manager /etc/ansible/ansible-playbook]# ansible nfs -a "cat /opt/test.txt"
10.0.0.16 | CHANGED | rc=0 >>
Young test ansible_playbook condition function for Others
10.0.0.15 | CHANGED | rc=0 >>
Young test ansible_playbook condition function for web01
10.0.0.17 | CHANGED | rc=0 >>
Young test ansible_playbook condition function for Others
5. 忽略错误
- hosts: 主机IP地址
tasks:
- 模块名称: 参数
ignore_errors: yes #开启忽略错误功能(仅对当前模块有效)
|
忽略错误主要作用: 1. ansible-playbook遇到错误时,将会停止执行;使用忽略错误功能,便于整个剧本的调试。 2. 当使用shell模块执行操作时,会出现一些合理错误;使用忽略错误功能,便于忽略合理错误。 |
- hosts: 10.0.0.15
tasks:
- name: Create user01
user:
name: Young01
- name: Create user02
shell: useradd Young02
ignore_errors: yes
- name: Create user03
user:
nam: Young03
ignore_errors: yes
- name: Create user04
shell: useradd Young04
- name: Create user05
user:
name: Young05
[root@ansible-manager /etc/ansible/ansible-playbook]# cat ignoreErr_test.yaml
[root@ansible-manager /etc/ansible/ansible-playbook]# ansible-playbook ignoreErr_test.yaml
PLAY [10.0.0.15] *************************************************************************************
TASK [Gathering Facts] *******************************************************************************
ok: [10.0.0.15]
TASK [Create user01] *********************************************************************************
ok: [10.0.0.15]
TASK [Create user02] *********************************************************************************
fatal: [10.0.0.15]: FAILED! => {"changed": true, "cmd": "useradd Young02", "delta": "0:00:00.031795", "end": "2021-12-01 09:54:55.574370", "msg": "non-zero return code", "rc": 9, "start": "2021-12-01 09:54:55.542575", "stderr": "useradd: user 'Young02' already exists", "stderr_lines": ["useradd: user 'Young02' already exists"], "stdout": "", "stdout_lines": []}
...ignoring
TASK [Create user03] *********************************************************************************
fatal: [10.0.0.15]: FAILED! => {"changed": false, "msg": "Unsupported parameters for (user) module: nam Supported parameters include: append, authorization, comment, create_home, expires, force, generate_ssh_key, group, groups, hidden, home, local, login_class, move_home, name, non_unique, password, password_lock, profile, remove, role, seuser, shell, skeleton, ssh_key_bits, ssh_key_comment, ssh_key_file, ssh_key_passphrase, ssh_key_type, state, system, uid, update_password"}
...ignoring
TASK [Create user04] *********************************************************************************
fatal: [10.0.0.15]: FAILED! => {"changed": true, "cmd": "useradd Young04", "delta": "0:00:00.031879", "end": "2021-12-01 09:54:56.092036", "msg": "non-zero return code", "rc": 9, "start": "2021-12-01 09:54:56.060157", "stderr": "useradd: user 'Young04' already exists", "stderr_lines": ["useradd: user 'Young04' already exists"], "stdout": "", "stdout_lines": []}
PLAY RECAP *******************************************************************************************
10.0.0.15 : ok=4 changed=1 unreachable=0 failed=1 skipped=0 rescued=0 ignored=2
6. 标签功能
- hosts: 主机IP地址
tasks:
- 模块名称: 参数
ignore_errors: yes
tags: 标签名 #指定标签名称
|
标签功能: 1. 便于剧本调试时,仅执行指定的模块和操作。使用指令ansible-playbook -t 标记点 剧本名称执行指定模块 2. 常与忽略错误功能一起使用,用于剧本调试。 |
- hosts: 10.0.0.15
tasks:
- name: Create user01
user:
name: Young01
tags: process_01
- name: Create user02
shell: useradd Young02
ignore_errors: yes
tags: process_02
[root@ansible-manager /etc/ansible/ansible-playbook]# cat tags_test.yaml
[root@ansible-manager /etc/ansible/ansible-playbook]# ansible-playbook -t process_01 tags_test.yaml
PLAY [10.0.0.15] *************************************************************************************
TASK [Gathering Facts] *******************************************************************************
ok: [10.0.0.15]
TASK [Create user01] *********************************************************************************
ok: [10.0.0.15]
PLAY RECAP *******************************************************************************************
10.0.0.15 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@ansible-manager /etc/ansible/ansible-playbook]# ansible-playbook -t process_02 tags_test.yaml
PLAY [10.0.0.15] *************************************************************************************
TASK [Gathering Facts] *******************************************************************************
ok: [10.0.0.15]
TASK [Create user02] *********************************************************************************
fatal: [10.0.0.15]: FAILED! => {"changed": true, "cmd": "useradd Young02", "delta": "0:00:00.031879", "end": "2021-12-01 10:13:12.920290", "msg": "non-zero return code", "rc": 9, "start": "2021-12-01 10:13:12.888411", "stderr": "useradd: user 'Young02' already exists", "stderr_lines": ["useradd: user 'Young02' already exists"], "stdout": "", "stdout_lines": []}
...ignoring
PLAY RECAP *******************************************************************************************
10.0.0.15 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1
7. 忽略采集功能
该功能不能用于含有判断功能的剧本中;
ansible在执行剧本的时候,默认第一步动作是搜集所有被管理主机信息,随着管理主机的增多,该步骤的耗时将越来越长;为了提了剧本执行效率,可使用忽略采集功能进行提速。 |
- hosts: 主机IP地址
gather_facts: no #关闭主机信息采集功能
tasks:
- 模块名称: 参数
|
- hosts: nfs
gather_facts: no
tasks:
- name: Pull file from remote host
fetch:
src: /etc/sysconfig/network-scripts/ifcfg-eth0
dest: /tmp
[root@ansible-manager /etc/ansible/ansible-playbook]# cat disabledGatherFact_test.yaml
[root@ansible-manager /etc/ansible/ansible-playbook]# ansible-playbook disabledGatherFact_test.yaml
PLAY [nfs] *******************************************************************************************
TASK [Pull file from remote host] ********************************************************************
changed: [10.0.0.15]
changed: [10.0.0.17]
changed: [10.0.0.16]
PLAY RECAP *******************************************************************************************
10.0.0.15 : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
10.0.0.16 : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
10.0.0.17 : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
8. 触发功能
当触发器项目处于changed状态时,执行触发器动作; |
- hosts: 主机IP地址
tasks:
- 模块名称: 参数
notify: 触发器名称 #引用触发器
handlers: #定义触发器
- name: 触发器名称
模块名称: 参数
|
[root@ansible-manager /etc/ansible/ansible-playbook]# vim trigger_test.yaml
- hosts: 10.0.0.15
tasks:
- name: Delivery config file to host
copy:
src: ./rsync/rsyncd.conf
dest: /etc/rsyncd.conf
notify: rsyncd_service
- name: Starting service
service:
name: rsyncd
state: started
handlers:
- name: rsyncd_service
service:
name: rsyncd
state: restarted
[root@ansible-manager /etc/ansible/ansible-playbook]# cat trigger_test.yaml
[root@ansible-manager /etc/ansible/ansible-playbook]# ansible-playbook trigger_test.yaml
PLAY [10.0.0.15] *************************************************************************************
TASK [Gathering Facts] *******************************************************************************
ok: [10.0.0.15]
TASK [Delivery config file to host] ******************************************************************
ok: [10.0.0.15]
TASK [Starting service] ******************************************************************************
ok: [10.0.0.15]
PLAY RECAP *******************************************************************************************
10.0.0.15 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@ansible-manager /etc/ansible/ansible-playbook]# ansible 10.0.0.15 -m shell -a "netstat -lntup|grep [r]sync"
10.0.0.15 | CHANGED | rc=0 >>
tcp 0 0 0.0.0.0:873 0.0.0.0:* LISTEN 13634/rsync
tcp6 0 0 :::873 :::* LISTEN 13634/rsync
[root@ansible-manager /etc/ansible/ansible-playbook]# sed -i s#'port = 873'#'port = 876'#g rsync/rsyncd.conf
[root@ansible-manager /etc/ansible/ansible-playbook]# ansible-playbook trigger_test.yaml
PLAY [10.0.0.15] *************************************************************************************
TASK [Gathering Facts] *******************************************************************************
ok: [10.0.0.15]
TASK [Delivery config file to host] ******************************************************************
changed: [10.0.0.15]
TASK [Starting service] ******************************************************************************
ok: [10.0.0.15]
RUNNING HANDLER [rsyncd_service] *********************************************************************
changed: [10.0.0.15]
PLAY RECAP *******************************************************************************************
10.0.0.15 : ok=4 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@ansible-manager /etc/ansible/ansible-playbook]# ansible 10.0.0.15 -m shell -a "netstat -lntup|grep [r]sync"
10.0.0.15 | CHANGED | rc=0 >>
tcp 0 0 0.0.0.0:876 0.0.0.0:* LISTEN 14490/rsync
tcp6 0 0 :::876 :::* LISTEN 14490/rsync
9. 汇总功能
汇总功能是将多个剧本进行整合; |
方式一: include_tasks
include_tasks的整合方法用的较少,是因为它所引用的剧本仅能包含tasks下面的任务内容; |
- hosts: 主机IP地址
tasks:
- include_tasks: 剧本1 #相对于当前剧本的相对路径
- include_tasks: 剧本2
......
|
# 剧本1
- hosts: 10.0.0.15
s: 10.0.0.15
s:
- name: Create_User
user:
name: "{{ item }}"
shell: /sbin/nologin create_home=no
with_items:
- Young01
- Young02
- Young03
# 剧本2
[root@ansible-manager /etc/ansible/ansible-playbook]# cat ignoreErr_test.yaml
- name: Create user01
user:
name: Young01
- name: Create user02
shell: useradd Young02
ignore_errors: yes
- name: Create user03
user:
nam: Young03
ignore_errors: yes
# 合成剧本
- hosts: 10.0.0.15
tasks:
- include_tasks: ignoreErr_test.yaml
- include_tasks: cycle_test1.yaml
- hosts:
- 10.0.0.16
- 10.0.0.17
tasks:
- include_tasks: ignoreErr_test.yaml
[root@ansible-manager /etc/ansible/ansible-playbook]# ansible-playbook include_tasks.yaml
PLAY [10.0.0.15] *************************************************************************************
TASK [Gathering Facts] *******************************************************************************
ok: [10.0.0.15]
TASK [include_tasks] *********************************************************************************
included: /etc/ansible/ansible-playbook/ignoreErr_test.yaml for 10.0.0.15
TASK [Create user01] *********************************************************************************
ok: [10.0.0.15]
TASK [Create user02] *********************************************************************************
fatal: [10.0.0.15]: FAILED! => {"changed": true, "cmd": "useradd Young02", "delta": "0:00:00.032157", "end": "2021-12-01 16:54:47.945938", "msg": "non-zero return code", "rc": 9, "start": "2021-12-01 16:54:47.913781", "stderr": "useradd: user 'Young02' already exists", "stderr_lines": ["useradd: user 'Young02' already exists"], "stdout": "", "stdout_lines": []}
...ignoring
TASK [Create user03] *********************************************************************************
fatal: [10.0.0.15]: FAILED! => {"changed": false, "msg": "Unsupported parameters for (user) module: nam Supported parameters include: append, authorization, comment, create_home, expires, force, generate_ssh_key, group, groups, hidden, home, local, login_class, move_home, name, non_unique, password, password_lock, profile, remove, role, seuser, shell, skeleton, ssh_key_bits, ssh_key_comment, ssh_key_file, ssh_key_passphrase, ssh_key_type, state, system, uid, update_password"}
...ignoring
TASK [include_tasks] *********************************************************************************
included: /etc/ansible/ansible-playbook/cycle_test1.yaml for 10.0.0.15
TASK [Create_User] ***********************************************************************************
changed: [10.0.0.15] => (item=Young01)
changed: [10.0.0.15] => (item=Young02)
changed: [10.0.0.15] => (item=Young03)
PLAY [10.0.0.16,10.0.0.17] ***************************************************************************
TASK [Gathering Facts] *******************************************************************************
ok: [10.0.0.16]
ok: [10.0.0.17]
TASK [include_tasks] *********************************************************************************
included: /etc/ansible/ansible-playbook/ignoreErr_test.yaml for 10.0.0.16, 10.0.0.17
TASK [Create user01] *********************************************************************************
changed: [10.0.0.17]
changed: [10.0.0.16]
TASK [Create user02] *********************************************************************************
changed: [10.0.0.16]
changed: [10.0.0.17]
TASK [Create user03] *********************************************************************************
fatal: [10.0.0.17]: FAILED! => {"changed": false, "msg": "Unsupported parameters for (user) module: nam Supported parameters include: append, authorization, comment, create_home, expires, force, generate_ssh_key, group, groups, hidden, home, local, login_class, move_home, name, non_unique, password, password_lock, profile, remove, role, seuser, shell, skeleton, ssh_key_bits, ssh_key_comment, ssh_key_file, ssh_key_passphrase, ssh_key_type, state, system, uid, update_password"}
...ignoring
fatal: [10.0.0.16]: FAILED! => {"changed": false, "msg": "Unsupported parameters for (user) module: nam Supported parameters include: append, authorization, comment, create_home, expires, force, generate_ssh_key, group, groups, hidden, home, local, login_class, move_home, name, non_unique, password, password_lock, profile, remove, role, seuser, shell, skeleton, ssh_key_bits, ssh_key_comment, ssh_key_file, ssh_key_passphrase, ssh_key_type, state, system, uid, update_password"}
...ignoring
PLAY RECAP *******************************************************************************************
10.0.0.15 : ok=7 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=2
10.0.0.16 : ok=5 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1
10.0.0.17 : ok=5 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1
方式2: include
- include: 剧本1 #相对于当前剧本的相对路径 - include: 剧本2 ...... |
- hosts: 10.0.0.15
vars:
user_name: www
tasks:
- name: Display user info
command: id {{ user_name }}
register: user_info
- name: Display result
debug:
msg:
- "{{ user_info.stdout_lines }}"
- hosts: 10.0.0.15
tasks:
- name: Create_User
user:
name: "{{ item }}"
shell: /sbin/nologin
create_home: no
with_items:
- Young01
- Young02
- Young03
- include: ansible-playbook/cycle_test1.yaml
- include: ansible-playbook/register_test.yaml
[root@ansible-manager /etc/ansible]# ansible-playbook include.yaml
[DEPRECATION WARNING]: 'include' for playbook includes. You should use 'import_playbook' instead.
This feature will be removed in version 2.12. Deprecation warnings can be disabled by setting
deprecation_warnings=False in ansible.cfg.
PLAY [10.0.0.15] *************************************************************************************
TASK [Gathering Facts] *******************************************************************************
ok: [10.0.0.15]
TASK [Create_User] ***********************************************************************************
changed: [10.0.0.15] => (item=Young01)
changed: [10.0.0.15] => (item=Young02)
changed: [10.0.0.15] => (item=Young03)
PLAY [10.0.0.15] *************************************************************************************
TASK [Gathering Facts] *******************************************************************************
ok: [10.0.0.15]
TASK [Display user info] *****************************************************************************
changed: [10.0.0.15]
TASK [Display result] ********************************************************************************
ok: [10.0.0.15] => {
"msg": [
[
"uid=2000(www) gid=2000(www) groups=2000(www)"
]
]
}
PLAY RECAP *******************************************************************************************
10.0.0.15 : ok=5 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
方式3: import_playbook
- import_playbook: 剧本1 #相对于当前剧本的相对路径 - import_playbook: 剧本2 ...... |
- import_playbook: ansible-playbook/cycle_test1.yaml
- import_playbook: ansible-playbook/register_test.yaml
[root@ansible-manager /etc/ansible]# ansible-playbook import_playbook.yaml
PLAY [10.0.0.15] *************************************************************************************
TASK [Gathering Facts] *******************************************************************************
ok: [10.0.0.15]
TASK [Create_User] ***********************************************************************************
ok: [10.0.0.15] => (item=Young01)
ok: [10.0.0.15] => (item=Young02)
ok: [10.0.0.15] => (item=Young03)
PLAY [10.0.0.15] *************************************************************************************
TASK [Gathering Facts] *******************************************************************************
ok: [10.0.0.15]
TASK [Display user info] *****************************************************************************
changed: [10.0.0.15]
TASK [Display result] ********************************************************************************
ok: [10.0.0.15] => {
"msg": [
[
"uid=2000(www) gid=2000(www) groups=2000(www)"
]
]
}
PLAY RECAP *******************************************************************************************
10.0.0.15 : ok=5 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
六、ansible-playbook角色
ansible-playbook角色功能是由ansible公司提出的剧本规划化配置; |
- 名称规范
- 目录规范
1. 规范化操作流程
本文以rsyncd服务部署为例
在/etc/ansible/roles目录下创建,角色目录;目录名称可自定义。 |
step 01 创建角色目录
mkdir 角色名 #为角色创建子目录 |
[root@ansible-manager /etc/ansible]# cd
[root@ansible-manager ~]# cd /etc/ansible/roles/
[root@ansible-manager /etc/ansible/roles]# mkdir rsync
step 02 在角色目录中创建规范化子目录
mkdir {tasks,handlers,vars,files,templates} #为角色创建子目录 |
tasks #包含觉得需要执行的主要任务列表 handlers #包含处理程序,可以由此角色使用,甚至可以在此角色之外的任何位置使用 defaults #角色的默认变量 vars #角色的其他变量 files #包含可以通过此角色部署的文件 templates #包含可以通过此角色部署的模板 meta #为此角色定义一些元数据 |
[root@ansible-manager /etc/ansible/roles]# cd rsync/
[root@ansible-manager /etc/ansible/roles/rsync]# mkdir {tasks,vars,files,handlers,templates}
[root@ansible-manager /etc/ansible/roles/rsync]# tree .
.
├── files
├── handlers
├── tasks
├── templates
└── vars
5 directories, 0 files
step 03 进入tasks目录,创建剧本主体任务
vim main.yaml #剧本名称必须为main.yaml |
[root@ansible-manager /etc/ansible/roles/rsync]# cd tasks/
[root@ansible-manager /etc/ansible/roles/rsync/tasks]# vim main.yml
# Server
- name: Install rsync service
yum:
name: rsync
state: installed
- name: Delivery File
copy:
src: "{{ item.src }}"
dest: "{{ Dest_path }}"
mode: "{{ item.mode }}"
with_items:
- {src: 'rsyncd.conf', mode: '644'}
- {src: 'rsyncd_server.password', mode: '600'}
notify: rsyncd_restart
when: (ansible_hostname == "web01")
- name: Create virtual user for rsync
user:
name: rsync
shell: /sbin/nologin
create_home: no
when: (ansible_hostname == "web01")
- name: Create directory for backup
file:
path: "{{ item.path }}"
state: directory
owner: "{{ item.owner }}"
group: "{{ item.group }}"
with_items:
- {path: '/backup', owner: 'rsync', group: 'rsync'}
when: (ansible_hostname == "web01")
- name: Start service
service:
name: rsyncd
state: started
enabled: yes
when: (ansible_hostname == "web01")
- name: register port info
shell: netstat -lntup | grep [r]sync
register: Port_info
tags: Check_Port
when: (ansible_hostname == "web01")
- name: Check service port
debug:
msg:
- "{{ Port_info.stdout_lines }}"
when: (ansible_hostname == "web01")
tags: Display_Port
#Client
- name: Delivery password for client
copy:
content: "{{ Rsync_password}}"
dest: "{{ Dest_path }}rsync_client.password"
mode: 600
when: (ansible_hostname != "web01")
step 04 进入vars目录,定义相关变量参数
vim main.yaml #剧本名称必须为main.yaml |
[root@ansible-manager /etc/ansible/roles/rsync/tasks]# cd ../vars/
[root@ansible-manager /etc/ansible/roles/rsync/vars]# vim main.yaml
Dest_path: /etc/
Rsync_password: '123456'
step 05 进入files目录,整理剧本需分发的文件
[root@ansible-manager /etc/ansible/roles/rsync/vars]# cd ../files/
[root@ansible-manager /etc/ansible/roles/rsync/files]# cp -rp ../../../ansible-playbook/rsync/rsyncd.conf .
[root@ansible-manager /etc/ansible/roles/rsync/files]# echo "rsync_backup:123456" >rsyncd_server.password
[root@ansible-manager /etc/ansible/roles/rsync/files]# ls
rsyncd.conf rsyncd_server.password
step 06 进入handlers目录,定义触发器操作
vim main.yaml #剧本名称必须为main.yaml |
[root@ansible-manager /etc/ansible/roles/rsync/files]# cd ../handlers/
[root@ansible-manager /etc/ansible/roles/rsync/handlers]# vim main.yaml
- name: rsyncd_restart
service:
name: rsyncd
state: restarted
step 07 进入roles目录,创建汇总剧本
- hosts: 主机IP地址
roles:
- 角色名1
- 角色名2
......
|
- hosts: rsync
roles:
- rsync
[root@ansible-manager /etc/ansible/roles]# cat execute_rsync.yml
[root@ansible-manager /etc/ansible/roles]# sed s#'port = 873'#'port = 874'#g rsync/files/rsyncd.conf -i
[root@ansible-manager /etc/ansible/roles]# ansible-playbook execute_rsync.yml
PLAY [rsync] *****************************************************************************************
TASK [Gathering Facts] *******************************************************************************
ok: [10.0.0.17]
ok: [10.0.0.15]
ok: [10.0.0.16]
TASK [Install rsync service] *************************************************************************
ok: [10.0.0.16]
ok: [10.0.0.17]
ok: [10.0.0.15]
TASK [rsync : Delivery File] *************************************************************************
skipping: [10.0.0.16] => (item={u'src': u'rsyncd.conf', u'mode': u'644'})
skipping: [10.0.0.16] => (item={u'src': u'rsyncd_server.password', u'mode': u'600'})
skipping: [10.0.0.17] => (item={u'src': u'rsyncd.conf', u'mode': u'644'})
skipping: [10.0.0.17] => (item={u'src': u'rsyncd_server.password', u'mode': u'600'})
changed: [10.0.0.15] => (item={u'src': u'rsyncd.conf', u'mode': u'644'})
ok: [10.0.0.15] => (item={u'src': u'rsyncd_server.password', u'mode': u'600'})
TASK [Create virtual user for rsync] *****************************************************************
skipping: [10.0.0.16]
skipping: [10.0.0.17]
ok: [10.0.0.15]
TASK [rsync : Create directory for backup] ***********************************************************
skipping: [10.0.0.16] => (item={u'owner': u'rsync', u'path': u'/backup', u'group': u'rsync'})
skipping: [10.0.0.17] => (item={u'owner': u'rsync', u'path': u'/backup', u'group': u'rsync'})
ok: [10.0.0.15] => (item={u'owner': u'rsync', u'path': u'/backup', u'group': u'rsync'})
TASK [rsync : Start service] *************************************************************************
skipping: [10.0.0.16]
skipping: [10.0.0.17]
ok: [10.0.0.15]
TASK [rsync : register port info] ********************************************************************
skipping: [10.0.0.16]
skipping: [10.0.0.17]
changed: [10.0.0.15]
TASK [rsync : Check service port] ********************************************************************
ok: [10.0.0.15] => {
"msg": [
[
"tcp 0 0 0.0.0.0:873 0.0.0.0:* LISTEN 11493/rsync ",
"tcp6 0 0 :::873 :::* LISTEN 11493/rsync "
]
]
}
skipping: [10.0.0.16]
skipping: [10.0.0.17]
TASK [rsync : Delivery password for client] **********************************************************
skipping: [10.0.0.15]
ok: [10.0.0.17]
ok: [10.0.0.16]
RUNNING HANDLER [rsyncd_restart] *********************************************************************
changed: [10.0.0.15]
PLAY RECAP *******************************************************************************************
10.0.0.15 : ok=9 changed=3 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
10.0.0.16 : ok=3 changed=0 unreachable=0 failed=0 skipped=6 rescued=0 ignored=0
10.0.0.17 : ok=3 changed=0 unreachable=0 failed=0 skipped=6 rescued=0 ignored=0
[root@ansible-manager /etc/ansible/roles]# ansible-playbook -t Check_Port -t Display_Port execute_rsync.yml
PLAY [rsync] *****************************************************************************************
TASK [Gathering Facts] *******************************************************************************
ok: [10.0.0.15]
ok: [10.0.0.16]
ok: [10.0.0.17]
TASK [rsync : register port info] ********************************************************************
skipping: [10.0.0.16]
skipping: [10.0.0.17]
changed: [10.0.0.15]
TASK [rsync : Check service port] ********************************************************************
ok: [10.0.0.15] => {
"msg": [
[
"tcp 0 0 0.0.0.0:874 0.0.0.0:* LISTEN 13091/rsync ",
"tcp6 0 0 :::874 :::* LISTEN 13091/rsync "
]
]
}
skipping: [10.0.0.16]
skipping: [10.0.0.17]
PLAY RECAP *******************************************************************************************
10.0.0.15 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
10.0.0.16 : ok=1 changed=0 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0
10.0.0.17 : ok=1 changed=0 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0
2. 角色说明
角色的主要用于实现剧本,任务一键化执行,进行批量管理;并且在一键化执行过程中,规划要求整个剧本文件目录的目录结构以及 剧本名称; |
剧本执行过程
templates目录说明
templates目录用于保存模板配置文件;在templates中保存的配置文件可以引用vars/main.yml中的变量; 注意:分发templates目录中的文件,需要调用变量,需使用template模块替换copy模块;两者参数基本一致; |
NFS 一键化部署配置规范化案例
# summary
- hosts: nfs
roles:
- nfs
# tasks
- name: Install Services
yum:
name:
- rpcbind
- nfs-utils
state: installed
- name: Create nfs group
group:
name: "{{ Nfs_name }}"
gid: "{{ Nfs_ID }}"
- name: Create nfs user
user:
name: "{{ Nfs_name }}"
shell: /sbin/nologin
create_home: no
group: "{{ Nfs_ID }}"
uid: "{{ Nfs_ID }}"
- name: Create shared directory
file:
path: "{{ item }}"
state: directory
owner: "{{ Nfs_name }}"
group: "{{ Nfs_name }}"
with_items:
- /backup/www/test
when: (ansible_hostname == 'web01')
- name: Delivery config file
template:
src: exports
dest: "{{ Dest_dir }}"
notify: restart_nfs
when: (ansible_hostname == 'web01')
- name: Start service
service:
name: "{{ item }}"
state: started
enabled: yes
with_items:
- rpcbind
- nfs-server
when: (ansible_hostname == 'web01')
- name: Create mount point
file:
path: "{{ item }}"
state: directory
with_items:
- /var/www/test_dir
when: (ansible_hostname != 'web01')
- name: Mount NFS file system
mount:
src: "{{ NfsS_IP }}:{{ item.srcdir }}"
path: "{{ item.dstdir }}"
fstype: nfs
state: mounted
with_items:
- {srcdir: '/backup/www/test', dstdir: '/var/www/test_dir'}
when: (ansible_hostname != 'web01')
- name: Check info
shell: "tail -1 /etc/fstab"
register: mount_info
- name: Display info
debug:
msg:
- "{{ mount_info.stdout_lines }}"
# vars
[root@ansible-manager /etc/ansible/roles]# cat nfs/vars/main.yml
Nfs_ID: "3000"
Nfs_name: test
Dest_dir: /etc/
NfsS_IP: 172.16.1.15
Shared_dir: /backup/www/test
Shared_ip: 172.16.1.0/24
# handlers
- name: restart_nfs
service:
name: nfs-server
state: reloaded
[root@ansible-manager /etc/ansible/roles]# cat nfs/templates/exports
{{Shared_dir}} {{ Shared_ip}}(rw,sync,anonuid={{ Nfs_ID }},anongid={{ Nfs_ID }})
[root@ansible-manager /etc/ansible/roles]# tree nfs
nfs
├── files
├── handlers
│ └── main.yml
├── tasks
│ └── main.yml
├── templates
│ └── exports
└── vars
└── main.yml
5 directories, 4 files
[root@ansible-manager /etc/ansible/roles]# ansible-playbook --syntax-check execute_nfs.yml
[WARNING]: Could not match supplied host pattern, ignoring: nfs
playbook: execute_nfs.yml
[root@ansible-manager /etc/ansible/roles]# ansible-playbook -i hosts execute_nfs.yml
PLAY [nfs] *******************************************************************************************
TASK [Gathering Facts] *******************************************************************************
ok: [10.0.0.17]
ok: [10.0.0.15]
ok: [10.0.0.16]
TASK [nfs : Install Services] ************************************************************************
ok: [10.0.0.15]
ok: [10.0.0.16]
ok: [10.0.0.17]
TASK [Create nfs group] ******************************************************************************
ok: [10.0.0.16]
ok: [10.0.0.17]
ok: [10.0.0.15]
TASK [Create nfs user] *******************************************************************************
ok: [10.0.0.16]
ok: [10.0.0.17]
ok: [10.0.0.15]
TASK [nfs : Create shared directory] *****************************************************************
skipping: [10.0.0.16] => (item=/backup/www/test)
skipping: [10.0.0.17] => (item=/backup/www/test)
ok: [10.0.0.15] => (item=/backup/www/test)
TASK [nfs : Delivery config file] ********************************************************************
skipping: [10.0.0.16]
skipping: [10.0.0.17]
changed: [10.0.0.15]
TASK [nfs : Start service] ***************************************************************************
skipping: [10.0.0.16] => (item=rpcbind)
skipping: [10.0.0.16] => (item=nfs-server)
skipping: [10.0.0.17] => (item=rpcbind)
skipping: [10.0.0.17] => (item=nfs-server)
ok: [10.0.0.15] => (item=rpcbind)
ok: [10.0.0.15] => (item=nfs-server)
TASK [nfs : Create mount point] **********************************************************************
skipping: [10.0.0.15] => (item=/var/www/test_dir)
ok: [10.0.0.17] => (item=/var/www/test_dir)
ok: [10.0.0.16] => (item=/var/www/test_dir)
TASK [nfs : Mount NFS file system] *******************************************************************
skipping: [10.0.0.15] => (item={u'dstdir': u'/var/www/test_dir', u'srcdir': u'/backup/www/test'})
changed: [10.0.0.16] => (item={u'dstdir': u'/var/www/test_dir', u'srcdir': u'/backup/www/test'})
changed: [10.0.0.17] => (item={u'dstdir': u'/var/www/test_dir', u'srcdir': u'/backup/www/test'})
TASK [nfs : Check info] ******************************************************************************
changed: [10.0.0.16]
changed: [10.0.0.17]
changed: [10.0.0.15]
TASK [nfs : Display info] ****************************************************************************
ok: [10.0.0.15] => {
"msg": [
[
"UUID=42eaa7c4-975b-4c3a-8301-1e4543eb730e swap swap defaults 0 0"
]
]
}
ok: [10.0.0.16] => {
"msg": [
[
"172.16.1.15:/backup/www/test /var/www/test_dir nfs defaults 0 0"
]
]
}
ok: [10.0.0.17] => {
"msg": [
[
"172.16.1.15:/backup/www/test /var/www/test_dir nfs defaults 0 0"
]
]
}
RUNNING HANDLER [restart_nfs] ************************************************************************
changed: [10.0.0.15]
PLAY RECAP *******************************************************************************************
10.0.0.15 : ok=10 changed=3 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0
10.0.0.16 : ok=8 changed=2 unreachable=0 failed=0 skipped=3 rescued=0 ignored=0
10.0.0.17 : ok=8 changed=2 unreachable=0 failed=0 skipped=3 rescued=0 ignored=0
[root@ansible-manager /etc/ansible/roles]# ansible 10.0.0.15 -m shell -a "cat /etc/exports"
10.0.0.15 | CHANGED | rc=0 >>
/backup/www/test 172.16.1.0/24(rw,sync,anonuid=3000,anongid=3000)