自动化运维工具——【ansible】——从菜鸟到菜鸟

一、ansible详解

  • 1.1、什么是ansible

ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet、cfengine、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。ansible是基于模块工作的,本身没有批量部署的能力。 ansible是基于 paramiko 开发的,并且基于模块化工作,本身没有批量部署的能力。真正具有批量部署的是ansible所运行的模块,ansible只是提供一种框架。ansible不需要在远程主机上安装client/agents,因为它们是基于ssh来和远程主机通讯的。且真正具有批量部署的是ansible所运行的模块,ansible只是提供一种框架。主要包括:如下:

  • 连接插件connection plugins:负责和被监控端实现通信;
  • host inventory:指定操作的主机,是一个配置文件里面定义监控的主机;
  • 各种模块核心模块、command模块、自定义模块;
  • 借助于插件完成记录日志邮件等功能;
  • playbook:剧本执行多个任务时,非必需可以让节点一次性运行多个任务。
  • ansible目前已经已经被红帽官方收购,是自动化运维工具中大家认可度最高的,并且上手容易,学习简单。是每位运维工程师必须掌握的技能之一。
  • 1.2、ansible的特点
  • 部署简单,只需在主控端部署Ansible环境,被控端无需做任何操作;
  • 默认使用SSH协议对设备进行管理;(ansible和远程主机有连接是因为ssh协议 ansible要对远程主机进行免密登录 ssh–22)
  • 有大量常规运维操作模块,可实现日常绝大部分操作;
  • 配置简单、功能强大、扩展性强;
  • 支持API及自定义模块,可通过Python轻松扩展;
  • 通过Playbooks来定制强大的配置、状态管理;
  • 轻量级,无需在客户端安装agent,更新时,只需在操作机上进行一次更新即可;
  • 提供一个功能强大、操作性强的Web管理界面和REST API接口——AWX平台。
  • 1.3、ansible常用模块

在这里插入图片描述

  • 如上图所见 ansible常用模块如下列所示:
  • ansible core : ansible 自身核心模块
  • host inventory: 主机库,定义可管控的主机列表
  • connection plugins: 连接插件,一般默认基于 ssh 协议连接
  • modules:core modules (自带模块 核心) custom modules (自定义模块)
    playbooks :剧本,按照所设定编排的顺序执行完成安排任务
  • 1.4、ansible任务执行
ansible任务执行模式:

Ansible 系统由控制主机对被管节点的操作方式可分为两类,即adhoc和playbook:

  • ad-hoc模式(点对点模式): 使用单个模块,支持批量执行单条命令。ad-hoc 命令是一种可以快速输入的命令,而且不需要保存起来的命令。就相当于bash中的一句话shell。
  • playbook模式(剧本模式): 是Ansible主要管理方式,也是Ansible功能强大的关键所在。playbook通过多个task集合完成一类功能,如Web服务的安装部署、数据库服务器的批量备份等。可以简单地把playbook理解为通过组合多条ad-hoc操作的配置文件。
ansible执行流程:

是Ansible主要管理方式,也是Ansible功能强大的关键所在。playbook通过多个task集合完成一类功能,如Web服务的安装部署、数据库服务器的批量备份等。可以简单地把playbook理解为通过组合多条ad-hoc操作的配置文件。

  • 1.5、ansible基础命令
  • ansible hosts(主机清单) -m module_name(模块名) -a job(对后端主机进行的操作)
  • -M 指定模块路径
  • -m 使用模块,默认 command 模块
  • -a or –args 模块参数
  • -i inventory 文件路径,或可执行脚本
  • -k 使用交互式登录密码
  • -e 定义变量
  • -v 详细信息,-vvvv 开启 debug 模式
  • ansible的执行结果:
  • ansible的执行结果
  • 绿色 执行成功
  • 红色 执行失败
  • 黄色 执行成功 并且对后端的主机进行了修改
  • 紫色 警告

二、环境部署及实操

  • 环境部署如下

所需安装包从这里获取:
链接:https://pan.baidu.com/s/122DrPPev90Q3cVEN6uCEbw
提取码:ozal

服务IP
ansible192.168.20.10
客户端01192.168.20.20
客户端02192.168.20.30
  • 虚拟环境实操如下
  • 2.1、安装ansible (联网安装和脱网安装)
先展示脱网安装在做联网安装
- 
- 把所需的安装包拖进ansible服务器新建的文件夹ansibleapp内
[root@lpj1 ~]#  createrepo /root/app
Directory /root/app must exist
[root@lpj1 ~]#  createrepo /root/ansibleapp
Spawning worker 0 with 11 pkgs
Workers Finished
Saving Primary metadata
Saving file lists metadata
Saving other metadata
Generating sqlite DBs
Sqlite DBs complete
[root@lpj1 ~]# ls /root/ansibleapp/
ansible-2.4.2.0-2.el7.noarch.rpm
libyaml-0.1.4-11.el7_0.x86_64.rpm
python2-jmespath-0.9.0-3.el7.noarch.rpm
python-babel-0.9.6-8.el7.noarch.rpm
python-httplib2-0.9.2-1.el7.noarch.rpm
python-jinja2-2.7.2-2.el7.noarch.rpm
python-markupsafe-0.11-10.el7.x86_64.rpm
python-paramiko-2.1.1-2.el7.noarch.rpm
python-passlib-1.6.5-2.el7.noarch.rpm
PyYAML-3.10-11.el7.x86_64.rpm
repodata
sshpass-1.06-2.el7.x86_64.rpm
- 新做一个yum源
[root@lpj1 ~]# cd /etc/yum.repos.d/
[root@lpj1 yum.repos.d]# vim ansible.repo
[root@lpj1 yum.repos.d]# cat ansible.repo 
[ansible]
name=ansible
baseurl=file:///root/ansibleapp
enabled=1
gpgcheck=0
- 进行安装及查看版本
[root@lpj1 yum.repos.d]# yum -y install ansible
[root@lpj1 yum.repos.d]# ansible  --version
ansible 2.4.2.0
  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, Aug  7 2019, 00:51:29) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
联网安装如下:(能够ping通baidu)
[root@lpj2 ~]# cd /etc/yum.repos.d/
[root@lpj2 yum.repos.d]# wget  http://mirrors.aliyun.com/repo/Centos-7.repo
--2020-06-10 16:17:47--  http://mirrors.aliyun.com/repo/Centos-7.repo
正在解析主机 mirrors.aliyun.com (mirrors.aliyun.com)... 60.221.72.241, 60.221.72.243, 124.165.216.248, ...
正在连接 mirrors.aliyun.com (mirrors.aliyun.com)|60.221.72.241|:80... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:2523 (2.5K) [application/octet-stream]
正在保存至: “Centos-7.repo.1”

100%[==================================>] 2,523       --.-K/s 用时 0s      

2020-06-10 16:17:47 (311 MB/s) - 已保存 “Centos-7.repo.1” [2523/2523])


[root@lpj2 yum.repos.d]# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
--2020-06-10 16:15:29--  http://mirrors.aliyun.com/repo/epel-7.repo
正在解析主机 mirrors.aliyun.com (mirrors.aliyun.com)... 124.165.216.238, 139.170.154.152, 116.177.243.231, ...
正在连接 mirrors.aliyun.com (mirrors.aliyun.com)|124.165.216.238|:80... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:664 [application/octet-stream]
正在保存至: “/etc/yum.repos.d/epel.repo”

100%[==================================>] 664         --.-K/s 用时 0s      

2020-06-10 16:15:29 (152 MB/s) - 已保存 “/etc/yum.repos.d/epel.repo” [664/664])


