ansible

运维自动化之ANSLBLE

本章内容
运维自动化发展历程及技术应用
ansible命令使用
absible常用模块详解
YAML语法
Ansible palybook基础
Playbook变量,tags、handlers使用
Playbook模块 templates
Playbook条件判断when
Playbook字典with_items
Ansible Roles

自动化运维应用场景

image-20210801164640069

文件传输
应用部署(软件升级)
配置管理
任务流编排

常用自动化运维工具

  • Ansible:python,Agentless,中小型应用环境
    Saltstack:python,一般需部署agent,执行效率更高
    Puppet:ruby,功能强大,配置复杂,重型,适合大型环境
    Fabric:python,agentless
    Chef:ruby,国内应用少
    Cfengine
    func

Ansible发展史
作者:Michakl DaHaan (Cobbke与Func作者)
ansible的名称来自《安德的游戏》中跨越时空的即时通信工具
2012-03-09发布0.0.1版 2015-10-17,RedHat宣布1.5亿美金收购
官网:https://www.ensible.com/
官方文档:https://www.docs.ansible.com/

Ansible特性

模块化:调用特定的模块,完成特定任务
Paramiko(ptyhon对ssh的实现),PyYAML,jinja2(模块语言)三个关键模块
支持自定义模块,可使用任何编程语言写模块
基于python实现
部署简单,基于python和ssh(默认以安装),agentless,无需代理不依赖PKI(无需ssl)
安全,基于Openssh
幂等性:一个任务执行1遍和执行n遍效果一样,不因重复执行带来意外情况
支持playbook编排任务,YAML格式,编排任务,支持丰富的数据结构
较强大的多层解决方案role

Ansible架构

image-20210801213738793

组合INVENTORY,API,MODULES,PLUGINS的绿框,可以理解为是ansible命令工具,其为核心执行工具
INVENTORY:Ansble管理主机的清单/etc/ananaible/hosts
MODULES:ansible执行命令的功能模块,多为内核模块,也可自定义
PLUGINS:模块功能的补充,如连接类型插件,循环插件,变量插件等,该功能不常用
API:供第三方程序调用的应用程序编程接口

Ansible 命令执行来源

USER普通用户,既SYSTEM ADMINISTRATOR
PLAYBOOK:认为你剧本(任务集),编排定义1Ansible任务集的配置文件,由Ansible顺序依次执行,通常是JSON格式的YAML文件
CMDO(配置管理数据库)API调用
PUBLIC/PRIVATE CLOUD API调用
USER->Ansible Playbook -> Ansible

注意事项

执行ansible的主机一般称为主控端,中控,master或堡垒机
主控端python版本需要2.6或以上
被控端端版本小于2.4需要安装python-simplejson
被控端如开启SElinux需要安装libselinux-python
Windows不能作为主控端 可以当客户端

Ansible安装和入门

Ansible安装

ansible的安装方法有很多种
EPEL源的rpm包安装
yum install ansible