2020-06-10 16:11:41 (352 MB/s) - 已保存 “Centos-7.repo” [2523/2523])
[root@lpj2 yum.repos.d]#  yum -y install ansible
查看版本
[root@lpj2 yum.repos.d]# ansible --version
ansible 2.9.9
  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, Aug  7 2019, 00:51:29) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]

  • 2.2、ansible 配置公私钥
  • 上面我们已经提到过 ansible 是基于 ssh 协议实现的,所以其配置公私钥的方式与 ssh 协议的方式相同,下面说明免密登录的原理和具体操作:
  • 免密登录的原理:免密登录的原理
    主控端生成一对密钥,将公钥传递到远程主机上,当主控端想要连接远程主机时,远程主机会随机发送一串字符给主控端,主控端将这串字符用私钥加密,返回给远程主机,远程主机使用公钥将加密的字符解密,如果和自己生成的字符一致,则验证通过,可以进行登录
主控端生成秘钥
[root@lpj1 ~]# ssh-keygen  ## 4次回车
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
Created directory '/root/.ssh'.
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:wed2LJ4toiiTfH49BaIzfkoZqedj7lH5J7Fil3OdziY root@lpj1
The key's randomart image is:
+---[RSA 2048]----+
|                 |
|       .         |
|        o .      |
|     ....+ .     |
|    o.o.S.+ o    |
|   .++ . *.* .   |
| ..o=oo.O.* +    |
|  =+=+o+o*E+.    |
|   OB=.  . oo    |
+----[SHA256]-----+
[root@lpj1 ~]# cd /root/.ssh/   
[root@lpj1 .ssh]# ls 
id_rsa  id_rsa.pub
id_rsa私钥  id_rsa.pub公钥
公钥传递到远程主机上
[root@lpj1 .ssh]# ssh-copy-id root@192.168.20.20
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
The authenticity of host '192.168.20.20 (192.168.20.20)' can't be established.
ECDSA key fingerprint is SHA256:toHBDUUac+V6dbIrzsgiZfD38kR35IwY6NsDfkEwyXE.
ECDSA key fingerprint is MD5:4c:9f:c4:1b:d8:1e:bf:97:80:e6:55:f6:68:f1:56:1e.
Are you sure you want to continue connecting (yes/no)? yes
/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.20.20's password: 输入所远程连接主机的用户密码

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'root@192.168.20.20'"
and check to make sure that only the key(s) you wanted were added.
远程连接第二台
[root@lpj1 .ssh]# ssh-copy-id root@192.168.20.30
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
The authenticity of host '192.168.20.30 (192.168.20.30)' can't be established.
ECDSA key fingerprint is SHA256:bEN7HssU4h/61Fs5KCK9FM4iZCBIa76702eEBpGHHPU.
ECDSA key fingerprint is MD5:05:0d:46:30:8d:1b:4d:aa:6f:28:b2:64:2b:94:e6:23.
Are you sure you want to continue connecting (yes/no)? yes
/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.20.30's password: 

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'root@192.168.20.30'"
and check to make sure that only the key(s) you wanted were added.
查看远程主机上的公钥
第一台
[root@lpj2 ~]# cd /root/.ssh/
[root@lpj2 .ssh]# ls
authorized_keys
第二台
[root@lpj3 ~]# cd /root/.ssh/
[root@lpj3 .ssh]# ls
authorized_keys
[root@lpj3 .ssh]# 
回到ansible服务器上 远程连接客户端 看是否连接成功
[root@lpj1 .ssh]#  ssh root@192.168.20.20
Last login: Wed Jun 10 16:25:33 2020 from 192.168.20.1
[root@lpj2 ~]# exit
logout
Connection to 192.168.20.20 closed.
[root@lpj1 .ssh]#  ssh root@192.168.20.30
Last login: Wed Jun 10 15:57:21 2020 from 192.168.20.1
[root@lpj3 ~]# exit
logout
Connection to 192.168.20.30 closed.
[root@lpj1 .ssh]# 
  • 2.3、ansible常用模块如下:
-- 列出ansible所有的模块  ## -l 列出
[root@lpj1 ansible]#  ansible-doc -l 
a10_server                                Manage A10 Networks AX/SoftAX/Thu.
a10_server_axapi3                         Manage A10 Networks AX/SoftAX/Thu.
a10_service_group                         Manage A10 Networks AX/SoftAX/Thu.
a10_virtual_server                        Manage A10 Networks AX/SoftAX/Thu.
accelerate                                Enable accelerated mode on remote.
aci_aep                                   Manage attachable Access Entity P.
aci_ap                                    Manage top level Application Prof.
aci_bd                                    Manage Bridge Domains (BD) on Cis.
aci_bd_subnet                             Manage Subnets on Cisco ACI fabri.
aci_bd_to_l3out                           Bind Bridge Domain to L3 Out on C.
aci_config_rollback                       Provides rollback and rollback pr.
aci_config_snapshot                       Manage Config Snapshots on Cisco .
aci_contract                              Manage contract resources on Cisc.
aci_contract_subject                      Manage initial Contract Subjects .
aci_contract_subject_to_filter            Bind Contract Subjects to Filters.
aci_epg                                   Manage End Point Groups (EPG) on .
aci_epg_monitoring_policy                 Manage monitoring policies on Cis.
aci_epg_to_contract                       Bind EPGs to Contracts on Cisco A.
aci_epg_to_domain                         Bind EPGs to Domains on Cisco ACI.
: ##使用q退出      如果死机  终端关掉就可以了
-- 查看模块的帮助信息   ##-s 加载模块名
[root@lpj1 ansible]# ansible-doc -s ping
- name: Try to connect to host, verify a usable python and return `pong' on 
  ping:
      data:                  # Data to return for the `ping' return value. I
                               this parameter is
                               set to `crash',
                               the module will
                               cause an
                               exception.
ansible常用模块之 ping 测试主控端和远程主机是否能够连通   ssh
[root@lpj1 .ssh]# cd /etc/ansible/
[root@lpj1 ansible]# vim hosts ## 主机清单
[peng]  ##清单名称
192.168.20.20  ##远程主机的IP
192.168.20.30
[jie]
192.168.20.20
[root@lpj1 ansible]# ansible peng -m ping
192.168.20.20 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
192.168.20.30 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
[root@lpj1 ansible]# ansible jie -m ping
192.168.20.20 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
[root@lpj1 ansible]# ansible all -m ping ##all所有主机清单中的所有主机
192.168.20.30 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
192.168.20.20 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
[root@lpj1 ansible]# ansible 192.168.20.30 -m ping  ## 通过IP测试
192.168.20.30 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
ansible常用模块之 command : command 模块用于在远程主机上执行命令,
             ansible默认就是使用 command 模块。
             command 模块有一个缺点的缺陷是不能用特殊符号 例如| > >>
[root@lpj1 ansible]# ansible all -m command -a "ls /home"
192.168.20.30 | SUCCESS | rc=0 >>
peng

192.168.20.20 | SUCCESS | rc=0 >>
peng
## 参数 chdir   切换目录
## creates   当指定文件存在时,命令不执行  当指定文件不存在时,命令执行
##removes  当指定的文件存在时,命令执行   当指定文件不存在时  命令不执行
chdir演示如下 :
[root@lpj1 ansible]# ansible all -m command -a "chdir=/home ls"
192.168.20.20 | SUCCESS | rc=0 >>
peng
zs

192.168.20.30 | SUCCESS | rc=0 >>
ls
peng
creates演示如下 :	
[root@lpj1 ansible]# ansible all -m command -a "creates=/etc/fstab ls /home"  ##存在时
192.168.20.30 | SUCCESS | rc=0 >>
skipped, since /etc/fstab exists

192.168.20.20 | SUCCESS | rc=0 >>
skipped, since /etc/fstab exists
[root@lpj1 ansible]# ansible all -m command -a "creates=/etc/fstabbbbbb ls /home"  ##不存在时候
192.168.20.30 | SUCCESS | rc=0 >>
ls
peng

192.168.20.20 | SUCCESS | rc=0 >>
peng
zs
removes演示如下 :
[root@lpj1 ansible]# ansible all -m command -a "removes=/etc/fstab ls /home"    ##存在时
192.168.20.30 | SUCCESS | rc=0 >>
ls
peng

192.168.20.20 | SUCCESS | rc=0 >>
peng
zs
[root@lpj1 ansible]# ansible all -m command -a "removes=/etc/fstabdfsfsdf ls /home"  ## 不存在时
192.168.20.30 | SUCCESS | rc=0 >>
skipped, since /etc/fstabdfsfsdf does not exist

192.168.20.20 | SUCCESS | rc=0 >>
skipped, since /etc/fstabdfsfsdf does not exist
ansible常用的模块之 : shell:shell模块用于在受控主机上执行受控主机上的脚本,也可以直接在受控主机上执行命令,是万能模块   
[root@lpj1 ansible]#  ansible all -m shell -a "touch /home/aa"
 [WARNING]: Consider using file module with state=touch rather than running touch

192.168.20.20 | SUCCESS | rc=0 >>


192.168.20.30 | SUCCESS | rc=0 >>
[root@lpj1 ansible]# ansible all -m shell -a "ls /home | grep aa"
192.168.20.30 | SUCCESS | rc=0 >>
aa

192.168.20.20 | SUCCESS | rc=0 >>
aa
[root@lpj1 ansible]# ansible all -m shell -a "echo '123' > /home/aa "
192.168.20.20 | SUCCESS | rc=0 >>


192.168.20.30 | SUCCESS | rc=0 >>


[root@lpj1 ansible]# ansible all -m shell -a "cat /home/aa "
192.168.20.30 | SUCCESS | rc=0 >>
123

192.168.20.20 | SUCCESS | rc=0 >>
123
ansible常用模块之 user : 管理或者创建远程主机上的用户
    参数 :参数:  name  指定用户名  如果用户不存在  则创建该用户
[root@lpj1 ansible]# ansible all -m user -a "name=aa"  
192.168.20.20 | SUCCESS => {
    "changed": true, 
    "comment": "", 
    "createhome": true, 
    "group": 1002, 
    "home": "/home/aa", 
    "name": "aa", 
    "shell": "/bin/bash", 
    "state": "present", 
    "stderr": "useradd: warning: the home directory already exists.\nNot copying any file from skel directory into it.\n", 
    "stderr_lines": [
        "useradd: warning: the home directory already exists.", 
        "Not copying any file from skel directory into it."
    ], 
    "system": false, 
    "uid": 1002
}
192.168.20.30 | SUCCESS => {
    "changed": true, 
    "comment": "", 
    "createhome": true, 
    "group": 1002, 
    "home": "/home/aa", 
    "name": "aa", 
    "shell": "/bin/bash", 
    "state": "present", 
    "stderr": "useradd: warning: the home directory already exists.\nNot copying any file from skel directory into it.\n", 
    "stderr_lines": [
        "useradd: warning: the home directory already exists.", 
        "Not copying any file from skel directory into it."
    ], 
    "system": false, 
    "uid": 1002
}
[root@lpj1 ansible]# ansible all -m shell -a "tail -1 /etc/passwd"  ##password    给用户添加密码  修改密码   添加密码的时候只能识别加密后的字符
192.168.20.30 | SUCCESS | rc=0 >>
aa:x:1002:1002::/home/aa:/bin/bash

192.168.20.20 | SUCCESS | rc=0 >>
aa:x:1002:1002::/home/aa:/bin/bash
[root@lpj1 ansible]#  yum -y install openssl-devel
[root@lpj1 ansible]# openssl passwd -1 123.com
$1$xNp3AQv9$UnFy1fpdc0m4/TuUJsqmj/
[root@lpj1 ansible]# ansible all -m user -a 'name=aa   password=$1$xNp3AQv9$UnFy1fpdc0m4/TuUJsqmj/ '
192.168.20.20 | SUCCESS => {
    "append": false, 
    "changed": true, 
    "comment": "", 
    "group": 1002, 
    "home": "/home/aa", 
    "move_home": false, 
    "name": "aa", 
    "password": "NOT_LOGGING_PASSWORD", 
    "shell": "/bin/bash", 
    "state": "present", 
    "uid": 1002
}
192.168.20.30 | SUCCESS => {
    "append": false, 
    "changed": true, 
    "comment": "", 
    "group": 1002, 
    "home": "/home/aa", 
    "move_home": false, 
    "name": "aa", 
    "password": "NOT_LOGGING_PASSWORD", 
    "shell": "/bin/bash", 
    "state": "present", 
    "uid": 1002
} ## 这里要单引号 双引号不行
远程主机上进行验证
[peng@lpj2 ~]$ su aa
密码:123.com
bash: /home/aa/.bashrc: 不是目录
bash-4.2$ 
参数:
exit   返回到root用户
           uid  指定用户的uid 
           group   指定用户的基本组
           groups   指定用户的附加组
           append=yes   增量增加附加组   相当于把用户添加到另一个附加组中
           append=no    全量添加附加组    相当于只设置一个附加组
指定uid
[root@lpj1 ansible]# ansible all -m user -a "uid=1030 name=test"
192.168.20.30 | SUCCESS => {
    "changed": true, 
    "comment": "", 
    "createhome": true, 
    "group": 1030, 
    "home": "/home/test", 
    "name": "test", 
    "shell": "/bin/bash", 
    "state": "present", 
    "system": false, 
    "uid": 1030
}
192.168.20.20 | SUCCESS => {
    "changed": true, 
    "comment": "", 
    "createhome": true, 
    "group": 1030, 
    "home": "/home/test", 
    "name": "test", 
    "shell": "/bin/bash", 
    "state": "present", 
    "system": false, 
    "uid": 1030
}
[root@lpj1 ansible]# ansible all -m shell -a "tail -2 /etc/passwd"
192.168.20.30 | SUCCESS | rc=0 >>
aa:x:1002:1002::/home/aa:/bin/bash
test:x:1030:1030::/home/test:/bin/bash

192.168.20.20 | SUCCESS | rc=0 >>
aa:x:1002:1002::/home/aa:/bin/bash
test:x:1030:1030::/home/test:/bin/bash
指定用户的基本组
[root@lpj1 ansible]# ansible all -m user -a"name=test group=aa"
192.168.20.30 | SUCCESS => {
    "append": false, 
    "changed": true, 
    "comment": "", 
    "group": 1002, 
    "home": "/home/test", 
    "move_home": false, 
    "name": "test", 
    "shell": "/bin/bash", 
    "state": "present", 
    "uid": 1030
}
192.168.20.20 | SUCCESS => {
    "append": false, 
    "changed": true, 
    "comment": "", 
    "group": 1002, 
    "home": "/home/test", 
    "move_home": false, 
    "name": "test", 
    "shell": "/bin/bash", 
    "state": "present", 
    "uid": 1030
}
[root@lpj1 ansible]#  ansible all -m shell -a "tail -2 /etc/passwd"
192.168.20.30 | SUCCESS | rc=0 >>
aa:x:1002:1002::/home/aa:/bin/bash
test:x:1030:1002::/home/test:/bin/bash

192.168.20.20 | SUCCESS | rc=0 >>
aa:x:1002:1002::/home/aa:/bin/bash
test:x:1030:1002::/home/test:/bin/bash
附加组
[root@lpj1 ansible]# ansible all -m user -a "name=test groups=test"
192.168.20.20 | SUCCESS => {
    "append": false, 
    "changed": true, 
    "comment": "", 
    "group": 1002, 
    "groups": "test", 
    "home": "/home/test", 
    "move_home": false, 
    "name": "test", 
    "shell": "/bin/bash", 
    "state": "present", 
    "uid": 1030
}
192.168.20.30 | SUCCESS => {
    "append": false, 
    "changed": true, 
    "comment": "", 
    "group": 1002, 
    "groups": "test", 
    "home": "/home/test", 
    "move_home": false, 
    "name": "test", 
    "shell": "/bin/bash", 
    "state": "present", 
    "uid": 1030
}
[root@lpj1 ansible]# ansible all -m user -a "name=test groups=test"
192.168.20.20 | SUCCESS => {
    "append": false, 
    "changed": true, 
    "comment": "", 
    "group": 1002, 
    "groups": "test", 
    "home": "/home/test", 
    "move_home": false, 
    "name": "test", 
    "shell": "/bin/bash", 
    "state": "present", 
    "uid": 1030
}
192.168.20.30 | SUCCESS => {
    "append": false, 
    "changed": true, 
    "comment": "", 
    "group": 1002, 
    "groups": "test", 
    "home": "/home/test", 
    "move_home": false, 
    "name": "test", 
    "shell": "/bin/bash", 
    "state": "present", 
    "uid": 1030
}
[root@lpj1 ansible]#  ansible all -m shell -a "tail -2 /etc/group"
192.168.20.20 | SUCCESS | rc=0 >>
aa:x:1002:
test:x:1030:test
增量添加
[root@lpj1 ansible]# ansible all -m shell -a "groupadd one"
192.168.20.20 | SUCCESS | rc=0 >>


192.168.20.30 | SUCCESS | rc=0 >>
[root@lpj1 ansible]#  ansible all -m user -a "name=test groups=one append=yes"
192.168.20.20 | SUCCESS => {
    "append": true, 
    "changed": true, 
    "comment": "", 
    "group": 1002, 
    "groups": "one", 
    "home": "/home/test", 
    "move_home": false, 
    "name": "test", 
    "shell": "/bin/bash", 
    "state": "present", 
    "uid": 1030
}
192.168.20.30 | SUCCESS => {
    "append": true, 
    "changed": true, 
    "comment": "", 
    "group": 1002, 
    "groups": "one", 
    "home": "/home/test", 
    "move_home": false, 
    "name": "test", 
    "shell": "/bin/bash", 
    "state": "present", 
    "uid": 1030
}
[root@lpj1 ansible]# ansible all -m shell -a "tail -3 /etc/group"
192.168.20.20 | SUCCESS | rc=0 >>
aa:x:1002:
test:x:1030:test
one:x:1031:test

192.168.20.30 | SUCCESS | rc=0 >>
aa:x:1002:
test:x:1030:test
one:x:1031:test
全量添加
[root@lpj1 ansible]# ansible all -m user -a "name=test groups=one append=no"
192.168.20.20 | SUCCESS => {
    "append": false, 
    "changed": true, 
    "comment": "", 
    "group": 1002, 
    "groups": "one", 
    "home": "/home/test", 
    "move_home": false, 
    "name": "test", 
    "shell": "/bin/bash", 
    "state": "present", 
    "uid": 1030
}
192.168.20.30 | SUCCESS => {
    "append": false, 
    "changed": true, 
    "comment": "", 
    "group": 1002, 
    "groups": "one", 
    "home": "/home/test", 
    "move_home": false, 
    "name": "test", 
    "shell": "/bin/bash", 
    "state": "present", 
    "uid": 1030
}
[root@lpj1 ansible]#  ansible all -m shell -a "tail -3 /etc/group"
192.168.20.20 | SUCCESS | rc=0 >>
aa:x:1002:
test:x:1030:
one:x:1031:test

192.168.20.30 | SUCCESS | rc=0 >>
aa:x:1002:
test:x:1030:
one:x:1031:test
state=absent    删除用户   默认不删除家目录
remove=yes    删除用户的同时删除掉家目录
state=absent 演示如下
[root@lpj1 ansible]# ansible all -m user -a "name=test state=absent remove=yes"
192.168.20.20 | SUCCESS => {
    "changed": true, 
    "force": false, 
    "name": "test", 
    "remove": true, 
    "state": "absent", 
    "stderr": "userdel: group test not removed because it is not the primary group of user test.\n", 
    "stderr_lines": [
        "userdel: group test not removed because it is not the primary group of user test."
    ]
}
192.168.20.30 | SUCCESS => {
    "changed": true, 
    "force": false, 
    "name": "test", 
    "remove": true, 
    "state": "absent", 
    "stderr": "userdel: group test not removed because it is not the primary group of user test.\n", 
    "stderr_lines": [
        "userdel: group test not removed because it is not the primary group of user test."
    ]
}
[root@lpj1 ansible]#  ansible all -m shell -a "tail -1 /etc/passwd"
192.168.20.20 | SUCCESS | rc=0 >>
aa:x:1002:1002::/home/aa:/bin/bash

192.168.20.30 | SUCCESS | rc=0 >>
aa:x:1002:1002::/home/aa:/bin/bash
[root@lpj1 ansible]#  ansible all -m shell -a "ls /home"
192.168.20.30 | SUCCESS | rc=0 >>
aa
ls
peng

192.168.20.20 | SUCCESS | rc=0 >>
aa
peng
zs
-- ansible常用模块之group: 创建和管理远程主机上的组
	参数:
		name  指定组   如果不存在则创建
        gid    修改或者指定组的gid
       state=absent   删除指定的组
name:
[root@lpj1 ansible]# ansible all -m group -a "name=two"
192.168.20.30 | SUCCESS => {
    "changed": false, 
    "gid": 1032, 
    "name": "two", 
    "state": "present", 
    "system": false
}
192.168.20.20 | SUCCESS => {
    "changed": false, 
    "gid": 1032, 
    "name": "two", 
    "state": "present", 
    "system": false
}
[root@lpj1 ansible]#  ansible all -m shell -a "tail -1 /etc/group"
192.168.20.30 | SUCCESS | rc=0 >>
two:x:1032:

192.168.20.20 | SUCCESS | rc=0 >>
two:x:1032:
gid
[root@lpj1 ansible]# ansible all -m group -a "name=two gid=1050"
192.168.20.20 | SUCCESS => {
    "changed": true, 
    "gid": 1050, 
    "name": "two", 
    "state": "present", 
    "system": false
}
192.168.20.30 | SUCCESS => {
    "changed": true, 
    "gid": 1050, 
    "name": "two", 
    "state": "present", 
    "system": false
}
[root@lpj1 ansible]# ansible all -m shell -a "tail -1 /etc/group"
192.168.20.20 | SUCCESS | rc=0 >>
two:x:1050:

192.168.20.30 | SUCCESS | rc=0 >>
two:x:1050:
state=absent 
[root@lpj1 ansible]# ansible all -m group -a "name=two state=absent"
192.168.20.30 | SUCCESS => {
    "changed": true, 
    "name": "two", 
    "state": "absent"
}
192.168.20.20 | SUCCESS => {
    "changed": true, 
    "name": "two", 
    "state": "absent"
}
[root@lpj1 ansible]# ansible all -m shell -a "tail -1 /etc/group"
192.168.20.20 | SUCCESS | rc=0 >>
apache:x:48:

192.168.20.30 | SUCCESS | rc=0 >>
apache:x:48:
--ansible常用模块之.script : 在远程主机上执行主控端的脚本
	参数    chdir   切换目录  远程主机上的目录
            creates   文件存在   脚本不执行
            removes  文件存在   脚本执行
[root@lpj1 ansible]# vim test.sh
[root@lpj1 ansible]# cat test.sh 
#!/bin/bash
cd /usr
ls | grep src
creates:存在
[root@lpj1 ansible]# ansible all -m script -a "creates=/etc/fstab chdir=/root test.sh"
192.168.20.20 | SKIPPED
192.168.20.30 | SKIPPED
不存在:
[root@lpj1 ansible]# ansible all -m script -a "creates=/etc/fstabbbbb chdir=/root test.sh"
192.168.20.30 | SUCCESS => {
    "changed": true, 
    "rc": 0, 
    "stderr": "Shared connection to 192.168.20.30 closed.\r\n", 
    "stdout": "src\r\n", 
    "stdout_lines": [
        "src"
    ]
}
192.168.20.20 | SUCCESS => {
    "changed": true, 
    "rc": 0, 
    "stderr": "Shared connection to 192.168.20.20 closed.\r\n", 
    "stdout": "src\r\n", 
    "stdout_lines": [
        "src"
    ]
}
removes:存在
[root@lpj1 ansible]# ansible all -m script -a "removes=/etc/fstab chdir=/root test.sh"
192.168.20.20 | SUCCESS => {
    "changed": true, 
    "rc": 0, 
    "stderr": "Shared connection to 192.168.20.20 closed.\r\n", 
    "stdout": "src\r\n", 
    "stdout_lines": [
        "src"
    ]
}
192.168.20.30 | SUCCESS => {
    "changed": true, 
    "rc": 0, 
    "stderr": "Shared connection to 192.168.20.30 closed.\r\n", 
    "stdout": "src\r\n", 
    "stdout_lines": [
        "src"
    ]
}
不存在
[root@lpj1 ansible]# ansible all -m script -a "removes=/etc/fstabbbb chdir=/root test.sh"
192.168.20.20 | SKIPPED
192.168.20.30 | SKIPPED
--ansible常用模块之setup:查看远程主机上的信息   查看自带的变量
	参数  filter   过滤
[root@lpj1 ansible]# ansible all -m setup  (粘贴了其中一点)
                "rx_software", 
                "software"
            ], 
            "type": "ether"
        }, 
        "ansible_virtualization_role": "guest", 
        "ansible_virtualization_type": "VMware", 
        "gather_subset": [
            "all"
        ], 
        "module_setup": true
    }, 
    "changed": false
}
进行过滤
[root@lpj1 ansible]#  ansible all -m setup -a "filter=ansible_all_ipv4_addresses"   
192.168.20.20 | SUCCESS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "192.168.122.1", 
            "192.168.20.20"
        ]
    }, 
    "changed": false
}
192.168.20.30 | SUCCESS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "192.168.122.1", 
            "192.168.20.30"
        ]
    }, 
    "changed": false
}
--ansible常用模块之 copy模块:将主控端的文件复制到远程主机上,可以复制目录,但是目录当中必须有文件
参数    src   要复制文件的路径 (源文件)
            dest   将文件复制到目标主机的位置   
[root@lpj1 ansible]#  touch hehehe
[root@lpj1 ansible]# ansible all -m copy -a "src=/root/hehehe dest=/home"
[root@lpj1 ansible]# ansible all -m shell -a "ls /mnt"
192.168.20.20 | SUCCESS | rc=0 >>


192.168.20.30 | SUCCESS | rc=0 >>
content    将指定的内容写入到远程主机的文件中     会将原来的内容进行覆盖
[root@lpj1 ansible]#  ansible all -m copy  -a "content='11111\n22222' dest=/home/hehehe" 
192.168.20.20 | SUCCESS => {
    "changed": true, 
    "checksum": "7b6b1fce37f21601911579bd732fad05501edb46", 
    "dest": "/home/hehehe", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "97a3ddd80988315f10613a8dec79ec34", 
    "mode": "0644", 
    "owner": "root", 
    "secontext": "unconfined_u:object_r:user_home_dir_t:s0", 
    "size": 11, 
    "src": "/root/.ansible/tmp/ansible-tmp-1591862346.87-85101333503247/source", 
    "state": "file", 
    "uid": 0
}
192.168.20.30 | SUCCESS => {
    "changed": true, 
    "checksum": "7b6b1fce37f21601911579bd732fad05501edb46", 
    "dest": "/home/hehehe", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "97a3ddd80988315f10613a8dec79ec34", 
    "mode": "0644", 
    "owner": "root", 
    "secontext": "unconfined_u:object_r:user_home_dir_t:s0", 
    "size": 11, 
    "src": "/root/.ansible/tmp/ansible-tmp-1591862346.88-75036136590050/source", 
    "state": "file", 
    "uid": 0
}
[root@lpj1 ansible]# ansible all -m shell -a "cat /home/hehehe"
192.168.20.30 | SUCCESS | rc=0 >>
11111
22222

192.168.20.20 | SUCCESS | rc=0 >>
11111
22222
[root@lpj1 ansible]#  ansible all -m copy  -a "content='55555\n66666' dest=/home/hehehe"192.168.20.30 | SUCCESS => {
    "changed": true, 
    "checksum": "e66591a2bac048a079c0c0db1a65718cf2c2c226", 
    "dest": "/home/hehehe", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "d0ce73b19a9bdf7d94fbe1605e74339a", 
    "mode": "0644", 
    "owner": "root", 
    "secontext": "unconfined_u:object_r:user_home_dir_t:s0", 
    "size": 11, 
    "src": "/root/.ansible/tmp/ansible-tmp-1591862384.91-157847546279054/source", 
    "state": "file", 
    "uid": 0
}
192.168.20.20 | SUCCESS => {
    "changed": true, 
    "checksum": "e66591a2bac048a079c0c0db1a65718cf2c2c226", 
    "dest": "/home/hehehe", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "d0ce73b19a9bdf7d94fbe1605e74339a", 
    "mode": "0644", 
    "owner": "root", 
    "secontext": "unconfined_u:object_r:user_home_dir_t:s0", 
    "size": 11, 
    "src": "/root/.ansible/tmp/ansible-tmp-1591862384.9-201026476411221/source", 
    "state": "file", 
    "uid": 0
}
[root@lpj1 ansible]# ansible all -m shell -a "cat /home/hehehe"
192.168.20.20 | SUCCESS | rc=0 >>
55555
66666

192.168.20.30 | SUCCESS | rc=0 >>
55555
66666
copy   当没有任何参数的时候    当主控端拷贝的文件和远程主机上的文件名一致时 ,但是内容不一致,则会强制覆盖
 force=no   当主控端拷贝的文件和远程主机上的文件名一致时 ,但是内容不一致,则不会覆盖   会放弃拷贝
backup=yes     当主控端拷贝的文件和远程主机上的文件名一致时 ,但是内容不一致,会覆盖   但是会对远程主机的文件进行备份
[root@lpj1 ansible]#  echo 111111 > hehehe 
[root@lpj1 ansible]# ansible all -m copy -a "src=/root/hehehe dest=/home"
[root@lpj1 ansible]# ansible all -m shell -a "cat /home/hehehe"
192.168.20.20 | SUCCESS | rc=0 >>
55555
66666

192.168.20.30 | SUCCESS | rc=0 >>
55555
66666
[root@lpj1 ansible]# ansible all -m copy -a "src=/root/hehehe dest=/home backup=yes"
[root@lpj1 ansible]# ansible all -m shell -a "cat  /home/hehehe"
192.168.20.30 | SUCCESS | rc=0 >>
55555
66666

192.168.20.20 | SUCCESS | rc=0 >>
55555
66666
[root@lpj1 ansible]#  ansible all -m shell -a "ls /home"
192.168.20.30 | SUCCESS | rc=0 >>
aa
hehe
hehehe
ls
peng
rr

192.168.20.20 | SUCCESS | rc=0 >>
aa
hehe
hehehe
peng
rr
zs
[root@lpj1 ansible]# mkdir /aaa
[root@lpj1 ansible]#   ansible all -m copy -a "src=/aaa dest=/home/"
192.168.20.20 | SUCCESS => {
    "changed": false, 
    "dest": "/home/", 
    "src": "/aaa"
}
192.168.20.30 | SUCCESS => {
    "changed": false, 
    "dest": "/home/", 
    "src": "/aaa"
}
[root@lpj1 ansible]# ansible all -m shell -a "ls /home"
192.168.20.30 | SUCCESS | rc=0 >>
aa
hehe
hehehe
ls
peng
rr

192.168.20.20 | SUCCESS | rc=0 >>
aa
hehe
hehehe
peng
rr
zs
[root@lpj1 ansible]#  ansible all -m copy -a "src=/aaa dest=/home/"
192.168.20.30 | SUCCESS => {
    "changed": true, 
    "checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709", 
    "dest": "/home/aaa/rrr", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "d41d8cd98f00b204e9800998ecf8427e", 
    "mode": "0644", 
    "owner": "root", 
    "secontext": "unconfined_u:object_r:user_home_t:s0", 
    "size": 0, 
    "src": "/root/.ansible/tmp/ansible-tmp-1591862653.72-171925879046613/source", 
    "state": "file", 
    "uid": 0
}
192.168.20.20 | SUCCESS => {
    "changed": true, 
    "checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709", 
    "dest": "/home/aaa/rrr", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "d41d8cd98f00b204e9800998ecf8427e", 
    "mode": "0644", 
    "owner": "root", 
    "secontext": "unconfined_u:object_r:user_home_t:s0", 
    "size": 0, 
    "src": "/root/.ansible/tmp/ansible-tmp-1591862653.71-71362448129619/source", 
    "state": "file", 
    "uid": 0
}
[root@lpj1 ansible]# ansible all -m shell -a "ls /home"
192.168.20.20 | SUCCESS | rc=0 >>
aa
aaa
hehe
hehehe
peng
rr
zs

192.168.20.30 | SUCCESS | rc=0 >>
aa
aaa
hehe
hehehe
ls
peng
rr
owner:  指定文件的属主
group :指定文件的属组
mode:指定文件的权限
[root@lpj1 ansible]# ansible all -m user -a "name=rr"
192.168.20.20 | SUCCESS => {
    "append": false, 
    "changed": false, 
    "comment": "", 
    "group": 1003, 
    "home": "/home/rr", 
    "move_home": false, 
    "name": "rr", 
    "shell": "/bin/bash", 
    "state": "present", 
    "uid": 1003
}
192.168.20.30 | SUCCESS => {
    "append": false, 
    "changed": false, 
    "comment": "", 
    "group": 1003, 
    "home": "/home/rr", 
    "move_home": false, 
    "name": "rr", 
    "shell": "/bin/bash", 
    "state": "present", 
    "uid": 1003
}
[root@lpj1 ansible]#  touch cc
[root@lpj1 ansible]# ansible all -m copy -a "src=/root/cc dest=/"
[root@lpj1 ansible]#  ansible all -m shell -a "ls -l /cc"
192.168.20.20 | SUCCESS | rc=0 >>
-rw-r--r--. 1 root root 0 Jun 11 17:44 /cc

192.168.20.30 | SUCCESS | rc=0 >>
-rw-r--r--. 1 root root 0 Jun 11 09:44 /cc
[root@lpj1 ansible]# ansible all -m shell -a "ls -l /cc"
[root@lpj1 ansible]# ansible all -m copy -a "src=/root/cc dest=/ group=rr"
 [root@lpj1 ansible]# ansible all -m shell -a "ls -l /cc"
 [root@lpj1 ansible]# ansible all -m copy -a "src=/root/cc dest=/ mode=777"
  [root@lpj1 ansible]# ansible all -m shell -a "ls -l /cc"
  [root@lpj1 ansible]# ansible all -m copy -a "src=/root/cc dest=/ mode=7777"
  [root@lpj1 ansible]# ansible all -m shell -a "ls -l /cc"
  --ansible常用模块之yum:模块    在远程主机上使用yum安装软件   远程主机上要提前配置好yum
  	参数   name:软件名 
          state : installed   安装软件包
                         removed   卸载软件包    
 卸载:
 [root@lpj1 ansible]# ansible all -m yum -a "name=httpd state=removed"
192.168.20.30 | SUCCESS => {
    "changed": true, 
    "msg": "", 
    "rc": 0, 
    "results": [
        "Loaded plugins: fastestmirror, langpacks\nResolving Dependencies\n--> Running transaction check\n---> Package httpd.x86_64 0:2.4.6-90.el7.centos will be erased\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package        Arch            Version                       Repository   Size\n================================================================================\nRemoving:\n httpd          x86_64          2.4.6-90.el7.centos           @a          9.4 M\n\nTransaction Summary\n================================================================================\nRemove  1 Package\n\nInstalled size: 9.4 M\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n  Erasing    : httpd-2.4.6-90.el7.centos.x86_64                             1/1 \n  Verifying  : httpd-2.4.6-90.el7.centos.x86_64                             1/1 \n\nRemoved:\n  httpd.x86_64 0:2.4.6-90.el7.centos                                            \n\nComplete!\n"
    ]
}
  安装
  [root@lpj1 ansible]# ansible all -m yum -a "name=httpd state=installed"
192.168.20.30 | SUCCESS => {
    "changed": true, 
    "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-90.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-90.el7.centos            a          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-90.el7.centos.x86_64                             1/1 \n  Verifying  : httpd-2.4.6-90.el7.centos.x86_64                             1/1 \n\nInstalled:\n  httpd.x86_64 0:2.4.6-90.el7.centos                                            \n\nComplete!\n"
    ]
}
192.168.20.20 | SUCCESS => {
    "changed": true, 
    "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-90.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-90.el7.centos            a          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-90.el7.centos.x86_64                             1/1 \n  Verifying  : httpd-2.4.6-90.el7.centos.x86_64                             1/1 \n\nInstalled:\n  httpd.x86_64 0:2.4.6-90.el7.centos                                            \n\nComplete!\n"
    ]
}
--ansbile常用模块service模块    管理远程主机上的服务
 参数   name   服务名
           state    started 开启     stopped 关闭   restarted 重启  reloaded重新加载(开启服务的时候才能加载) enabled=yes   加入到开机自启当中
[root@lpj1 ansible]#   ansible all -m service  -a "name=httpd state=started"
[root@lpj1 ansible]# ansible all -m shell  -a "netstat -anput | grep httpd"
192.168.20.20 | SUCCESS | rc=0 >>
tcp6       0      0 :::80                   :::*                    LISTEN      13769/httpd         

192.168.20.30 | SUCCESS | rc=0 >>
tcp6       0      0 :::80                   :::*                    LISTEN      13662/httpd         
[root@lpj1 ansible]# ansible all -m service  -a "name=httpd state=stopped"
[root@lpj1 ansible]# ansible all -m shell  -a "netstat -anput | grep httpd"
192.168.20.20 | FAILED | rc=1 >>
non-zero return code

192.168.20.30 | FAILED | rc=1 >>
non-zero return code
[root@lpj1 ansible]#   ansible all -m service  -a "name=httpd state=restarted"
[root@lpj1 ansible]# ansible all -m service  -a "name=httpd state=reloaded"
[root@lpj1 ansible]# ansible all -m service  -a "name=httpd enabled=yes"
[root@lpj1 ansible]#  ansible all -m shell  -a "systemctl is-enabled httpd" 
192.168.20.20 | SUCCESS | rc=0 >>
enabled

192.168.20.30 | SUCCESS | rc=0 >>
enabled
ansible常用模块之 file  管理远程主机上的文件或者目录
参数    path指定路径  如果远程主机上没有该文件名   则创建
           state 创建的类型    touch文件    directory  目录   link软链接   hard硬链接 
           创建软硬链接  必须写绝对路径    src  远程主机上的源文件  path(dest)远程主机上的链接文件
[root@lpj1 ansible]# ansible all -m file -a "state=touch path=/usr/src/heihei"
192.168.20.30 | SUCCESS => {
    "changed": true, 
    "dest": "/usr/src/heihei", 
    "gid": 0, 
    "group": "root", 
    "mode": "0644", 
    "owner": "root", 
    "secontext": "unconfined_u:object_r:usr_t:s0", 
    "size": 0, 
    "state": "hard", 
    "uid": 0
}
192.168.20.20 | SUCCESS => {
    "changed": true, 
    "dest": "/usr/src/heihei", 
    "gid": 0, 
    "group": "root", 
    "mode": "0644", 
    "owner": "root", 
    "secontext": "unconfined_u:object_r:usr_t:s0", 
    "size": 0, 
    "state": "hard", 
    "uid": 0
}
[root@lpj1 ansible]# ansible all -m file -a "state=directory path=/usr/src/qq"
192.168.20.30 | SUCCESS => {
    "changed": false, 
    "gid": 0, 
    "group": "root", 
    "mode": "0755", 
    "owner": "root", 
    "path": "/usr/src/qq", 
    "secontext": "unconfined_u:object_r:usr_t:s0", 
    "size": 6, 
    "state": "directory", 
    "uid": 0
}
192.168.20.20 | SUCCESS => {
    "changed": false, 
    "gid": 0, 
    "group": "root", 
    "mode": "0755", 
    "owner": "root", 
    "path": "/usr/src/qq", 
    "secontext": "unconfined_u:object_r:usr_t:s0", 
    "size": 6, 
    "state": "directory", 
    "uid": 0
}
[root@lpj1 ansible]# ansible all -m file -a "state=link src=/usr/src/qq path=/usr/src/ee"
192.168.20.30 | SUCCESS => {
    "changed": false, 
    "dest": "/usr/src/ee", 
    "gid": 0, 
    "group": "root", 
    "mode": "0777", 
    "owner": "root", 
    "secontext": "unconfined_u:object_r:usr_t:s0", 
    "size": 11, 
    "src": "/usr/src/qq", 
    "state": "link", 
    "uid": 0
}
192.168.20.20 | SUCCESS => {
    "changed": false, 
    "dest": "/usr/src/ee", 
    "gid": 0, 
    "group": "root", 
    "mode": "0777", 
    "owner": "root", 
    "secontext": "unconfined_u:object_r:usr_t:s0", 
    "size": 11, 
    "src": "/usr/src/qq", 
    "state": "link", 
    "uid": 0
}
[root@lpj1 ansible]#  ansible all -m file -a "state=hard src=/usr/src/heihei path=/usr/src/ttt"
192.168.20.20 | SUCCESS => {
    "changed": false, 
    "dest": "/usr/src/ttt", 
    "gid": 0, 
    "group": "root", 
    "mode": "0644", 
    "owner": "root", 
    "secontext": "unconfined_u:object_r:usr_t:s0", 
    "size": 0, 
    "src": "/usr/src/heihei", 
    "state": "hard", 
    "uid": 0
}
192.168.20.30 | SUCCESS => {
    "changed": false, 
    "dest": "/usr/src/ttt", 
    "gid": 0, 
    "group": "root", 
    "mode": "0644", 
    "owner": "root", 
    "secontext": "unconfined_u:object_r:usr_t:s0", 
    "size": 0, 
    "src": "/usr/src/heihei", 
    "state": "hard", 
    "uid": 0
}
 owner   修改或指定属主
        group   修改或指定属组
        mode    修改或指定权限
[root@lpj1 ansible]# ansible all -m file -a "path=/yyy state=touch mode=777 owner=rr group=rr"
192.168.20.20 | SUCCESS => {
    "changed": true, 
    "dest": "/yyy", 
    "gid": 1003, 
    "group": "rr", 
    "mode": "0777", 
    "owner": "rr", 
    "secontext": "unconfined_u:object_r:etc_runtime_t:s0", 
    "size": 0, 
    "state": "file", 
    "uid": 1003
}
192.168.20.30 | SUCCESS => {
    "changed": true, 
    "dest": "/yyy", 
    "gid": 1003, 
    "group": "rr", 
    "mode": "0777", 
    "owner": "rr", 
    "secontext": "unconfined_u:object_r:etc_runtime_t:s0", 
    "size": 0, 
    "state": "file", 
    "uid": 1003
}
[root@lpj1 ansible]# ansible all -m shell  -a "ls -l /yyy"
192.168.20.20 | SUCCESS | rc=0 >>
-rwxrwxrwx. 1 rr rr 0 Jun 11 21:32 /yyy

192.168.20.30 | SUCCESS | rc=0 >>
-rwxrwxrwx. 1 rr rr 0 Jun 11 16:18 /yyy
[root@lpj1 ansible]# ansible all -m file -a "path=/yyy  mode=755"
192.168.20.20 | SUCCESS => {
    "changed": true, 
    "gid": 1003, 
    "group": "rr", 
    "mode": "0755", 
    "owner": "rr", 
    "path": "/yyy", 
    "secontext": "unconfined_u:object_r:etc_runtime_t:s0", 
    "size": 0, 
    "state": "file", 
    "uid": 1003
}
192.168.20.30 | SUCCESS => {
    "changed": true, 
    "gid": 1003, 
    "group": "rr", 
    "mode": "0755", 
    "owner": "rr", 
    "path": "/yyy", 
    "secontext": "unconfined_u:object_r:etc_runtime_t:s0", 
    "size": 0, 
    "state": "file", 
    "uid": 1003
}
[root@lpj1 ansible]#  ansible all -m shell  -a "ls -l /yyy"
192.168.20.30 | SUCCESS | rc=0 >>
-rwxr-xr-x. 1 rr rr 0 Jun 11 16:18 /yyy

192.168.20.20 | SUCCESS | rc=0 >>
-rwxr-xr-x. 1 rr rr 0 Jun 11 21:32 /yyy
[root@lpj1 ansible]#   ansible all -m file -a "path=/yyy  owner=root"
192.168.20.30 | SUCCESS => {
    "changed": true, 
    "gid": 1003, 
    "group": "rr", 
    "mode": "0755", 
    "owner": "root", 
    "path": "/yyy", 
    "secontext": "unconfined_u:object_r:etc_runtime_t:s0", 
    "size": 0, 
    "state": "file", 
    "uid": 0
}
192.168.20.20 | SUCCESS => {
    "changed": true, 
    "gid": 1003, 
    "group": "rr", 
    "mode": "0755", 
    "owner": "root", 
    "path": "/yyy", 
    "secontext": "unconfined_u:object_r:etc_runtime_t:s0", 
    "size": 0, 
    "state": "file", 
    "uid": 0
}
[root@lpj1 ansible]# ansible all -m shell  -a "ls -l /yyy"
192.168.20.30 | SUCCESS | rc=0 >>
-rwxr-xr-x. 1 root rr 0 Jun 11 16:18 /yyy

192.168.20.20 | SUCCESS | rc=0 >>
-rwxr-xr-x. 1 root rr 0 Jun 11 21:32 /yyy
[root@lpj1 ansible]# ansible all -m file -a "path=/yyy  mode=7777"
192.168.20.20 | SUCCESS => {
    "changed": true, 
    "gid": 1003, 
    "group": "rr", 
    "mode": "07777", 
    "owner": "root", 
    "path": "/yyy", 
    "secontext": "unconfined_u:object_r:etc_runtime_t:s0", 
    "size": 0, 
    "state": "file", 
    "uid": 0
}
192.168.20.30 | SUCCESS => {
    "changed": true, 
    "gid": 1003, 
    "group": "rr", 
    "mode": "07777", 
    "owner": "root", 
    "path": "/yyy", 
    "secontext": "unconfined_u:object_r:etc_runtime_t:s0", 
    "size": 0, 
    "state": "file", 
    "uid": 0
}
[root@lpj1 ansible]#   ansible all -m shell  -a "ls -l /yyy"
192.168.20.30 | SUCCESS | rc=0 >>
-rwsrwsrwt. 1 root rr 0 Jun 11 16:18 /yyy

192.168.20.20 | SUCCESS | rc=0 >>
-rwsrwsrwt. 1 root rr 0 Jun 11 21:32 /yyy
删除文件或目录 
state=absent
[root@lpj1 ansible]#  ansible all -m file -a "path=/yyy state=absent"
192.168.20.20 | SUCCESS => {
    "changed": true, 
    "path": "/yyy", 
    "state": "absent"
}
192.168.20.30 | SUCCESS => {
    "changed": true, 
    "path": "/yyy", 
    "state": "absent"
}
-- ansible常用模块之cron  在远程主机上添加计划任务
	参数
minute   分钟
hour   小时
day  天
mouth   月
weekday   周
job   执行的命令
name   对计划任务的命名
special_time=hourly  每小时
10   8   *  *   *    echo  xixi
[root@lpj1 ansible]# ansible all -m cron -a "name=one hour=8 minute=10 job='echo xixi'"
192.168.20.30 | SUCCESS => {
    "changed": true, 
    "envs": [], 
    "jobs": [
        "one"
    ]
}
192.168.20.20 | SUCCESS => {
    "changed": true, 
    "envs": [], 
    "jobs": [
        "one"
    ]
}
[root@lpj1 ansible]#  ansible all -m cron -a "name=one hour=8 minute=10 job='echo xixi'"
192.168.20.30 | SUCCESS => {
    "changed": false, 
    "envs": [], 
    "jobs": [
        "one"
    ]
}
192.168.20.20 | SUCCESS => {
    "changed": false, 
    "envs": [], 
    "jobs": [
        "one"
    ]
}
root@lpj1 ansible]#  ansible all -m shell  -a "crontab -l"
192.168.20.20 | SUCCESS | rc=0 >>
#Ansible: one
10 8 * * * echo xixi

192.168.20.30 | SUCCESS | rc=0 >>
#Ansible: one
10 8 * * * echo xixi
[root@lpj1 ansible]#  ansible all -m shell -a "crontab -r"
192.168.20.20 | SUCCESS | rc=0 >>


192.168.20.30 | SUCCESS | rc=0 >>
ansible常用模块之lineinfile     用来给文件中添加内容  或者修改文件中的内容
	参数:regexp  正则匹配  ^……    ……$
line   将匹配的内容进行替换
line  单独使用   是在文件的最后添加内容
[root@lpj1 ansible]# ansible all -m file -a "name=/oo state=touch"
192.168.20.20 | SUCCESS => {
    "changed": true, 
    "dest": "/oo", 
    "gid": 0, 
    "group": "root", 
    "mode": "0644", 
    "owner": "root", 
    "secontext": "unconfined_u:object_r:etc_runtime_t:s0", 
    "size": 18, 
    "state": "file", 
    "uid": 0
}
192.168.20.30 | SUCCESS => {
    "changed": true, 
    "dest": "/oo", 
    "gid": 0, 
    "group": "root", 
    "mode": "0644", 
    "owner": "root", 
    "secontext": "unconfined_u:object_r:etc_runtime_t:s0", 
    "size": 18, 
    "state": "file", 
    "uid": 0
}
[root@lpj1 ansible]#  ansible all -m shell -a "echo -e '111111\n222222\n33333' > /oo"
192.168.20.20 | SUCCESS | rc=0 >>


192.168.20.30 | SUCCESS | rc=0 >>
[root@lpj1 ansible]# ansible all -m shell -a "cat /oo"
192.168.20.30 | SUCCESS | rc=0 >>
111111
222222
33333

192.168.20.20 | SUCCESS | rc=0 >>
111111
222222
33333
[root@lpj1 ansible]#  ansible all -m lineinfile -a "line='44444' path=/oo"
192.168.20.20 | SUCCESS => {
    "backup": "", 
    "changed": true, 
    "msg": "line added"
}
192.168.20.30 | SUCCESS => {
    "backup": "", 
    "changed": true, 
    "msg": "line added"
}
[root@lpj1 ansible]#  ansible all -m shell -a "cat /oo"
192.168.20.20 | SUCCESS | rc=0 >>
111111
222222
33333
44444

192.168.20.30 | SUCCESS | rc=0 >>
111111
222222
33333
44444
[root@lpj1 ansible]# ansible all -m lineinfile -a "regexp="^2" line='5555' path=/oo"
192.168.20.30 | SUCCESS => {
    "backup": "", 
    "changed": true, 
    "msg": "line replaced"
}
192.168.20.20 | SUCCESS => {
    "backup": "", 
    "changed": true, 
    "msg": "line replaced"
}
[root@lpj1 ansible]# ansible all -m shell -a "cat /oo"
192.168.20.20 | SUCCESS | rc=0 >>
111111
5555
33333
44444

192.168.20.30 | SUCCESS | rc=0 >>
111111
5555
33333
44444
insertbefore   在匹配行的前面添加内容
insertafter   在匹配行的之后添加
[root@lpj1 ansible]#   ansible all -m lineinfile -a "insertbefore='^4' line='22222' path=/oo" 
192.168.20.30 | SUCCESS => {
    "backup": "", 
    "changed": true, 
    "msg": "line added"
}
192.168.20.20 | SUCCESS => {
    "backup": "", 
    "changed": true, 
    "msg": "line added"
}
[root@lpj1 ansible]# ansible all -m shell -a "cat /oo"
192.168.20.30 | SUCCESS | rc=0 >>
111111
5555
33333
22222
44444

192.168.20.20 | SUCCESS | rc=0 >>
111111
5555
33333
22222
44444
[root@lpj1 ansible]# ansible all -m lineinfile -a "insertafter='^5' line='33333' path=/oo"
192.168.20.20 | SUCCESS => {
    "backup": "", 
    "changed": false, 
    "msg": ""
}
192.168.20.30 | SUCCESS => {
    "backup": "", 
    "changed": false, 
    "msg": ""
}
[root@lpj1 ansible]#  ansible all -m shell -a "cat /oo"
192.168.20.20 | SUCCESS | rc=0 >>
111111
5555
33333
22222
44444

192.168.20.30 | SUCCESS | rc=0 >>
111111
5555
33333
22222
44444
playbook   剧本
playbook   是由多个模块组成的
yaml语言编写的   集合性语言   c语言   python   ruby   perl
后缀   .yaml   .yml
语法格式
---  代表yaml文件
区分大小写
层级是通过缩进   使用空格
#注释
数据类型
集合
列表 
字符串
数据
对象
yaml语言编写的playbook剧本中  特殊字符的含义
tasks  任务
handlers   触发器
variables   变量

ansible的变量
1.本身就有很多的变量   这些变量是可以直接使用的
setup  查看远程主机上的信息   查看自带的变量
参数  filter   过滤
[root@localhost ~]# ansible all -m setup
[root@localhost ~]# ansible all -m setup -a "filter=ansible_all_ipv4_addresses"         
2.可以通过命令来设置变量   -e
---   #代表yaml文件
    - hosts: peng    #主机清单
      remote_user: root   #用户
      tasks:   #任务
        - name: touch file     #命名
          shell: echo {{ var }} > haha    #创建文件
[root@lpj1 ansible]# ansible-playbook -e "var=haha" test.yaml 

PLAY [peng] **************************************************************************

TASK [Gathering Facts] ***************************************************************
ok: [192.168.20.20]
ok: [192.168.20.30]

TASK [touch file] ********************************************************************
changed: [192.168.20.20]
changed: [192.168.20.30]

PLAY RECAP ***************************************************************************
192.168.20.20              : ok=2    changed=1    unreachable=0    failed=0   
192.168.20.30              : ok=2    changed=1    unreachable=0    failed=0   
[root@lpj1 ansible]# ansible all -m shell -a "cat haha"
192.168.20.30 | SUCCESS | rc=0 >>
haha

192.168.20.20 | SUCCESS | rc=0 >>
haha
3.可以直接将变量写到剧本当中
[root@lpj1 ansible]# vim test.yaml
---
    - hosts:peng
      remote_user: root
      vars:
          var: hehe
      tasks:
        - name: touch file
          shell: echo {{ var }} > haha
[root@lpj1 ansible]# ansible-playbook test.yaml 

PLAY [peng] **************************************************************************

TASK [Gathering Facts] ***************************************************************
ok: [192.168.20.30]
ok: [192.168.20.20]

TASK [touch file] ********************************************************************
changed: [192.168.20.20]
changed: [192.168.20.30]

PLAY RECAP ***************************************************************************
192.168.20.20              : ok=2    changed=1    unreachable=0    failed=0   
192.168.20.30              : ok=2    changed=1    unreachable=0    failed=0   
  [root@lpj1 ansible]# ansible all -m shell -a "cat haha"
192.168.20.20 | SUCCESS | rc=0 >>
hehe

192.168.20.30 | SUCCESS | rc=0 >>
hehe

[root@lpj1 ansible]# 
        




                            

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值