| 编译安装                                                     |
| ------------------------------------------------------------ |
| yum     -y   install  python-jinja2  PyYAML  python-paramiko  python-babel  python-    cryto |
 tar  xf  ansible-1.5.4.tar.gz                                |
 cd  ansible-1.5.4        
 python setup.py  build
 python  setup.py  install
 mkdir  /etc/ansible
 cp  -r  examples/*   /etc/ansible
Git方式

git clone git://github.com/ansible/ansible.git --recursive
cd ./ansible
source ./hacking/env–setup

pip安装

pip是安装python包的管理器,类似yum
yum install python-pip python-devel
yum install gcc glibc-devel zibl-devel rpm-bulid openssl-devel
pip install --upgrade pip
pip install ansible --upgrade

确认安装
ansible --version

[root@ansible ~]# ansible  --version
ansible 2.9.23
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.5 (default, Oct 14 2020, 14:45:30) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)]

centos7安装
image-20210802220800454

Ansible 相关文件

/etv/ansible/ansible.cfg 主配置文件,配置ansible工作特性
/etc/ansible/hosts 主机清单
/etc/ansible/roles/ 存放角色的目录

Ansible主配置文件

ansible 的配置文件/etc/ansible/ansible.cfg,其中大部分配置内容无需进行修改

[defaults]
#inventory = /etc/ansible/ hosts#主机列表配置文件
#library = /usr/share/ my_modules/#库文件存放目录
#remote_tmp = $HOME/.ansible/tmp#临时py命令文件存放在远程主机目录
#local_tmp  =  $HOME/.ansible/tmp#本机的临时命令执行目录
#forks   =  5#默认并发数
#sudo_user     =   root    #默认sudo用户
#ask_sudo_pass =  True  #每次执行 ansi1e命令是否询问ssh密码
#ask_pass  =  True
#remote_port 22
#host_key_checking =  False#检查对应服务器的 host_key,建议取消注释
#log_path = /var/log/ ansible.log#日志文件,建议启
#module _name =  command#默认模块,可以修改为she11模块

111行[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FNfQDD6H-1637840564484)(D:/Typora/image-20210803094535354.png)]

inventory主机清单

ansible的主要功用在于批量主机操作,为了便捷地使用其中的部分主机,可以在inventory file中将其分组命名默认的inventory file为 /etc/ansible/hosts
inventory file可以有很多个,且也可以通过Dynamic inventory来动态生成

主机清单文件格式

inventory文件遵循INI文件格式,中括号的字符为组名,可以将同一个主机归并到多个不同的组中

此外,当如若目标主机使用了非默认的SSH端口查看ss -ntl,还可以在名称之后使用冒号加端口来标明

如果主机名称遵循相似的命名模式,还可以使用列表的方式标识各主机

配置文件在vim /etc/ansible/hostsimage-20210803100011743

分成了几个类

image-20210803100409500
Ansible相关工具

/usr/bin/ansible 主程序,临时命令执行工具

/usr/bin/ansible-doc 查看配置文档,模块功能查看工具

/usr/bin/ansible-galaxy 下载/上传优秀代码或Roles模块的官网平台

/usr/bin/ansible-playbook 定制自动化任务,编排剧本工具

/usr/bin/ansible-pull 远程执行命令的工具

/usr/bin/ansible-vault 文件加密工具

/usr/bin/ansible-console 基于Console界面与用户交互的执行工具

利用ansible实现管理的主要方式

Ad-Hoc即利用ansible命令,主要用于临时命令使用场景

Ansible-playbook 主要用于长期规划好的,大型项目的场景,需要有前期的规划过程

ansible-doc

此工具用来显示模块帮助

格式

ansible-doc   [options] [module..]
-l   --list    #列出可用模块
-s   --snippet #显示指定模块的playbook片段

范例:

 #列出所有模块
ansible -doc  -l
#查看指定模块帮助用法
ansible -doc  ping
查看指定模块帮助用法
ansible  -doc  -s ping
ansible

此工具通过ssh协议,实现对远程主机的配置管理,应用部署,任务执行等功能

建议:使用此工具前,先配置ansible主控端能基于密钥认证的方式联系各个被管理节点

范例:利用sshpass批量实现基于key验证

ssh-keygen  -f  /root/.ssh/id_rsa  -p ''
NET=192.168.100
export  SSHPASS=123.com
for  IP  in {1..222};do
	sshpass  -e  ssh-copy-id   $NET.$IP
done

格式

ansible   <host-pattern>  [-m  module_name] [-a args]

选项说明:

选项说明
verslon    	     #显示版本
-m module  	     #指定模块,默认为 command
-v         	     #井详细过程   -vv -vvv更详细
--list-hosts     #显示主机列表,可简写--1ist
-k, --ask-pass   #提示输入ssh连接密码,默认key验证
-C,  --check     #检查,并不执行
-T,-- tImeout=TIMEOUT #执行命令的超时时间,默认10s
-u,--user= REMOTE_USER#执行远程执行的用户
-b, --become #代替旧版的sudo切换
--become-user= USERNAME#指定sudo的 runas用户,默认为root
-K, --ask-become-pass #提示输入sudo时的口令

小实验 为什么会错误呢 因为第一次没有输入yes
image-20210803104158548

image-20210803104338339

启用起来 就不会爆出来

image-20210803105221592

以及把他们的文件放进去了 为什么还失败了 默认基于key验证 所以就失败了 可以基于用户名密码

image-20210803105337172

绿色代表成功 因为 192.168.10.18的密码和其他两台主机的密码不一样所以连接不成功 pong表示成功的意思

image-20210803105705791

把192.168.10.18的密码改成和其他两位主机一样的密码就可以了

image-20210803105847576

基于key验证就需要把ssh密钥发送给其他客户机

[root@node ~]# ssh-keygen 
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:dXk3x4TEsUGdWI7iUBriR2vtgm46O9Iiby+UVHIBg98 root@node
The key's randomart image is:
+---[RSA 2048]----+
|  .o.... o . +B=o|
| . ..o. o *  o=*.|
|  . =  . *.oo.oo+|
|   o E  +.+... .o|
|  . .  .S. o     |
|   o  .   .      |
|  . .  o         |
| . = +o          |
|  +.=++          |
+----[SHA256]-----+
[root@node ~]# ssh-copy-id   192.168.10.16
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@192.168.10.16's password: 

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh '192.168.10.16'"
and check to make sure that only the key(s) you wanted were added.

[root@node ~]# ssh-copy-id   192.168.10.17
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@192.168.10.17's password: 

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh '192.168.10.17'"
and check to make sure that only the key(s) you wanted were added.

[root@node ~]# ssh-copy-id   192.168.10.18
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@192.168.10.18's password: 

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh '192.168.10.18'"
and check to make sure that only the key(s) you wanted were added.

[root@node ~]# ansible   all   -m ping
192.168.10.18 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
192.168.10.16 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
192.168.10.17 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}

查看以管理的机器 也可以是分组名字

[root@node ~]# ansible all  --list-hosts
  hosts (3):
    192.168.10.16
    192.168.10.17
    192.168.10.18

通配符*

image-20210804101300105
ansible命令执行过程

1.加载自己的配置文件 默认/etc/ansible/ansible.cfg
2.加载自己对应的模块文件,如:command
3.通过ansible将模块或命令生成对应的临时py文件,并将该文件传输至远程服务器的对应执行用户 $HOME/.ansible/tmp/ansible-tmp-数字/XXX.PY文件
4.给文件+x执行
5.执行并返回结果
6.删除临时py文件,退出

ansible的执行状态:
[root@node ~]# grep  -A   13 '\[colors\]'  /etc/ansible/ansible.cfg 
[colors]
#highlight = white
#verbose = blue
#warn = bright purple
#error = red
#debug = dark gray
#deprecate = purple
#skip = cyan
#unreachable = red
#ok = green
#changed = yellow
#diff_add = green
#diff_remove = red
#diff_lines = cyan
  • 绿色:执行成功并且不需要做改变的操作
  • 黄色:执行成功并且对目标主机做变更
  • 红色:执行失败
image-20210804104320189
ansible-galaxy

此工具会连接https://galaxy.ansible.com下载相应的roles(角色)

image-20210804110420395
ansible-pull

此工具会推送ansible的命令至远程,效率无限提升,对运维要求较高

ansible-playbook

此工具用于执行编写好的playbook任务

范例:

ansible-playbook  hello.yml
cat  hellp.yml
---
#hello  word  yml  file
- hosts: websrvs
  remote_user: root
  tasks: 
  	- name: hello word
  	  command: /usr/bin/wall  hello wold
ansible-vault

此工具可以用于加密解密yml文件

格式

ansible-vault  [create|decrypt|edit|encrypt|rekey|view]

范例

ansible-vault  encrypt  hello.yml       #加密
ansible-vault  decrypt  hello.yml       #解密
ansible-vault  view     hello.yml       #查看
ansible-vault  edit     hello.yml       #编辑加密文件
ansible-vault  rekey    hello.yml       #修改口令
ansible-vault  create   new.yml         #创建新文件
ansible-console

此工具可交互执行命令,支持tab,ansible 2.0+新增

执行用户@当前操作的主机组(当前的主机数量)[f:并发量]$

常用子命令:

  • 设置并发数:forks n 例如:forks 10
  • 切换组: cd 主机组 例如:cd web
  • 列出当前主机列表:list
Welcome to the ansible console.
Type help or ? to list commands.

root@all (3)[f:5]$ list
192.168.10.16
192.168.10.17
192.168.10.18
root@all (3)[f:5]$ cd  appsrvs
root@appsrvs (3)[f:5]$ list
192.168.10.16
192.168.10.17
192.168.10.18
root@* (3)[f:5]$ cd websrvs
root@websrvs (2)[f:5]$ list
192.168.10.16
192.168.10.17
root@websrvs (2)[f:5]$ cd dbsrvs
root@dbsrvs (1)[f:5]$ list
192.168.10.17
root@dbsrvs (1)[f:5]$ cd
root@* (3)[f:5]$ forks 10
root@* (3)[f:10]$ 

Ansible常用模块 ansible-doc -s 可以查看模块用法

1.1.0 Command模块

功能:在远程主机执行命令,此为默认模块,可忽略-m选项

注意:此命令不支持$VARNAME < > | ; &等,用shell模块实现
范例:

[root@node ~]# ansible  websrvs  -m command   -a 'cat  /etc/centos-release'
#websrvs 指/etc/ansible/hosts  下面的组
192.168.10.17 | CHANGED | rc=0 >>
CentOS Linux release 7.3.1611 (Core) 
192.168.10.16 | CHANGED | rc=0 >>
CentOS Linux release 7.3.1611 (Core) 
[root@node ~]# ansible  websrvs  -m command   -a 'chdir=/etc   cat centos-release'
192.168.10.17 | CHANGED | rc=0 >>
CentOS Linux release 7.3.1611 (Core) 
192.168.10.16 | CHANGED | rc=0 >>
CentOS Linux release 7.3.1611 (Core) 
#跟这个意思一样
#[root@node ~]# cd  /etc/  ;  cat  centos-release
#CentOS Linux release 7.9.2009 (Core)
[root@node etc]# ansible  websrvs  -m command   -a 'chdir=/etc creates=/data/f1.txt   cat centos-release'
192.168.10.17 | CHANGED | rc=0 >>
CentOS Linux release 7.3.1611 (Core) 
192.168.10.16 | CHANGED | rc=0 >>
CentOS Linux release 7.3.1611 (Core) 
creates的命令是如果这个文件存在将不会执行下一条命令 如果不存在将执行下一条命令
#如果在  IP 17 上有这个文件将不会执行下一条命令
[root@node ~]# ansible  websrvs  -m command   -a 'chdir=/etc creates=/data/f1.txt   cat centos-release'
192.168.10.17 | SUCCESS | rc=0 >>
skipped, since /data/f1.txt exists
192.168.10.16 | CHANGED | rc=0 >>
CentOS Linux release 7.3.1611 (Core) 
removes 的命令是 creates 反过来的意思如果如这个文件的话  会执行下一条命令,如果没有的话将不会执行下一条命令
[root@node ~]# ansible  websrvs  -m command   -a 'chdir=/etc removes=/data/f1.txt   cat centos-release'
192.168.10.17 | CHANGED | rc=0 >>
CentOS Linux release 7.3.1611 (Core) 
192.168.10.16 | SUCCESS | rc=0 >>
skipped, since /data/f1.txt does not exist

1.1.1 Shell模块

功能和:Command相似,用shell执行命令
范例

ansible   wevsrvs  -m  shell  -a  'echo  1234.com   | passwd --stdin root '
[root@node ~]# ansible websrvs   -m shell  -a   "echo  $HOSTNAME"
192.168.10.16 | CHANGED | rc=0 >>
node
192.168.10.17 | CHANGED | rc=0 >>
node
[root@node ~]# ansible websrvs   -m shell  -a   'echo  $HOSTNAME'
192.168.10.17 | CHANGED | rc=0 >>
localhost.localdomain
192.168.10.16 | CHANGED | rc=0 >>
localhost.localdomain


[root@node ~]# ansible websrvs   -m shell  -a   ' echo  hello  >  /tmp/hello.log'
192.168.10.17 | CHANGED | rc=0 >>

192.168.10.16 | CHANGED | rc=0 >>

[root@node ~]# ansible websrvs   -m shell  -a   ' cat /tmp/hello.log'
192.168.10.17 | CHANGED | rc=0 >>
hello
192.168.10.16 | CHANGED | rc=0 >>
hello
[root@node ~]# ansible websrvs   -m shell  -a   ' chdir=/tmp  cat hello.log'
192.168.10.17 | CHANGED | rc=0 >>
hello
192.168.10.16 | CHANGED | rc=0 >>
hello

注意调用bash执行命令 类似cat/tmp/test.md | awk -F “|” ‘{print 1,2}’ &> /tmp/example.txt这些复杂命令,即使使用shell也可能会失败,解决办法:写到脚本时,copy到远程,执行,再把需要的结果拉回执行命令的机器

将默认模块command改为shell vim/etc/ansible/ansible.cfg

module_name = shell

1.1.2Script模块

功能:在远程主机上运行ansible服务器上的脚本

ansible  websrvs   -m  script   -a   '/data/test.sh'
[root@node ~]# ansible  websrvs  -m  script   -a  '/data/test.sh'
192.168.10.17 | CHANGED => {
    "changed": true, 
    "rc": 0, 
    "stderr": "Shared connection to 192.168.10.17 closed.\r\n", 
    "stderr_lines": [
        "Shared connection to 192.168.10.17 closed."
    ], 
    "stdout": "My hostname is localhost.localdomain\r\n", 
    "stdout_lines": [
        "My hostname is localhost.localdomain"
    ]
}
192.168.10.16 | CHANGED => {
    "changed": true, 
    "rc": 0, 
    "stderr": "Shared connection to 192.168.10.16 closed.\r\n", 
    "stderr_lines": [
        "Shared connection to 192.168.10.16 closed."
    ], 
    "stdout": "My hostname is localhost.localdomain\r\n", 
    "stdout_lines": [
        "My hostname is localhost.localdomain"
    ]
}
假如将这个脚本慢放100秒就会在客户端显示  一百秒之内显示一百秒之外就自动删除了crtl+c也会自动删除
[root@localhost ~]# tree   .ansible/tmp/ansible-tmp-1628132275.04-75210-50548140935223/
.ansible/tmp/ansible-tmp-1628132275.04-75210-50548140935223/
└── test.sh

0 directories, 1 file
[root@localhost ~]# cat   .ansible/tmp/ansible-tmp-1628132275.04-75210-50548140935223/
cat: .ansible/tmp/ansible-tmp-1628132275.04-75210-50548140935223/: 是一个目录
[root@localhost ~]# cat   .ansible/tmp/ansible-tmp-1628132275.04-75210-50548140935223/test.sh 
#!/bin/bash
echo   My  hostname    is `hostname`
sleep 100
[root@localhost ~]# cat   .ansible/tmp/ansible-tmp-1628132275.04-75210-50548140935223/test.sh 
cat: .ansible/tmp/ansible-tmp-1628132275.04-75210-50548140935223/test.sh: 没有那个文件或目录

1.1.4Copy模块

功能:从ansible服务器主控端复制文件到远程主机

#指定内容,直接生成目标文件
ansible  websrvs   -m copy  -a "content='test  line1\ntest lin2' dest=/tmp/test.txt "
192.168.10.16 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "checksum": "4f4d8a96a04e881aa5295348dc1e4d0ebe19802b", 
    "dest": "/tmp/test.txt", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "c644bb586fa388f2a4f29ed0dcb563f3", 
    "mode": "0644", 
    "owner": "root", 
    "secontext": "unconfined_u:object_r:admin_home_t:s0", 
    "size": 21, 
    "src": "/root/.ansible/tmp/ansible-tmp-1628168923.71-75698-249218734635622/source", 
    "state": "file", 
    "uid": 0
}
192.168.10.17 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "checksum": "4f4d8a96a04e881aa5295348dc1e4d0ebe19802b", 
    "dest": "/tmp/test.txt", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "c644bb586fa388f2a4f29ed0dcb563f3", 
    "mode": "0644", 
    "owner": "root", 
    "secontext": "unconfined_u:object_r:admin_home_t:s0", 
    "size": 21, 
    "src": "/root/.ansible/tmp/ansible-tmp-1628168923.72-75699-4497557374337/source", 
    "state": "file", 
    "uid": 0
}
#查看是否生成
[root@node ~]# ansible  websrvs     -a "chdir=/tmp  cat test.txt"
192.168.10.17 | CHANGED | rc=0 >>
test  line1
test lin2
192.168.10.16 | CHANGED | rc=0 >>
test  line1
test lin2
#将自己的文件传输到起到指定
[root@node ~]# ansible  websrvs  -m  copy -a   "src=/etc/centos-release  dest=/tmp/os.txt owner=root  mode=600"
192.168.10.17 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "checksum": "0d3186157c40752f89db0e618a5866935b523e7b", 
    "dest": "/tmp/os.txt", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "902962816d0ec4fbb532949f70a41ae7", 
    "mode": "0600", 
    "owner": "root", 
    "secontext": "unconfined_u:object_r:admin_home_t:s0", 
    "size": 37, 
    "src": "/root/.ansible/tmp/ansible-tmp-1628169367.11-75893-7571866854172/source", 
    "state": "file", 
    "uid": 0
}
192.168.10.16 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "checksum": "0d3186157c40752f89db0e618a5866935b523e7b", 
    "dest": "/tmp/os.txt", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "902962816d0ec4fbb532949f70a41ae7", 
    "mode": "0600", 
    "owner": "root", 
    "secontext": "unconfined_u:object_r:admin_home_t:s0", 
    "size": 37, 
    "src": "/root/.ansible/tmp/ansible-tmp-1628169367.14-75892-217136206457670/source", 
    "state": "file", 
    "uid": 0
}
[root@node ~]# ansible  websrvs    -a   "cat  /tmp/os.txt"
192.168.10.17 | CHANGED | rc=0 >>
CentOS Linux release 7.9.2009 (Core)
192.168.10.16 | CHANGED | rc=0 >>
CentOS Linux release 7.9.2009 (Core)
[root@node ~]# ansible  websrvs    -a   "ls -l   /tmp/os.txt"
192.168.10.17 | CHANGED | rc=0 >>
-rw-------. 1 root root 37 85 21:16 /tmp/os.txt
192.168.10.16 | CHANGED | rc=0 >>
-rw-------. 1 root root 37 85 21:16 /tmp/os.txt
#将目录拷贝过去
[root@node ~]# ansible  websrvs  -m  copy -a   "src=/etc/sysconfig  dest=/tmp/  owner=root  mode=600"

192.168.10.16 | CHANGED => {
    "changed": true, 
    "dest": "/tmp/", 
    "src": "/etc/sysconfig"
}
192.168.10.17 | CHANGED => {
    "changed": true, 
    "dest": "/tmp/", 
    "src": "/etc/sysconfig"
}
1.1.5Fetch模块

功能:从远程主机提取文件至ansible的主控端,copy相反,目前不支持目录

范例:

[root@node ~]# tree  /data/os/
/data/os/
├── 192.168.10.16
│   └── etc
│       └── redhat-release
├── 192.168.10.17
│   └── etc
│       └── redhat-release
└── 192.168.10.18
    └── etc
        └── redhat-release

6 directories, 3 files
[root@node ~]# ansible  all   -m  fetch   -a   'src=/etc/redhat-release   dest=/data/os'
1.1.6File模块

功能:设置文件属性

image-20210805215734910
[root@node ~]# ansible  websrvs  -m  file   -a  'path=/data/test.txt  state=touch'
192.168.10.16 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "dest": "/data/test.txt", 
    "gid": 0, 
    "group": "root", 
    "mode": "0644", 
    "owner": "root", 
    "secontext": "unconfined_u:object_r:default_t:s0", 
    "size": 0, 
    "state": "file", 
    "uid": 0
}
192.168.10.17 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "dest": "/data/test.txt", 
    "gid": 0, 
    "group": "root", 
    "mode": "0644", 
    "owner": "root", 
    "secontext": "unconfined_u:object_r:default_t:s0", 
    "size": 0, 
    "state": "file", 
    "uid": 0
}
[root@node ~]# ansible  websrvs    -a  'ls -l /data/test.txt'
192.168.10.17 | CHANGED | rc=0 >>
-rw-r--r--. 1 root root 0 85 21:54 /data/test.txt
192.168.10.16 | CHANGED | rc=0 >>
-rw-r--r--. 1 root root 0 85 21:54 /data/test.txt
[root@node ~]# ansible  websrvs  -m  file   -a  'path=/data/test.txt  group=bin  mode=666'
192.168.10.17 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "gid": 1, 
    "group": "bin", 
    "mode": "0666", 
    "owner": "root", 
    "path": "/data/test.txt", 
    "secontext": "unconfined_u:object_r:default_t:s0", 
    "size": 0, 
    "state": "file", 
    "uid": 0
}
192.168.10.16 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "gid": 1, 
    "group": "bin", 
    "mode": "0666", 
    "owner": "root", 
    "path": "/data/test.txt", 
    "secontext": "unconfined_u:object_r:default_t:s0", 
    "size": 0, 
    "state": "file", 
    "uid": 0
}
[root@node ~]# ansible  websrvs    -a  'ls -l /data/test.txt'
192.168.10.17 | CHANGED | rc=0 >>
-rw-rw-rw-. 1 root bin 0 85 21:54 /data/test.txt
192.168.10.16 | CHANGED | rc=0 >>
-rw-rw-rw-. 1 root bin 0 85 21:54 /data/test.txt

1.1.7unarchive模块

功能:解包解压缩

实现有两种用法:
1、将ansible主机上的压缩包传到远程主机后解压缩至特定目录,设置copy=yes
2、将远程主机上的某个压缩包解压压缩至指定路径下,设置copy=no

常见参数:

  • copy:默认为yes,当copy=yes,拷贝的文件是从ansible主机复制到远程主机上,如果设置为copy=no,会在远程主机上寻找src源文件
  • remote_src:和copy功能一样且互斥,yes表示在远程主机,不在ansible主机,no表示文件在ansible主机上
  • src:源路径,可以是ansible主机上的路径,也可以是远程主机上的路劲,如果是远程主机上的路径,则需要设置copy=no
  • dest:远程主机上的目标路径
  • mode:设置解压缩后的文件权限

范例:

#将本地的tar,gz文件解压到其他机器
[root@node ~]# ansible  websrvs  -m  unarchive   -a  'src=/data/etc.tar.gz dest=/data/ owner=root'
192.168.10.16 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "dest": "/data/", 
    "extract_results": {
        "cmd": [
            "/usr/bin/gtar", 
            "--extract", 
            "-C", 
            "/data/", 
            "-z", 
            "--owner=root", 
            "-f", 
            "/root/.ansible/tmp/ansible-tmp-1628212890.8-78167-6385590959496/source"
        ], 
        "err": "", 
        "out": "", 
        "rc": 0
    }, 
    "gid": 0, 
    "group": "root", 
    "handler": "TgzArchive", 
    "mode": "0755", 
    "owner": "root", 
    "secontext": "unconfined_u:object_r:default_t:s0", 
    "size": 17, 
    "src": "/root/.ansible/tmp/ansible-tmp-1628212890.8-78167-6385590959496/source", 
    "state": "directory", 
    "uid": 0
}
192.168.10.17 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "dest": "/data/", 
    "extract_results": {
        "cmd": [
            "/usr/bin/gtar", 
            "--extract", 
            "-C", 
            "/data/", 
            "-z", 
            "--owner=root", 
            "-f", 
            "/root/.ansible/tmp/ansible-tmp-1628212890.79-78168-81835740355826/source"
        ], 
        "err": "", 
        "out": "", 
        "rc": 0
    }, 
    "gid": 0, 
    "group": "root", 
    "handler": "TgzArchive", 
    "mode": "0755", 
    "owner": "root", 
    "secontext": "unconfined_u:object_r:default_t:s0", 
    "size": 17, 
    "src": "/root/.ansible/tmp/ansible-tmp-1628212890.79-78168-81835740355826/source", 
    "state": "directory", 
    "uid": 0
}
[root@node ~]# ansible  websrvs  -m  unarchive   -a  'src=/data/etc.tar.gz dest=/data/ owner=root copy=yes'

#主控端将压缩包传输到客户端
[root@node ~]# ansible  websrvs  -m  copy   -a  'src=/data/etc.tar.xz dest=/data/'
192.168.10.17 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "checksum": "89b230a1bc50d8098bdf6b132a038a3c03ce3eda", 
    "dest": "/data/etc.tar.xz", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "6cf81d9587c1449f3fdada07470097f5", 
    "mode": "0644", 
    "owner": "root", 
    "secontext": "system_u:object_r:default_t:s0", 
    "size": 8099436, 
    "src": "/root/.ansible/tmp/ansible-tmp-1628213207.03-78301-147337025091910/source", 
    "state": "file", 
    "uid": 0
}
192.168.10.16 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "checksum": "89b230a1bc50d8098bdf6b132a038a3c03ce3eda", 
    "dest": "/data/etc.tar.xz", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "6cf81d9587c1449f3fdada07470097f5", 
    "mode": "0644", 
    "owner": "root", 
    "secontext": "system_u:object_r:default_t:s0", 
    "size": 8099436, 
    "src": "/root/.ansible/tmp/ansible-tmp-1628213207.0-78299-22615467353598/source", 
    "state": "file", 
    "uid": 0
}
#进行查看
[root@node ~]# ansible  websrvs     -a  'ls  -l /data/'
192.168.10.16 | CHANGED | rc=0 >>
总用量 7924
drwxr-xr-x. 77 root root    8192 86 09:06 etc
-rw-r--r--.  1 root root 8099436 86 09:26 etc.tar.xz
192.168.10.17 | CHANGED | rc=0 >>
总用量 7924
drwxr-xr-x. 77 root root    8192 86 09:06 etc
-rw-r--r--.  1 root root 8099436 86 09:26 etc.tar.xz
#在主控端进行解包客户端的包 设置权限为700  copy=no 表示是在远程主机上解包
[root@node ~]# ansible  websrvs  -m  unarchive   -a  'src=/data/etc.tar.xz dest=/opt/ mode=700 copy=no'
192.168.10.16 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "dest": "/opt/", 
    "extract_results": {
        "cmd": [
            "/usr/bin/gtar", 
            "--extract", 
            "-C", 
            "/opt/", 
            "-f", 
            "/data/etc.tar.xz"
        ], 
        "err": "", 
        "out": "", 
        "rc": 0
    }, 
    "gid": 0, 
    "group": "root", 
    "handler": "TarArchive", 
    "mode": "0755", 
    "owner": "root", 
    "secontext": "system_u:object_r:usr_t:s0", 
    "size": 17, 
    "src": "/data/etc.tar.xz", 
    "state": "directory", 
    "uid": 0
}
192.168.10.17 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "dest": "/opt/", 
    "extract_results": {
        "cmd": [
            "/usr/bin/gtar", 
            "--extract", 
            "-C", 
            "/opt/", 
            "-f", 
            "/data/etc.tar.xz"
        ], 
        "err": "", 
        "out": "", 
        "rc": 0
    }, 
    "gid": 0, 
    "group": "root", 
    "handler": "TarArchive", 
    "mode": "0755", 
    "owner": "root", 
    "secontext": "system_u:object_r:usr_t:s0", 
    "size": 17, 
    "src": "/data/etc.tar.xz", 
    "state": "directory", 
    "uid": 0
}
[root@node ~]# ansible  websrvs     -a  'ls -l/opt/'
192.168.10.16 | FAILED | rc=2 >>
ls:无效选项 -- /
Try 'ls --help' for more information.non-zero return code
192.168.10.17 | FAILED | rc=2 >>
ls:无效选项 -- /
Try 'ls --help' for more information.non-zero return code
[root@node ~]# ansible  websrvs     -a  'ls -l /opt/'
192.168.10.17 | CHANGED | rc=0 >>
总用量 12
drwx------. 77 root root 8192 86 09:06 etc
192.168.10.16 | CHANGED | rc=0 >>
总用量 12
drwx------. 77 root root 8192 86 09:06 etc
[root@node ~]# ansible  websrvs     -a  'du  -sh  /opt/'
192.168.10.17 | CHANGED | rc=0 >>
36M	/opt/
192.168.10.16 | CHANGED | rc=0 >>
36M	/opt/

1.1.8Archive模块

功能:打包压缩

范例:

[root@node ~]# ansible  websrvs   -m archive  -a  'path=/var/log/ dest=/data/log.tar.bz2 format=bz2  owner=root  mode=0600'
192.168.10.17 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "archived": [
        "/var/log/tallylog", 
        "/var/log/lastlog", 
        "/var/log/wtmp", 
        "/var/log/btmp", 
        "/var/log/messages", 
        "/var/log/secure", 
        "/var/log/maillog", 
        "/var/log/spooler", 
        "/var/log/vmware-vmsvc.log", 
        "/var/log/firewalld", 
        "/var/log/Xorg.9.log", 
        "/var/log/cron", 
        "/var/log/wpa_supplicant.log", 
        "/var/log/boot.log", 
        "/var/log/dmesg.old", 
        "/var/log/dmesg", 
        "/var/log/Xorg.0.log.old", 
        "/var/log/Xorg.0.log", 
        "/var/log/vmware-vmusr.log", 
        "/var/log/yum.log", 
        "/var/log/audit/audit.log", 
        "/var/log/gdm/:0.log.3", 
        "/var/log/gdm/:0.log.2", 
        "/var/log/gdm/:0.log.1", 
        "/var/log/gdm/:0.log", 
        "/var/log/gdm/:0-greeter.log.2", 
        "/var/log/gdm/:0-greeter.log.1", 
        "/var/log/gdm/:0-greeter.log", 
        "/var/log/cups/access_log", 
        "/var/log/cups/error_log", 
        "/var/log/cups/page_log", 
        "/var/log/tuned/tuned.log", 
        "/var/log/sa/sa24", 
        "/var/log/sa/sa11", 
        "/var/log/sa/sa05", 
        "/var/log/sa/sa06", 
        "/var/log/anaconda/anaconda.log", 
        "/var/log/anaconda/syslog", 
        "/var/log/anaconda/X.log", 
        "/var/log/anaconda/program.log", 
        "/var/log/anaconda/packaging.log", 
        "/var/log/anaconda/storage.log", 
        "/var/log/anaconda/ifcfg.log", 
        "/var/log/anaconda/ks-script-D4Gm2a.log", 
        "/var/log/anaconda/journal.log"
    ], 
    "arcroot": "/var/log/", 
    "changed": true, 
    "dest": "/data/log.tar.bz2", 
    "expanded_exclude_paths": [], 
    "expanded_paths": [
        "/var/log/"
    ], 
    "gid": 0, 
    "group": "root", 
    "missing": [], 
    "mode": "0600", 
    "owner": "root", 
    "secontext": "unconfined_u:object_r:default_t:s0", 
    "size": 390428, 
    "state": "file", 
    "uid": 0
}
192.168.10.16 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "archived": [
        "/var/log/tallylog", 
        "/var/log/lastlog", 
        "/var/log/wtmp", 
        "/var/log/btmp", 
        "/var/log/messages", 
        "/var/log/secure", 
        "/var/log/maillog", 
        "/var/log/spooler", 
        "/var/log/boot.log", 
        "/var/log/dmesg", 
        "/var/log/vmware-vmsvc.log", 
        "/var/log/firewalld", 
        "/var/log/Xorg.9.log", 
        "/var/log/cron", 
        "/var/log/wpa_supplicant.log", 
        "/var/log/Xorg.0.log.old", 
        "/var/log/Xorg.0.log", 
        "/var/log/vmware-vmusr.log", 
        "/var/log/yum.log", 
        "/var/log/audit/audit.log", 
        "/var/log/cups/access_log", 
        "/var/log/cups/error_log", 
        "/var/log/cups/page_log", 
        "/var/log/gdm/:0.log.1", 
        "/var/log/gdm/:0.log", 
        "/var/log/gdm/:0-greeter.log.1", 
        "/var/log/gdm/:0-greeter.log", 
        "/var/log/sa/sa14", 
        "/var/log/sa/sa05", 
        "/var/log/sa/sa06", 
        "/var/log/tuned/tuned.log", 
        "/var/log/anaconda/anaconda.log", 
        "/var/log/anaconda/syslog", 
        "/var/log/anaconda/X.log", 
        "/var/log/anaconda/program.log", 
        "/var/log/anaconda/packaging.log", 
        "/var/log/anaconda/storage.log", 
        "/var/log/anaconda/ifcfg.log", 
        "/var/log/anaconda/ks-script-CbRh53.log", 
        "/var/log/anaconda/journal.log"
    ], 
    "arcroot": "/var/log/", 
    "changed": true, 
    "dest": "/data/log.tar.bz2", 
    "expanded_exclude_paths": [], 
    "expanded_paths": [
        "/var/log/"
    ], 
    "gid": 0, 
    "group": "root", 
    "missing": [], 
    "mode": "0600", 
    "owner": "root", 
    "secontext": "unconfined_u:object_r:default_t:s0", 
    "size": 352434, 
    "state": "file", 
    "uid": 0
}
[root@node ~]# ansible  websrvs    -a  'ls  -l /data/log.tar.bz2 '
192.168.10.17 | CHANGED | rc=0 >>
-rw-------. 1 root root 390428 86 09:35 /data/log.tar.bz2
192.168.10.16 | CHANGED | rc=0 >>
-rw-------. 1 root root 352434 86 09:35 /data/log.tar.bz2
[root@node ~]# ansible  websrvs    -a  'file  /data/log.tar.bz2 '
192.168.10.17 | CHANGED | rc=0 >>
/data/log.tar.bz2: bzip2 compressed data, block size = 900k
192.168.10.16 | CHANGED | rc=0 >>
/data/log.tar.bz2: bzip2 compressed data, block size = 900k
1.1.9Hostname模块

功能:管理主机名

范例:

[root@node ~]# ansible   192.168.10.16  -m  hostname  -a  'name=centos7.aqi'
192.168.10.16 | CHANGED => {
    "ansible_facts": {
        "ansible_domain": "aqi", 
        "ansible_fqdn": "centos7.aqi", 
        "ansible_hostname": "centos7", 
        "ansible_nodename": "centos7.aqi", 
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "name": "centos7.aqi"
}
[root@node ~]# ansible   192.168.10.16    -a   'hostname'
192.168.10.16 | CHANGED | rc=0 >>
centos7.aqi
1.2.0Cron模块

功能:计划任务
支持时间:minute,day,month,weekday
范例:

image-20210806102014170
1.2.1Yum模块

功能:管理软件包,只支持Rhel,CentOS,fedora,不支持Ubuntu其他版本

范例:

[root@node ~]# ansible  all    -m  yum    -a  "name=httpd"
192.168.10.18 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "changes": {
        "installed": [
            "httpd"
        ]
    }, 
    "msg": "", 
    "rc": 0, 
    "results": [
        "Loaded plugins: fastestmirror, langpacks\nLoading mirror speeds from cached hostfile\nResolving Dependencies\n--> Running transaction check\n---> Package httpd.x86_64 0:2.4.6-45.el7.centos will be installed\n--> Processing Dependency: httpd-tools = 2.4.6-45.el7.centos for package: httpd-2.4.6-45.el7.centos.x86_64\n--> Processing Dependency: /etc/mime.types for package: httpd-2.4.6-45.el7.centos.x86_64\n--> Processing Dependency: libaprutil-1.so.0()(64bit) for package: httpd-2.4.6-45.el7.centos.x86_64\n--> Processing Dependency: libapr-1.so.0()(64bit) for package: httpd-2.4.6-45.el7.centos.x86_64\n--> Running transaction check\n---> Package apr.x86_64 0:1.4.8-3.el7 will be installed\n---> Package apr-util.x86_64 0:1.5.2-6.el7 will be installed\n---> Package httpd-tools.x86_64 0:2.4.6-45.el7.centos will be installed\n---> Package mailcap.noarch 0:2.1.41-2.el7 will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package            Arch          Version                      Repository  Size\n================================================================================\nInstalling:\n httpd              x86_64        2.4.6-45.el7.centos          yum        2.7 M\nInstalling for dependencies:\n apr                x86_64        1.4.8-3.el7                  yum        103 k\n apr-util           x86_64        1.5.2-6.el7                  yum         92 k\n httpd-tools        x86_64        2.4.6-45.el7.centos          yum         84 k\n mailcap            noarch        2.1.41-2.el7                 yum         31 k\n\nTransaction Summary\n================================================================================\nInstall  1 Package (+4 Dependent packages)\n\nTotal download size: 3.0 M\nInstalled size: 10 M\nDownloading packages:\n--------------------------------------------------------------------------------\nTotal                                               15 MB/s | 3.0 MB  00:00     \nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n  Installing : apr-1.4.8-3.el7.x86_64                                       1/5 \n  Installing : apr-util-1.5.2-6.el7.x86_64                                  2/5 \n  Installing : httpd-tools-2.4.6-45.el7.centos.x86_64                       3/5 \n  Installing : mailcap-2.1.41-2.el7.noarch                                  4/5 \n  Installing : httpd-2.4.6-45.el7.centos.x86_64                             5/5 \n  Verifying  : httpd-tools-2.4.6-45.el7.centos.x86_64                       1/5 \n  Verifying  : mailcap-2.1.41-2.el7.noarch                                  2/5 \n  Verifying  : apr-1.4.8-3.el7.x86_64                                       3/5 \n  Verifying  : httpd-2.4.6-45.el7.centos.x86_64                             4/5 \n  Verifying  : apr-util-1.5.2-6.el7.x86_64                                  5/5 \n\nInstalled:\n  httpd.x86_64 0:2.4.6-45.el7.centos                                            \n\nDependency Installed:\n  apr.x86_64 0:1.4.8-3.el7                     apr-util.x86_64 0:1.5.2-6.el7    \n  httpd-tools.x86_64 0:2.4.6-45.el7.centos     mailcap.noarch 0:2.1.41-2.el7    \n\nComplete!\n"
    ]
}
192.168.10.17 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "changes": {
        "installed": [
            "httpd"
        ]
    }, 
    "msg": "", 
    "rc": 0, 
    "results": [
        "Loaded plugins: fastestmirror, langpacks\nLoading mirror speeds from cached hostfile\nResolving Dependencies\n--> Running transaction check\n---> Package httpd.x86_64 0:2.4.6-45.el7.centos will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package        Arch            Version                      Repository    Size\n================================================================================\nInstalling:\n httpd          x86_64          2.4.6-45.el7.centos          yum          2.7 M\n\nTransaction Summary\n================================================================================\nInstall  1 Package\n\nTotal download size: 2.7 M\nInstalled size: 9.4 M\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n  Installing : httpd-2.4.6-45.el7.centos.x86_64                             1/1 \n  Verifying  : httpd-2.4.6-45.el7.centos.x86_64                             1/1 \n\nInstalled:\n  httpd.x86_64 0:2.4.6-45.el7.centos                                            \n\nComplete!\n"
    ]
}
192.168.10.16 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "changes": {
        "installed": [
            "httpd"
        ]
    }, 
    "msg": "", 
    "rc": 0, 
    "results": [
        "Loaded plugins: fastestmirror, langpacks\nLoading mirror speeds from cached hostfile\n * base: mirrors.aliyun.com\n * extras: mirrors.aliyun.com\n * updates: mirrors.aliyun.com\nResolving Dependencies\n--> Running transaction check\n---> Package httpd.x86_64 0:2.4.6-97.el7.centos will be installed\n--> Processing Dependency: httpd-tools = 2.4.6-97.el7.centos for package: httpd-2.4.6-97.el7.centos.x86_64\n--> Processing Dependency: /etc/mime.types for package: httpd-2.4.6-97.el7.centos.x86_64\n--> Running transaction check\n---> Package httpd-tools.x86_64 0:2.4.6-97.el7.centos will be installed\n---> Package mailcap.noarch 0:2.1.41-2.el7 will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package           Arch         Version                     Repository     Size\n================================================================================\nInstalling:\n httpd             x86_64       2.4.6-97.el7.centos         updates       2.7 M\nInstalling for dependencies:\n httpd-tools       x86_64       2.4.6-97.el7.centos         updates        93 k\n mailcap           noarch       2.1.41-2.el7                base           31 k\n\nTransaction Summary\n================================================================================\nInstall  1 Package (+2 Dependent packages)\n\nTotal download size: 2.8 M\nInstalled size: 9.6 M\nDownloading packages:\n--------------------------------------------------------------------------------\nTotal                                              5.8 MB/s | 2.8 MB  00:00     \nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n  Installing : httpd-tools-2.4.6-97.el7.centos.x86_64                       1/3 \n  Installing : mailcap-2.1.41-2.el7.noarch                                  2/3 \n  Installing : httpd-2.4.6-97.el7.centos.x86_64                             3/3 \n  Verifying  : httpd-2.4.6-97.el7.centos.x86_64                             1/3 \n  Verifying  : mailcap-2.1.41-2.el7.noarch                                  2/3 \n  Verifying  : httpd-tools-2.4.6-97.el7.centos.x86_64                       3/3 \n\nInstalled:\n  httpd.x86_64 0:2.4.6-97.el7.centos                                            \n\nDependency Installed:\n  httpd-tools.x86_64 0:2.4.6-97.el7.centos     mailcap.noarch 0:2.1.41-2.el7    \n\nComplete!\n"
    ]
}
[root@node ~]# ansible  all        -a  "rpm  -qa httpd"
[WARNING]: Consider using the yum, dnf or zypper module rather than running 'rpm'.  If
you need to use command because yum, dnf or zypper 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.
192.168.10.17 | CHANGED | rc=0 >>
httpd-2.4.6-45.el7.centos.x86_64
192.168.10.18 | CHANGED | rc=0 >>
httpd-2.4.6-45.el7.centos.x86_64
192.168.10.16 | CHANGED | rc=0 >>
httpd-2.4.6-97.el7.centos.x86_64
[root@node ~]# ansible  all        -a  "rpm  -qi httpd"  #查看包是否安装
[WARNING]: Consider using the yum, dnf or zypper module rather than running 'rpm'.  If
you need to use command because yum, dnf or zypper 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.
192.168.10.18 | CHANGED | rc=0 >>
Name        : httpd
Version     : 2.4.6
Release     : 45.el7.centos
Architecture: x86_64
Install Date: 2021年08月05日 星期四 19时28分49秒
Group       : System Environment/Daemons
Size        : 9807149
License     : ASL 2.0
Signature   : RSA/SHA256, 2016年11月20日 星期日 10时14分03秒, Key ID 24c6a8a7f4a80eb5
Source RPM  : httpd-2.4.6-45.el7.centos.src.rpm
Build Date  : 2016年11月14日 星期一 10时06分40秒
Build Host  : c1bm.rdu2.centos.org
Relocations : (not relocatable)
Packager    : CentOS BuildSystem <http://bugs.centos.org>
Vendor      : CentOS
URL         : http://httpd.apache.org/
Summary     : Apache HTTP Server
Description :
The Apache HTTP Server is a powerful, efficient, and extensible
web server.
192.168.10.17 | CHANGED | rc=0 >>
Name        : httpd
Version     : 2.4.6
Release     : 45.el7.centos
Architecture: x86_64
Install Date: 2021年08月06日 星期五 10时28分51秒
Group       : System Environment/Daemons
Size        : 9807149
License     : ASL 2.0
Signature   : RSA/SHA256, 2016年11月21日 星期一 02时14分03秒, Key ID 24c6a8a7f4a80eb5
Source RPM  : httpd-2.4.6-45.el7.centos.src.rpm
Build Date  : 2016年11月15日 星期二 02时06分40秒
Build Host  : c1bm.rdu2.centos.org
Relocations : (not relocatable)
Packager    : CentOS BuildSystem <http://bugs.centos.org>
Vendor      : CentOS
URL         : http://httpd.apache.org/
Summary     : Apache HTTP Server
Description :
The Apache HTTP Server is a powerful, efficient, and extensible
web server.
192.168.10.16 | CHANGED | rc=0 >>
Name        : httpd
Version     : 2.4.6
Release     : 97.el7.centos
Architecture: x86_64
Install Date: 2021年08月06日 星期五 10时28分54秒
Group       : System Environment/Daemons
Size        : 9821064
License     : ASL 2.0
Signature   : RSA/SHA256, 2020年11月18日 星期三 22时17分43秒, Key ID 24c6a8a7f4a80eb5
Source RPM  : httpd-2.4.6-97.el7.centos.src.rpm
Build Date  : 2020年11月17日 星期二 00时21分17秒
Build Host  : x86-02.bsys.centos.org
Relocations : (not relocatable)
Packager    : CentOS BuildSystem <http://bugs.centos.org>
Vendor      : CentOS
URL         : http://httpd.apache.org/
Summary     : Apache HTTP Server
Description :
The Apache HTTP Server is a powerful, efficient, and extensible
web server.

卸载   httpd包    state=absent就是卸载的意思
[root@node ~]# ansible  all    -m  yum    -a  "name=httpd  state=absent"
192.168.10.18 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "changes": {
        "removed": [
            "httpd"
        ]
    }, 
    "msg": "", 
    "rc": 0, 
    "results": [
        "已加载插件:fastestmirror, langpacks\n正在解决依赖关系\n--> 正在检查事务\n---> 软件包 httpd.x86_64.0.2.4.6-45.el7.centos 将被 删除\n--> 解决依赖关系完成\n\n依赖关系解决\n\n================================================================================\n Package       架构           版本                           源            大小\n================================================================================\n正在删除:\n httpd         x86_64         2.4.6-45.el7.centos            @yum         9.4 M\n\n事务概要\n================================================================================\n移除  1 软件包\n\n安装大小:9.4 M\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n  正在删除    : httpd-2.4.6-45.el7.centos.x86_64                            1/1 \n  验证中      : httpd-2.4.6-45.el7.centos.x86_64                            1/1 \n\n删除:\n  httpd.x86_64 0:2.4.6-45.el7.centos                                            \n\n完毕!\n"
    ]
}
192.168.10.17 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "changes": {
        "removed": [
            "httpd"
        ]
    }, 
    "msg": "", 
    "rc": 0, 
    "results": [
        "已加载插件:fastestmirror, langpacks\n正在解决依赖关系\n--> 正在检查事务\n---> 软件包 httpd.x86_64.0.2.4.6-45.el7.centos 将被 删除\n--> 解决依赖关系完成\n\n依赖关系解决\n\n================================================================================\n Package       架构           版本                           源            大小\n================================================================================\n正在删除:\n httpd         x86_64         2.4.6-45.el7.centos            @yum         9.4 M\n\n事务概要\n================================================================================\n移除  1 软件包\n\n安装大小:9.4 M\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n  正在删除    : httpd-2.4.6-45.el7.centos.x86_64                            1/1 \n  验证中      : httpd-2.4.6-45.el7.centos.x86_64                            1/1 \n\n删除:\n  httpd.x86_64 0:2.4.6-45.el7.centos                                            \n\n完毕!\n"
    ]
}
192.168.10.16 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "changes": {
        "removed": [
            "httpd"
        ]
    }, 
    "msg": "", 
    "rc": 0, 
    "results": [
        "已加载插件:fastestmirror, langpacks\n正在解决依赖关系\n--> 正在检查事务\n---> 软件包 httpd.x86_64.0.2.4.6-97.el7.centos 将被 删除\n--> 解决依赖关系完成\n\n依赖关系解决\n\n================================================================================\n Package      架构          版本                          源               大小\n================================================================================\n正在删除:\n httpd        x86_64        2.4.6-97.el7.centos           @updates        9.4 M\n\n事务概要\n================================================================================\n移除  1 软件包\n\n安装大小:9.4 M\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n  正在删除    : httpd-2.4.6-97.el7.centos.x86_64                            1/1 \n  验证中      : httpd-2.4.6-97.el7.centos.x86_64                            1/1 \n\n删除:\n  httpd.x86_64 0:2.4.6-97.el7.centos                                            \n\n完毕!\n"
    ]
}
1.2.2 Service模块

功能:管理服务

范例:

[root@node ~]# ansible  all     -m  service    -a  "name=httpd  state=started"
192.168.10.18 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "name": "httpd", 
    "state": "started", 
    "status": {
        "ActiveEnterTimestampMonotonic": "0", 
        "ActiveExitTimestampMonotonic": "0", 

[root@node ~]# ansible  all   -a   "ss  -ntl"
192.168.10.16 | CHANGED | rc=0 >>
State      Recv-Q Send-Q Local Address:Port               Peer Address:Port              
LISTEN     0      128          *:111                      *:*                  
LISTEN     0      5      192.168.122.1:53                       *:*                  
LISTEN     0      128          *:22                       *:*                  
LISTEN     0      128    127.0.0.1:631                      *:*                  
LISTEN     0      100    127.0.0.1:25                       *:*                  
LISTEN     0      128    127.0.0.1:6010                     *:*                  
LISTEN     0      128         :::111                     :::*                  
LISTEN     0      128         :::80                      :::*                  
LISTEN     0      128         :::22                      :::*                  
LISTEN     0      128        ::1:631                     :::*                  
LISTEN     0      100        ::1:25                      :::*                  
LISTEN     0      128        ::1:6010                    :::*                  
192.168.10.17 | CHANGED | rc=0 >>
State      Recv-Q Send-Q Local Address:Port               Peer Address:Port              
LISTEN     0      128          *:111                      *:*                  
LISTEN     0      5      192.168.122.1:53                       *:*                  
LISTEN     0      128          *:22                       *:*                  
LISTEN     0      128    127.0.0.1:631                      *:*                  
LISTEN     0      100    127.0.0.1:25                       *:*                  
LISTEN     0      128    127.0.0.1:6010                     *:*                  
LISTEN     0      128         :::111                     :::*                  
LISTEN     0      128         :::80                      :::*                  
LISTEN     0      128         :::22                      :::*                  
LISTEN     0      128        ::1:631                     :::*                  
LISTEN     0      100        ::1:25                      :::*                  
LISTEN     0      128        ::1:6010                    :::*                  
192.168.10.18 | CHANGED | rc=0 >>
State      Recv-Q Send-Q Local Address:Port               Peer Address:Port              
LISTEN     0      128          *:111                      *:*                  
LISTEN     0      5      192.168.122.1:53                       *:*                  
LISTEN     0      128          *:22                       *:*                  
LISTEN     0      128    127.0.0.1:631                      *:*                  
LISTEN     0      100    127.0.0.1:25                       *:*                  
LISTEN     0      128    127.0.0.1:6011                     *:*                  
LISTEN     0      128         :::111                     :::*                  
LISTEN     0      128         :::80                      :::*                  
LISTEN     0      128         :::22                      :::*                  
LISTEN     0      128        ::1:631                     :::*                  
LISTEN     0      100        ::1:25                      :::*                  
LISTEN     0      128        ::1:6011                    :::*                  
[root@node ~]# ansible  all     -m  service    -a  "name=httpd  state=stopped"
192.168.10.18 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "name": "httpd", 
    "state": "stopped", 
    "status": {
        "ActiveEnterTimestamp": "四 2021-08-05 19:39:22 PDT", 
        "ActiveEnterTimestampMonotonic": "11611676350", 
        "ActiveExitTimestampMonotonic": "0", 
        "ActiveState": "active", 
        "After": "remote-fs.target system.slice tmp.mount systemd-journald.socket nss-lookup.target basic.target -.mount network.target", 
        "AllowIsolate": "no", 
        "AssertResult": "yes", 
        "AssertTimestamp": "四 2021-08-05 19:39:22 PDT", 
        "AssertTimestampMonotonic": "11611575514", 
        "Before": "shutdown.target", 
        "BlockIOAccounting": "no", 
        "BlockIOWeight": "18446744073709551615", 
        "CPUAccounting": "no", 
        "CPUQuotaPerSecUSec": "infinity", 
        "CPUSchedulingPolicy": "0", 
        "CPUSchedulingPriority": "0", 
        "CPUSchedulingResetOnFork": "no", 
        "CPUShares": "18446744073709551615", 
        "CanIsolate": "no", 
   
}
[root@node ~]# ansible  all   -a   "ss  -ntl"
192.168.10.16 | CHANGED | rc=0 >>
State      Recv-Q Send-Q Local Address:Port               Peer Address:Port              
LISTEN     0      128          *:111                      *:*                  
LISTEN     0      5      192.168.122.1:53                       *:*                  
LISTEN     0      128          *:22                       *:*                  
LISTEN     0      128    127.0.0.1:631                      *:*                  
LISTEN     0      100    127.0.0.1:25                       *:*                  
LISTEN     0      128    127.0.0.1:6010                     *:*                  
LISTEN     0      128         :::111                     :::*                  
LISTEN     0      128         :::22                      :::*                  
LISTEN     0      128        ::1:631                     :::*                  
LISTEN     0      100        ::1:25                      :::*                  
LISTEN     0      128        ::1:6010                    :::*                  
192.168.10.17 | CHANGED | rc=0 >>
State      Recv-Q Send-Q Local Address:Port               Peer Address:Port              
LISTEN     0      128          *:111                      *:*                  
LISTEN     0      5      192.168.122.1:53                       *:*                  
LISTEN     0      128          *:22                       *:*                  
LISTEN     0      128    127.0.0.1:631                      *:*                  
LISTEN     0      100    127.0.0.1:25                       *:*                  
LISTEN     0      128    127.0.0.1:6010                     *:*                  
LISTEN     0      128         :::111                     :::*                  
LISTEN     0      128         :::22                      :::*                  
LISTEN     0      128        ::1:631                     :::*                  
LISTEN     0      100        ::1:25                      :::*                  
LISTEN     0      128        ::1:6010                    :::*                  
192.168.10.18 | CHANGED | rc=0 >>
State      Recv-Q Send-Q Local Address:Port               Peer Address:Port              
LISTEN     0      128          *:111                      *:*                  
LISTEN     0      5      192.168.122.1:53                       *:*                  
LISTEN     0      128          *:22                       *:*                  
LISTEN     0      128    127.0.0.1:631                      *:*                  
LISTEN     0      100    127.0.0.1:25                       *:*                  
LISTEN     0      128    127.0.0.1:6011                     *:*                  
LISTEN     0      128         :::111                     :::*                  
LISTEN     0      128         :::22                      :::*                  
LISTEN     0      128        ::1:631                     :::*                  
LISTEN     0      100        ::1:25                      :::*                  
LISTEN     0      128        ::1:6011                    :::*     

#将80端口修改成8080
[root@node ~]# ansible   all  -a  "sed  -i  's/^Listen 80/Listen 8080/' /etc/httpd/conf/httpd.conf"
[root@localhost ~]# grep   ^Listen  /etc/httpd/conf/httpd.conf 
Listen 80
[root@localhost ~]# grep   ^Listen  /etc/httpd/conf/httpd.conf 
Listen 8080
#重启httpd服务  并且查看是否改变
[root@node ~]# ansible  all     -m  service    -a  "name=httpd   state=restarted" &>/dev/null  
[root@node ~]# 
[root@node ~]# ansible  all   -a   "ss  -ntl"
192.168.10.16 | CHANGED | rc=0 >>
State      Recv-Q Send-Q Local Address:Port               Peer Address:Port              
LISTEN     0      128          *:111                      *:*                  
LISTEN     0      5      192.168.122.1:53                       *:*                  
LISTEN     0      128          *:22                       *:*                  
LISTEN     0      128    127.0.0.1:631                      *:*                  
LISTEN     0      100    127.0.0.1:25                       *:*                  
LISTEN     0      128    127.0.0.1:6010                     *:*                  
LISTEN     0      128         :::111                     :::*                  
LISTEN     0      128         :::8080                    :::*                  
LISTEN     0      128         :::22                      :::*                  
LISTEN     0      128        ::1:631                     :::*                  
LISTEN     0      100        ::1:25                      :::*                  
LISTEN     0      128        ::1:6010                    :::*                  
192.168.10.17 | CHANGED | rc=0 >>
State      Recv-Q Send-Q Local Address:Port               Peer Address:Port              
LISTEN     0      128          *:111                      *:*                  
LISTEN     0      5      192.168.122.1:53                       *:*                  
LISTEN     0      128          *:22                       *:*                  
LISTEN     0      128    127.0.0.1:631                      *:*                  
LISTEN     0      100    127.0.0.1:25                       *:*                  
LISTEN     0      128    127.0.0.1:6010                     *:*                  
LISTEN     0      128         :::111                     :::*                  
LISTEN     0      128         :::8080                    :::*                  
LISTEN     0      128         :::22                      :::*                  
LISTEN     0      128        ::1:631                     :::*                  
LISTEN     0      100        ::1:25                      :::*                  
LISTEN     0      128        ::1:6010                    :::*                  
192.168.10.18 | CHANGED | rc=0 >>
State      Recv-Q Send-Q Local Address:Port               Peer Address:Port              
LISTEN     0      128          *:111                      *:*                  
LISTEN     0      5      192.168.122.1:53                       *:*                  
LISTEN     0      128          *:22                       *:*                  
LISTEN     0      128    127.0.0.1:631                      *:*                  
LISTEN     0      100    127.0.0.1:25                       *:*                  
LISTEN     0      128    127.0.0.1:6011                     *:*                  
LISTEN     0      128         :::111                     :::*                  
LISTEN     0      128         :::8080                    :::*                  
LISTEN     0      128         :::22                      :::*                  
LISTEN     0      128        ::1:631                     :::*                  
LISTEN     0      100        ::1:25                      :::*                  
LISTEN     0      128        ::1:6011                    :::*  
1.2.3 User模块

功能:管理用户

1.2.4Group模块
1.2.5Lineinfile模块

ansible在使用sed进行替换时,经常会遇到需要转义的问题,而已ansible在遇到特殊符号进行替换时,存在问题,无法正常进行替换。其实在ansible自身提供了两个模块:;ineinfile模块和replace模块,可以方便的进行替换

功能:相当于sed,可以修改文件内容
范例:

[root@node ~]# ansible   all   -m     lineinfile  -a  "path=/etc/selinux/config regexp='^SELINUX='   line='SELINUX=disabled'  "
192.168.10.18 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "backup": "", 
    "changed": true, 
    "msg": "line replaced"
}
192.168.10.17 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "backup": "", 
    "changed": true, 
    "msg": "line replaced"
}
192.168.10.16 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "backup": "", 
    "changed": true, 
    "msg": "line replaced"
}
[root@node ~]# ansible  all  -a  "cat  /etc/selinux/config "
192.168.10.17 | CHANGED | rc=0 >>

# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#     enforcing - SELinux security policy is enforced.
#     permissive - SELinux prints warnings instead of enforcing.
#     disabled - No SELinux policy is loaded.
SELINUX=disabled
# SELINUXTYPE= can take one of three two values:
#     targeted - Targeted processes are protected,
#     minimum - Modification of targeted policy. Only selected processes are protected. 
#     mls - Multi Level Security protection.
SELINUXTYPE=targeted 
192.168.10.18 | CHANGED | rc=0 >>

# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#     enforcing - SELinux security policy is enforced.
#     permissive - SELinux prints warnings instead of enforcing.
#     disabled - No SELinux policy is loaded.
SELINUX=disabled
# SELINUXTYPE= can take one of three two values:
#     targeted - Targeted processes are protected,
#     minimum - Modification of targeted policy. Only selected processes are protected. 
#     mls - Multi Level Security protection.
SELINUXTYPE=targeted 
192.168.10.16 | CHANGED | rc=0 >>

# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#     enforcing - SELinux security policy is enforced.
#     permissive - SELinux prints warnings instead of enforcing.
#     disabled - No SELinux policy is loaded.
SELINUX=disabled
# SELINUXTYPE= can take one of three two values:
#     targeted - Targeted processes are protected,
#     minimum - Modification of targeted policy. Only selected processes are protected. 
#     mls - Multi Level Security protection.
SELINUXTYPE=targeted 


去掉以#开头的行
[root@node ~]# ansible    all  -m  lineinfile   -a  'dest=/etc/fstab  state=absent  regexp="^#"'
192.168.10.18 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "backup": "", 
    "changed": true, 
    "found": 7, 
    "msg": "7 line(s) removed"
}
192.168.10.16 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "backup": "", 
    "changed": true, 
    "found": 7, 
    "msg": "7 line(s) removed"
}
192.168.10.17 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "backup": "", 
    "changed": true, 
    "found": 7, 
    "msg": "7 line(s) removed"
}
[root@node ~]# ansible  all  -a  "cat  /etc/fstab "
192.168.10.18 | CHANGED | rc=0 >>

UUID=59e57886-f23a-4fc4-b553-30218a4ecb63 /                       xfs     defaults        0 0
UUID=bb2989b3-5461-4fdd-814a-f5398e452c51 /boot                   xfs     defaults        0 0
UUID=2216e66a-8cda-4840-bac7-b553f4337750 swap                    swap    defaults        0 0
192.168.10.17 | CHANGED | rc=0 >>

/dev/mapper/cl-root     /                       xfs     defaults        0 0
UUID=82f03d9d-21a6-4f18-8af2-2f630a0263fc /boot                   xfs     defaults        0 0
/dev/mapper/cl-swap     swap                    swap    defaults        0 0
192.168.10.16 | CHANGED | rc=0 >>

/dev/mapper/cl-root     /                       xfs     defaults        0 0
UUID=702c12b4-224b-4679-9913-8c66e80cc466 /boot                   xfs     defaults        0 0
/dev/mapper/cl-swap     swap                    swap    defaults        0 0

1.26 Replace模块

该模块有点类似于sed命令,主要也是基于正则进行匹配和替换
范例:

以uuid开头的行加上注释
[root@node ~]# ansible   all   -m   replace  -a "path=/etc/fstab  regexp='^(UUID.*)' replace='#\1'"
192.168.10.16 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "msg": "1 replacements made"
}
192.168.10.17 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "msg": "1 replacements made"
}
192.168.10.18 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "msg": "3 replacements made"
}
[root@node ~]# ansible  all  -a  "cat  /etc/fstab "
192.168.10.18 | CHANGED | rc=0 >>

#UUID=59e57886-f23a-4fc4-b553-30218a4ecb63 /                       xfs     defaults        0 0
#UUID=bb2989b3-5461-4fdd-814a-f5398e452c51 /boot                   xfs     defaults        0 0
#UUID=2216e66a-8cda-4840-bac7-b553f4337750 swap                    swap    defaults        0 0
192.168.10.17 | CHANGED | rc=0 >>

/dev/mapper/cl-root     /                       xfs     defaults        0 0
#UUID=82f03d9d-21a6-4f18-8af2-2f630a0263fc /boot                   xfs     defaults        0 0
/dev/mapper/cl-swap     swap                    swap    defaults        0 0
192.168.10.16 | CHANGED | rc=0 >>

/dev/mapper/cl-root     /                       xfs     defaults        0 0
#UUID=702c12b4-224b-4679-9913-8c66e80cc466 /boot                   xfs     defaults        0 0
/dev/mapper/cl-swap     swap                    swap    defaults        0 0
去掉以#开头的
[root@node ~]# ansible  all  -m  replace   -a  "path=/etc/fstab    regexp='^#(.*)' replace='\1'"
192.168.10.17 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "msg": "1 replacements made"
}
192.168.10.16 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "msg": "1 replacements made"
}
192.168.10.18 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "msg": "3 replacements made"
}
[root@node ~]# ansible  all  -a  "cat  /etc/fstab "
192.168.10.17 | CHANGED | rc=0 >>

/dev/mapper/cl-root     /                       xfs     defaults        0 0
UUID=82f03d9d-21a6-4f18-8af2-2f630a0263fc /boot                   xfs     defaults        0 0
/dev/mapper/cl-swap     swap                    swap    defaults        0 0
192.168.10.16 | CHANGED | rc=0 >>

/dev/mapper/cl-root     /                       xfs     defaults        0 0
UUID=702c12b4-224b-4679-9913-8c66e80cc466 /boot                   xfs     defaults        0 0
/dev/mapper/cl-swap     swap                    swap    defaults        0 0
192.168.10.18 | CHANGED | rc=0 >>

UUID=59e57886-f23a-4fc4-b553-30218a4ecb63 /                       xfs     defaults        0 0
UUID=bb2989b3-5461-4fdd-814a-f5398e452c51 /boot                   xfs     defaults        0 0
UUID=2216e66a-8cda-4840-bac7-b553f4337750 swap                    swap    defaults        0 0

1.2.7 Setup模块

功能:setup模块来收集主机的系统信息,这些facts信息可以直接以变量的形式使用,如果主机较多,会影响执行速度,可以使用gather_facts:no来禁止Ansible收集facts信息

范例:

[root@node ~]# ansible    192.168.10.16   -m setup
[root@node ~]# ansible   all   -m   setup  -a   'filter=ansible_distribution_major_version'
192.168.10.17 | SUCCESS => {
    "ansible_facts": {
        "ansible_distribution_major_version": "7", 
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false
}
192.168.10.18 | SUCCESS => {
    "ansible_facts": {
        "ansible_distribution_major_version": "7", 
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false
}
192.168.10.16 | SUCCESS => {
    "ansible_facts": {
        "ansible_distribution_major_version": "7", 
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false
}
[root@node ~]# ansible  all  -m  setup  -a  "filter=ansible_all_ipv4_addresses"
192.168.10.18 | SUCCESS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "192.168.122.1", 
            "192.168.10.18"
        ], 
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false
}
192.168.10.17 | SUCCESS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "192.168.122.1", 
            "192.168.10.17"
        ], 
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false
}
192.168.10.16 | SUCCESS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "192.168.122.1", 
            "192.168.10.16"
        ], 
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false
}

Playbook

playbook介绍

image-20210808213835205

playbook剧本是由一个或多个“play”组成的列表
play的主要功能在于将预定义的一组主机,装扮成事先通过ansible中的task定义好的角色。Task实际是调用ansible的一个module,将多个play组织在一个playbook中,既可以让他们联合起来,按事先编排的机制执行预定义动作
Playbook文件时采用YAML语言编写的

2.1.1YAML语言

YAML是一个可读性高的用来表达资料序列的格式,YAML参考了其他多种语言,包括:XML、C语言、Python、Perl以及电子邮件格式RFC2822等。Clark Evans在2001年在首次发表了这种语言,另外ingy dot Net于 Oren Ben-Kiki也是这语言的共同设计者,目前很多软件中采有此格式的文件,如:ubuntu、ansible、docker、k8s等
YAML:YAML Ain‘t Markup Language,即YAML不是XML。不过在开发的这种语言时,YAML的意思其实是“Yet Another Markup Language”(仍是一种标记语言)

YAML 官方网站:http://www.yaml.org

2.1.2YAML语言特训给
  • YAML的可读性好
  • YAML和脚本语言的交互性好
  • YANL使用实现语言的数据类型
  • YAML有一个一致的信息模式
2.1.3YAML语法简介
  • 在单一文件第一行,用连续三个连字符"-"开始,还有选择性的连续三个点号(…)用来表示文件的结尾
  • 次行开始正常些Playbook的内容,一般建议写明该Playbook的功能
  • 使用#号注释代码
  • 缩进必须是统一的,不能空格和tab混用
  • 缩进的级别也必须是一致的,同样的缩进代表同样的级别,程序判别配置的级别是通过缩进结合换行来实现的YAML文件内容是区别大小写的,key/value的值均需大小写名敏感
  • 多个k/v可同行写也可以换行写,同时使用,分割
  • v可是哥字符串,可也是另一个列表
  • 一个完整的代码块功能需最少元素需包括name和task
  • 一个name只能包括一个task
  • YAML文件扩展名通常为yml或yaml

YAML的语法和其他高阶语言类似,并且可以简单表达清单、散列表、标量等数据结构、其结构通过空格来展示,序列里的项用"-"来代表,Map里的键值对用“.”分割,下面介绍常见的数据结构

2.1.3.1 List列表

列表由多个元素组成,且所有元素前均使用“-”大头
范例:

# A list of tasty fruits
- Apple
- Orange
- Strawberry
- Mango


[Apple,Orange,Strawberry,Mango]
2.1.3.2 Dictionary

子典通常由多个key于value构成
范例:

# An employee record
name: Example Developer
job: Developer
skill: Elite
也可以将key:value放置于[]中进行表示,用,分割多个key:value

#An employee record
{name: “Example Developer”,job: "Developer",skill: "Eilte"}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2XiOoA65-1637840564487)(D:/Typora/image-20210809095459470.png)]

2.1.4 三种常见的数据格式
  • XML: Extensible Markup Language,可扩展标记语言,用于数据交换和配置
  • JSON: JavaScript Object Notation .JavaScprit对象标记法,主要用来数据交换或配置,不支持注释
  • YAML: YAML Aint’t Markup Language YAML 不是一种标记语言,主要用来配置,大小写敏感,不支持tab

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LX08Qmju-1637840564488)(D:/Typora/image-20210809100323012.png)]

可以用工具互相转换,参考网站:

https://www.json2yaml.com/
http://www,bejson.com/json/json2yaml/

2.2Playbook核心元素

  • Hosts 执行远程主机列表
  • Tasks 任务集
  • Variables内置变量或自定义变量在playbook中调用
  • Templates模块,可替换模板文件中的变量并实现一些简单逻辑文件
  • Hadnlers和notify结合使用,由特定条件触发的操作,满足条件方才执行,否则不执行
  • tags标签:只当某条任务执行,用于选择运行playbook中的部分代码。ansible具有幂等性。因此会自动跳过没有变化的部分,即便如此,有些代码为测试其确实没有变化的时间依然会非常地长,此时,如果确信其没有变化,就可以通过tags跳过这些代码片段
2.2.1 hosts组件

Hosts:playbook中的每一个play的母的都是为了让特定主机以某个指定用户身份执行任务,hosts用于指定要执行指定任务的主机。须事先定义在主机清单中

one.example.com
one.example.com:twoexample.com
192.168.10.16
192.166.10.*
websrvs:dbsrvs          #或者,两个组的并集
websrvs:&dbsrvs         #与,两个组的交集
websrvs:!phoenix        #在websrvs组,但不在dbsrvs组

案例:

- hosts: websrvs:appsrvs
2.2.2 remote_user组件

remote_user:可用于Host和task中。也可以通过指定其通过sudo的方式在远程主机上执行任务。其可用于play全局或某任务:此外,甚至可以在速冻时使用sudo_user指定sudo时切换的用户

- host: websrvs
  remote_user: root
  |
  tasks:
     - name: test cibbection
       ping:
       remote_user: laowang
       sudo: yes               #默认sudo为root
       sudo_user:wang          #sudo为wang

2.2.3task列表和action组件

play的主体部分时task list,task list中有一个或多个task,各个task按次序逐个在hosts中指定的所有主机上执行,即在所有主机上完成第一个task后,再开始第二个task
task的目的时使用指定的参数执行模块,而在模块参数中可以使用变量,模块执行是幂等的,这意味着多次执行时安全的,因为其结构均一致
每个task都应该有其name,用于playbook的执行结果输出,建议其内容能清晰地描述任务执行步骤。如果未提供name,则action的结果将用于输出

task两种格式:
(1)action:module arguments
(2)module:arguments 建议使用
注意:shell和cimmand模块后面跟命令,而非key=value

---
- hosts:websrvs
  remote_user: root
  tasks: 
     - name: install httpd
       yum: name=httpd
     - name: start httpd
       service: name=httpd state=started enabled=yes
2.2.3 其它组件

某任务的状态在运行后为changed时,可通过“notify”通知给相应的handiers
任务可以哦通过“tags”打标签,可在ansible-playbook命令上使用-t指定进行调用

2.2.4 ShellScripts VS Playbook案例

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UE9optD2-1637840564489)(D:/Typora/image-20210810091150367.png)]

2.3.0 playbook命令

格式
ansible-play <filename.yml> … [options]

常见选项

-C --list					#只检查可能会发生的改变,但不真正执行操作
--list-hosts				#列出运行任务的主机
--list-tags					#列出tag
--list-tasks				#列出task
--limic 主机列表			 #只针对主机列表中的主机执行
-v -vv  -vvv				#显示过程

范例

ansible-playbook   file.yml    --check#只检测
ansible-playbook   file.yml    
ansible-playbook   file.yml    --list  websrvs
2.4 Playbook初步

利用playbook创建mysql用户

范例:mysql_user.yml

---
- hosts: dbsrvs
  remote_user: root
  
  tasks:
  	- name: create group
  	  group: name=mysql  system=yes gid=306
  	- name: create user
  	  user: name=mysql shell=/sbin/nologin system=yes group=mysql uid=306 home=/tmp/mysql  create_home=
  	  ***
[root@ansible ansible]# ansible-playbook   create_mysql.yml 

PLAY [dbsrvs] ******************************************************************

TASK [create group] ************************************************************
changed: [192.168.10.17]
changed: [192.168.10.16]

TASK [create user] *************************************************************
changed: [192.168.10.16]
changed: [192.168.10.17]

PLAY RECAP *********************************************************************
192.168.10.16              : ok=2    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
192.168.10.17              : ok=2    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@ansible ansible]# ansible dbsrvs  -a   'getent passwd mysql'
192.168.10.16 | CHANGED | rc=0 >>
mysql:x:306:306::/data/mysql:/sbin/nologin
192.168.10.17 | CHANGED | rc=0 >>
mysql:x:306:306::/data/mysql:/sbin/nologin
[root@ansible ansible]# ansible dbsrvs  -a   'id  mysql'
192.168.10.16 | CHANGED | rc=0 >>
uid=306(mysql) gid=306(mysql) 组=306(mysql)
192.168.10.17 | CHANGED | rc=0 >>
uid=306(mysql) gid=306(mysql) 组=306(mysql)

2.4.1利用playbook按照nginx

范例:install_nginx.yml

---
install
	- hosts: websrvs
	remote_user: root
	
	tasks:
	  - name: add group nginx
	    user: name=nginx state=present
	  - name: add user nginx
	    user: name=nginx  state=present group=nginx
	  - name: install  Nginx
	    yum: name=nginx  state=present
	  - name: html   page
	    copy: src=files/index.html  dest=/usr/share/nginx/html/index.html
	  - name: Start Nginx
	    service: name=nginx  state=started enabled=yes
2.4.2利用playbook安装和卸载httpd

范例:

[root@localhost httpd]# ansible-playbook --syntax-check install_httpd.yml

---
#install httpd
- hosts: websrvs
  remote_user: root
  gather_facts: no
  
  tasks: 
   - name: Install httpd
     yum: name=httpd state=present
   - name: Install configure file
     copy: src=files/httpd.conf dest=/etc/httpd/httpd.conf
   - name: start service
     service: name=httpd state=started enabled=yes
ansible-playbook   install_httpd.yml  --limit   192.168.10.16

删除httpd

---
- hosts: websrvs
  remote_user: root
  gather_facts: no


  tasks:
   - name: remove  httpd  package
     yum: name=httpd   state=absent
   - name: remove apache  user
     user: name=apache  state=absent
   - name: remove config file
     file:  name=/etc/httpd  state=absent
   - name: remove  web html
     file: name=/vat/www/html/index.html state=absent

2.5.1Playbook使用handler和notify

handlers本质是task list,类似于MySql中的触发器触发的行为,其中的task与前述的task没有本质上的不同主要用于关注的资源发生变化时,才会采取一定的操作。而Notify对应的action可用于在每个paly的最后被触发,这样可避免多次有改变发生时每次都执行指定的操作,仅在所有的变法发生完成后一次性地执行指定操作。在notify中列出的操作称为handler,也即notify中调用handler中定义的操作

案例:yum -y install lrzsz

---
#install httpd
- hosts: websrvs
  remote_user: root
  gather_facts: no
  
  tasks: 
   - name: Install httpd
     yum: name=httpd state=present
   - name: Install configure file
     copy: src=files/httpd.conf dest=/etc/httpd/httpd.conf
     notify: restart  httpd
   - name: start service
     service: name=httpd state=started enabled=yes
  
  handlers: 
   - name: restart  httpd
     service: name=httpd  state=restarted
2.6.1Playbook中使用tags组件

在playbook文件中,可以利用tags组件,为特定task指定标签,当在执行playbook时,可以只执行特定tags的task,而非整个playbook

案例:

---
#install httpd
- hosts: websrvs
  remote_user: root
  gather_facts: no
  
  tasks: 
   - name: Install httpd
     yum: name=httpd state=present
   - name: Install configure file
     copy: src=files/httpd.conf dest=/etc/httpd/httpd.conf
     tags: conf
   - name: start service
     service: name=httpd state=started enabled=yes
     
 ansible-playbook   -t conf,service  httpd.yml
2.7.1Playbook中使用变量

变量名:仅能由字母、数字和下划线组成、且只能以字母开头
变量定义:

variadble=value

范例:

http_port=80

变量调用方式:

通过{{ variable_name }}调用变量,且变量名前后建议加空格,有时用"{{ variable_name }}"才生效

变量来源:
1.ansible的setup facts远程主机的所有变量都可直接调用

2.通过命令行指定变量,优先级最高

ansible-playbook  -e varname=value

3.在playbook文件中定义

vars:
- var1: value1
- var2: value2
范例: 使用setup模块中变量

要求在playbook中使用,不用ansible命令调用(会有问题的)

---
#var.yml
- hosts: websrvs
  remote_user: root
  
  tasks:
   - name: create  log file
     file: name=/var/log/{{ ansible_fqdn }}.log state=touch
     
#var.yml
- hosts: websrvs
  remote_user: root
  tasks:
   - name: create log  file
     file: name=/data/{{ ansible_nodename  }}.log state=touch  owner=root mode=600
2.7.2在playbook命令行中定义变量

范例:

[root@ansible ansible]# cat   var2.yml
---
- hosts: websrvs
  remote_user: root

  tasks: 
   - name: install  package
     yum: name={{ pkname }} state=present
[root@ansible ansible]# ansible-playbook   -e  pkname=memcached    var2.yml 

PLAY [websrvs] *************************************************************************************

TASK [Gathering Facts] *****************************************************************************
ok: [192.168.10.16]
ok: [192.168.10.17]

TASK [install  package] ****************************************************************************
changed: [192.168.10.17]
changed: [192.168.10.16]

PLAY RECAP *****************************************************************************************
192.168.10.16              : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
192.168.10.17              : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

范例

---
- hosts: websrvs
  remote_user: root
  
  vars:
   - username: user1
   - groupname: group1
   
   tasks:
   - name: create  group
     group: name={{ groupname }} state=present
   - name: create  user
     user: name={{ username }}  group={{ groupname }} state=present

2.7.3使用变量

可以在一个独立的playbook文件中定义变量,在另一个playbook文件中引用变量文件的变量

比playbook中定义的变量优先级高

vim  vars.yml
---
#variadb  file
package_name: vsftpd
service_name: vsftpd

vim  var4.yml
---
#install  app  and   configure
- hosts: appsrvs
  remote_user:root
   vars_files:
  - vars.yml
  
  tasks:
  - name: install  package
    yum: name={{ pack_name }}
    tags: install
  - name: start service
    service: name={{ service_name }} state=started enabled=yes
   handlers:
    ansible-playbook   var4.yml
2.7.4主机清单文件中定义变量

主机变量:

在inventory主机清单文件中为指定的主机定义变量以便于在playbook中使用

范例:

[wesrvs]
www1.aqlinux.com  http_port=80  maxRequestsPerChild=808
www2.aqlinux.com  http_port=8080 maxRequestsRerChild=909

组(公共)变量:

在inventory主机清单文件中赋予给指定组内所有主机上的在playbook中可用的变量

[websrvs]
www1.aqlinux.com
www2.aqlinux.com

[websrvs:vars]
ntp_server=ntp.aqlinux.com
nfs_server=nfs.aqlinux.com

范例:

[websrvs]
192.168.10.16  http_port=8080  hname=www1
192.168.10.17  http_port=80    hname=www2
2.8template模块

模块是一个文本文件,可以做为生成文件的模块,并且模块文件中还可嵌套jinjayufa

网站https://jinja.palletsprojects.com/en/2,11x/

2.8.1jinja2语言

jinja2语言使用字面量,有下面形式:

字符串:使用单引号或双引号
数字:整数,浮点数
列表:[ltem1,item2…]
元组:[item1,item2…]
字典:[key1:value1,key2:value2…]
布尔型: true/false
算术运算: +,-,*,/,//,%,**
比较运算符: ==,!=,>,>=,<,<=
逻辑运算:and,or,not
流表达式:For,if,when

字面量

表达式最简单的新式就是字面量,字面量表示诸如字符串和数值的Python对象,如"Hellp Word"双引号或单引号中间的一切都是字符串,无论何时你需要在模板中使用一个字符串(比如函数调用,过滤器或只是包含或继承一个模板的参数)如42,43
数据可以为整数和浮点数,如果有小数点,则为浮点数,否则为整数,在Python里,42和42.0是不一样的

算数运算

jinja允许用计算值,支持下面的运算符
+:把两个对象加到一起。通常对象是素质,但是如果两者是字符串或列表,你可以用这种方式来斜街它们,无论如何这不是首选的连接字符串的方式。连接字符串~运算符。{{1+1}}等于2
-:用第一个数减去第二个数{{3-2}}等于1
/:对两个数做处罚的余数,返回值是一个浮点数、{{1/2}}等于{{0.5}}
//:对两个数做触发返回正整数。{{20//7}}等于2
%:计算整数除法的余数、{{11%7}}等于4
*:用右边的数乘左边的操作数。{{ 2 * 2 }} 会返回4,也可以用于重复一个字符串多次。{{’=’*80}}会打印80整个等号的横条
**:取左操作数的右操作数的次幂。{{2 * * 3}}会返回8

比较操作符

==:比较两个对象是否相等
!=:比较两个对象是否不等
》 如果左边大于右边返回true
》= 如果左边大于等于右边返回true
《如果左边小于右边 返回true
《= 如果左边小于等于右边 返回true
逻辑运算符

对于if语句,在for过滤或if表达式中,它可以用于联合多个表达式
and 如果左操作数和右操作数为真则返回true
or 如果左操作数和右操作数有一个为真则返回true
not 对一个表达式取反
{expr}表达式组
true/false true永远是true, 而false始终是false

2.8.2 template

templaste功能:可以根据和参考模块文件,动态生成相类似的配置文件
template文件必须存放于templates目录下,且命名为.j2结尾
yaml/yml 文件需和template目录平级

案例 vim templnginx.yml

mkdir template

yum -y install nginx

cp /etc/nginx/nginx.conf template/nginx.conf.j2

---
- hosts: websrvs
  remote_user: root

  tasks:
   - name: install  nginx
     yum: name=nginx
   - name: template config to  remote  hosts
     template: src=nginx.conf.j2  dest=/etc/nginx/nginx.conf
   - name: start service
     service: name=nginx state=started  enabled=yes

template算术运算
范例:

vim  nginx.conf.j2
worker_processes  {{ ansible_processor_vcpus**2 }}
worker_processes  {{ ansible_processor_vcpu+2  }}

范例:

cat   templnginx.yml
---
- hosts: websrvs
  remote_user: root

  tasks:
   - name: install  nginx
     yum: name=nginx
   - name: template config to  remote  hosts
     template: src=nginx.conf.j2  dest=/etc/nginx/nginx.conf
     notify: restart nginx
   - name: start service
     service: name=nginx state=started  enabled=yes
     
  handlers:
   - name: restart nginx
     service: name=nginx  state=restarted

2.8.3 template中使用流程控制for和if
template中也可以使用流程控制for循环和if条件判断,实现动态生成文件功能

2.8.4playbook使用when

when语句,可以实现条件测试。如果需要根据变量,facts或此前任务的执行结果来做为某task执行与否的前提时要用到条件测试,通过在task后添加when子句即可使用条件测试,jinja2的语法格式

范例

---
- hosts: websrvs
  remote_user: root
  tasks:
   - name: "shutdown  RedHat  flavored  systems"
     command: /sbin/shutdown  -h  now
     when: ansible_os_family == "RedHat"

范例:

---
- hosts: websrvs
  remote——user: root
  tasks:
   - name: add  froup  nginx
     tags: user
     user: name=nginx state=present
   - name: add user  nginx
     user: name=nginx  state=present group=nginx
   - name: Install  nginx
     yum: name=nginx  state=present
   - name: restart  nginx
     service: name=nginx  state=restarted
     when: ansible_distribution_major_version == "6"
     

范例:

---
- hosts: websrvs
  remote_user: root
  tasks:
   - name: install conf  file to centos
     template: src=nginx.conf.c7.j2 dest=/data/nginx.conf
     when:  ansible_distribution_major_version =="7"
   - name: install  conf  file to  centos6
     template: src=nginx.conf.c6.j2 dest=/etc/nginx/nginx.conf
     when: ansible_distribution_major_version =="6"
2.8.6playbook使用迭代with_items

迭代:当有需要重复执行任务时,可以使用迭代机制
对迭代项的引用,固定变量名为”item“
要在task中使用with_items给定要迭代的元素列表
列表元素格式:

  • 字符串
  • 字典

范例

---
- hosts: websrvs
  remote_user: root

  tasks:
    - name: add  servsral  users
      user: name={{ item }} state=present  groups=wheel
      with_items:
          - testuser1
          - testuser2

#上面语句的功能等同于下面的语句
  - name: add  user  testuser1
    user: name=testuser1  state=present groups=wheel
  - name: add  user  testuser2
    user: name=testuser2 state=prenent groups=wheel
#查看是否成功
[root@ansible ansible]# ansible websrvs   -a  'getent passwd'
testuser1:x:1003:1003::/home/testuser1:/bin/bash
testuser2:x:1004:1004::/home/testuser2:/bin/bash
[root@ansible ansible]# ansible websrvs   -a  'id testuser1'
192.168.10.16 | CHANGED | rc=0 >>
uid=1003(testuser1) gid=1003(testuser1)=1003(testuser1),10(wheel)
192.168.10.17 | CHANGED | rc=0 >>
uid=1003(testuser1) gid=1003(testuser1)=1003(testuser1),10(wheel)

范例

---
#remove  mariadb server
- hosts:  websrvs:!192.168.10.17
  remote_user: root
  tasks:
    - name: stop  service
      shell: /etc/init.d/mysql/stop
    - name: delecte files and  dir
      file: path={{ item }} state=absent
      with_items:
      - /usr/local/mysql
      - /usr/local/mariadb-10.2.27-linux-x86_64
      - /etc/init.d/mysqld
      - /etc/profile.d/mysql.sh
      - /etc/my.cnf
      - /data/mysql
      - name: delete user
        user: name=mysql  state=absent remove=yes

范例

---
- hosts: websrvs
  remote_user: root
  taks
   - name: install some packages
     yum: name={{ item }} state=present
     with_items:
       - nginx
       - mencached
       - php-fpm

范例:

---
- hosts: websrvs
  remote_user: root
  tasks:
    - name: copy file
      copy: src={{  item }} dest=/tmp/{{ item }}
      with_items:
        - file1
        - file2
        - file3
     - name: yum  install  httpd
       yum: name={{ item }} state=present
       with_items:
        - apr
        - apr-util
        - httpd

迭代嵌套子变量:在迭代中,还可以嵌套子变量,关联多个变量在一起使用

---
- hosts: websrvs
  remote_user: root
  
  tasks:
    -  name: add some  groups
       group: name={{ item }} state=present
       with_items:
         - nginx
         - mysql
         - apache
    - name: add some users
      user: name={{ item.name }} group={{ item.group }} state=present
      with_items:
         - { name: 'nginx',group: 'nginx' }
         - { name: 'mysql',group: 'mysql' }
         - { name: 'apache',group: 'apache'}

范例:

[root@ansible ansible]# cat   with_item2.yml 
---
- hosts: websrvs
  remote_user: root
  
  tasks:
    - name: add some  groups
      group: name={{ item }} state=present
      with_items:
         - g1
         - g2
         - g3
    - name: add some users
      user: name={{ item.name }} group={{ item.group }} home={{ item.home }} create_home=yes  state=present
      with_items:
         - { name: 'user11', group: 'g1', home: '/data/user1' }
         - { name: 'user22', group: 'g2', home: '/data/user2' }
         - { name: 'user33', group: 'g3', home: '/data/user3' }
################
[root@ansible ansible]# ansible websrvs  -a  'id  user11'
192.168.10.16 | CHANGED | rc=0 >>
uid=1005(user11) gid=1005(g1)=1005(g1)
192.168.10.17 | CHANGED | rc=0 >>
uid=1005(user11) gid=1005(g1)=1005(g1)
[root@ansible ansible]# ansible websrvs  -a  'getent passwd  user11'
192.168.10.16 | CHANGED | rc=0 >>
user11:x:1005:1005::/data/user1:/bin/bash
192.168.10.17 | CHANGED | rc=0 >>
user11:x:1005:1005::/data/user1:/bin/bash
[root@ansible ansible]# ansible websrvs  -a  'ls  -l /data'
192.168.10.16 | CHANGED | rc=0 >>
总用量 0
-rw-------. 1 root   root  0 815 16:04 bogon.log
drwx------. 3 user11 g1   78 817 09:49 user1
drwx------. 3 user22 g2   78 817 09:49 user2
drwx------. 3 user33 g3   78 817 09:49 user3
192.168.10.17 | CHANGED | rc=0 >>
总用量 0
-rw-------. 1 root   root  0 815 16:04 bogon.log
drwx------. 3 user11 g1   78 817 09:49 user1
drwx------. 3 user22 g2   78 817 09:49 user2
drwx------. 3 user33 g3   78 817 09:49 user3

3 roles角色

角色是ansible自1.2版本引入的新特性,用于层次性,结构化地组织playbook。roles能够根据层次性结构自动装载变量。tasks以及handlers等。要使用roles只需要在playbook中使用include指令即可,简单来讲,roles就是通过分别将变量、文件、任务、模块及处理器放置于单独的目录中,并可以便捷地include他们的一种机制。角色一般用于基于主机构建服务的场景中,但也可以构建守护进程等场景中

运维复杂的场景:建议使用roles,代码复用度很高

roles:多个角色的集合,可以将很多个的role,分别放至roles目录下的独立子目录中

roles/
mysql/
httpd/
nginx/
redis/

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UcbWYOui-1637840564490)(D:/Typora/image-20210817101431550.png)]

每个角色,以特定的层级目录结构进行组织

roles目录结构
playbook.yml
roles/
project/
tasks/
files/
vars/
templates/
handlers/
default/
meta/

Roles各目录作用

roles/project/:项目名称,有以下子目录

  • files/:存放由copy或script模块等调用的文件
  • templates/: remplate模块查找所需要模板文件的目录
  • tasks/:定义task,role的基本元素,至少应该包含一个名为main.yml文件;其它的文件需要在此文件中通过include进行包含
  • handlers/: 至少应该包含一个名为main.yml的文件:其它的文件需要在此文件中通过include进行包含
  • vars/:定义变量,至少应该包含一个名为main.yml的文件;其他的文件需要在此文件中通过include进行包含
  • meta/: 定义当前角色的特殊设定及其依赖关系,至少应该包含一个名为main.yml其他文件需在此文件中通过include进行包含
  • default/: 设定默认变量时使用此目录中的main.yml文件,比vars的优先级低

3.2创建role

创建role的步骤
(1)创建以roles命名的目录
(2)在roles目录中分别创建以各角色名称命名的目录,如webservers等
(3)在每个角色命令的目录中分别创建files、handlers、meta、tasks、templates、和vars目录;用不到的目录可以创建为空目录,也可以不创建
(4)在playbook文件中,调用各角色
针对大型项目使用Roles进行编排
范例:roles的目录结构

3.3playbook调用角色

调用角色方法1

---
- hosts: websrvs
  remote_user: root
  roles:
   - mysql
   - memcached
   - nginx

调用角色方法2
键role用于指定角色名称,后续的k/v用于传递变量的角色

---
- hosts: all
  remote_user: root
  roles:
   - mysql
   - { role: nginx, username: nginx }

调用角色方法3
还可以基于条件测试实现角色调用

---
- hosts: all
  remote_user: root
  roles:
   - { role: nginx, username: nginx, when: ansible_distribution_major_version == '7' }

3.4 roles中tags使用

---
- hosts: websrvs
  remote_user: root
  roles:
  - { role: nginx ,tags: [ 'nginx','web' ] ,when: ansible_distribution_major_version =="7" }
  - { role: httpd ,tags: [ 'httpd','web'] }
  - { role: mysql ,tags: [ 'mysql','db' ] }
  - { role: mariadb ,tags: [ 'mariadb','db' ] }
ansible-playbook  --tags="nginx.httpd.mysql" nginx-role.yml

创建一个httpd角色

创建所在角色需要得yml文件和必要得启动程序main.yml

创建roles角色这个目录
最好在roles目录下创建
[root@ansible ansible]# ansible-galaxy  list
# /root/.ansible/roles
- nginxinc.nginx, 0.20.0
# /usr/share/ansible/roles
# /etc/ansible/roles
***
这里我们在/data/ansible/创建
mkdir  roles
mkdir    httpd/{tasks,files,handlers}  -pv  在roles下创建httpd这个角色所需要得东西
[root@ansible ansible]# tree  roles/
roles/
└── httpd
    ├── files
    │   ├── httpd.conf
    │   └── index.html
    ├── handlers
    │   └── main.yml
    └── tasks
        ├── config.yml
        ├── index.yml
        ├── install.yml
        ├── main.yml
        └── service.yml
vim roles/httpd/tasks/install.yml
- name: install httpd  package
  yum: name=httpd
vim   roles/httpd/tasks/config.yml
- name:  config file
  copy:  src=httpd.conf  dest=/etc/httpd/conf/ backup=yes
  notify: restart
#这里指定了  handles 所以待会要创建   src源文件从/etc/httpd下拷贝一份到 files下起名为httpd.conf 修改端口号为9527
vim  roles/httpd/tasks/index.yml
- name: index.html
  copy: src=index.html  dest=/var/www/html/
#####设置个网页文件为html 本地的html文件创建在files下
vim   roles/httpd/tasks/service.yml
- name: starte service
  service: name=httpd state=started enabled=yes
集合上边所说的需要一个handlers文件所以现在要去写一个
vim  roles/httpd/handlers/main.yml
- name: restart
  service: name=httpd state=restarted
做到这里以及创建快完成了写一个启动的文件
vim  roles/httpd/tasks/main.yml
- include: install.yml
- include: config.yml
- include: index.yml
- include: service.yml
在再与roles这个角色目录 同等目录下创建启动httpd的yml文件
vim   /data/ansible/role_httpd.yml
---
# httpd  role
- hosts: websrvs
  remote_user: root

  roles:
    - httpd
就可以执行此角色了
ansible-playbook  role_httpd.yml
在查看被控端是否有9527这个端口  如果有就是启动成功了
[root@ansible ansible]# ansible  websrvs   -a  'ss  -ntl'
192.168.10.17 | CHANGED | rc=0 >>
State      Recv-Q Send-Q Local Address:Port               Peer Address:Port  LISTEN     0      128         :::9527                    :::*    
192.168.10.16 | CHANGED | rc=0 >>
State      Recv-Q Send-Q Local Address:Port               Peer Address:Port LISTEN     0      128         :::9527                    :::*       
##创建一个memcacheed角色
[root@ansible ansible]# tree roles/memcached/
roles/memcached/
├── tasks
│   ├── config.yml
│   ├── install.yml
│   ├── main.yml
│   └── service.yml
└── templates
    └── memcached.j2
创建一个运算集
[root@ansible tasks]# cat   main.yml 
- include: install.yml
- include: config.yml
- include: service.yml
[root@ansible tasks]# cat  install.yml 
- name: install
  yum: name=memcached
[root@ansible tasks]# cat  service.yml 
- name: service
  service: name=memcached state=started enabled=yes
[root@ansible tasks]# cat config.yml 
- name: config file
  template: src=memcached.j2  dest=/etc/sysconfig/memcached

[root@ansible tasks]# cat  ../templates/memcached.j2 
PORT="11211"
USER="memcached"
MAXCONN="1024"
CACHESIZE="{{ansible_memtotal_mb//4}}"
OPTIONS=""
在同级目录(roles)创建一个role_memcached.yml
[root@ansible ansible]# cat  role_memcached.yml 
---
- hosts: websrvs
  
  roles:
  - role: memcached
  
  [root@nb ~]# cat  /etc/sysconfig/memcached 
PORT="11211"
USER="memcached"
MAXCONN="1024"
CACHESIZE="244"
OPTIONS=""
[root@nb ~]# ss   -ntl
State       Recv-Q Send-Q          Local Address:Port                         Peer Address:Port              
LISTEN      0      128                         *:11211                                   *:*   
ansible学习资料

http://galaxy.ansible.com
https://galaxy.ansible.com/explore#/
http://github.com/
http://ansible.com.cn/
https://github.com/ansible/ansible
install.yml
├── main.yml
└── service.yml
vim roles/httpd/tasks/install.yml

  • name: install httpd package
    yum: name=httpd
    vim roles/httpd/tasks/config.yml
  • name: config file
    copy: src=httpd.conf dest=/etc/httpd/conf/ backup=yes
    notify: restart
    #这里指定了 handles 所以待会要创建 src源文件从/etc/httpd下拷贝一份到 files下起名为httpd.conf 修改端口号为9527
    vim roles/httpd/tasks/index.yml
  • name: index.html
    copy: src=index.html dest=/var/www/html/
    #####设置个网页文件为html 本地的html文件创建在files下
    vim roles/httpd/tasks/service.yml
  • name: starte service
    service: name=httpd state=started enabled=yes
    集合上边所说的需要一个handlers文件所以现在要去写一个
    vim roles/httpd/handlers/main.yml
  • name: restart
    service: name=httpd state=restarted
    做到这里以及创建快完成了写一个启动的文件
    vim roles/httpd/tasks/main.yml
  • include: install.yml
  • include: config.yml
  • include: index.yml
  • include: service.yml
    在再与roles这个角色目录 同等目录下创建启动httpd的yml文件
    vim /data/ansible/role_httpd.yml

httpd role

  • hosts: websrvs
    remote_user: root

    roles:

    • httpd
      就可以执行此角色了
      ansible-playbook role_httpd.yml
      在查看被控端是否有9527这个端口 如果有就是启动成功了
      [root@ansible ansible]# ansible websrvs -a ‘ss -ntl’
      192.168.10.17 | CHANGED | rc=0 >>
      State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 :::9527 ::😗
      192.168.10.16 | CHANGED | rc=0 >>
      State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 :::9527 ::😗

```bash
##创建一个memcacheed角色
[root@ansible ansible]# tree roles/memcached/
roles/memcached/
├── tasks
│   ├── config.yml
│   ├── install.yml
│   ├── main.yml
│   └── service.yml
└── templates
    └── memcached.j2
创建一个运算集
[root@ansible tasks]# cat   main.yml 
- include: install.yml
- include: config.yml
- include: service.yml
[root@ansible tasks]# cat  install.yml 
- name: install
  yum: name=memcached
[root@ansible tasks]# cat  service.yml 
- name: service
  service: name=memcached state=started enabled=yes
[root@ansible tasks]# cat config.yml 
- name: config file
  template: src=memcached.j2  dest=/etc/sysconfig/memcached

[root@ansible tasks]# cat  ../templates/memcached.j2 
PORT="11211"
USER="memcached"
MAXCONN="1024"
CACHESIZE="{{ansible_memtotal_mb//4}}"
OPTIONS=""
在同级目录(roles)创建一个role_memcached.yml
[root@ansible ansible]# cat  role_memcached.yml 
---
- hosts: websrvs
  
  roles:
  - role: memcached
  
  [root@nb ~]# cat  /etc/sysconfig/memcached 
PORT="11211"
USER="memcached"
MAXCONN="1024"
CACHESIZE="244"
OPTIONS=""
[root@nb ~]# ss   -ntl
State       Recv-Q Send-Q          Local Address:Port                         Peer Address:Port              
LISTEN      0      128                         *:11211                                   *:*   
ansible学习资料

http://galaxy.ansible.com
https://galaxy.ansible.com/explore#/
http://github.com/
http://ansible.com.cn/
https://github.com/ansible/ansible
https://github.com/ansible-examples

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值