当前位置: 首页 > news >正文

ansible从入门到放弃

ansible简单入门

ansible的安装

由于ansible所在的源为epel源,所以需要先配置epel

[root@localhost ~]# vi /etc/yum.repos.d/bp.repo
[epel]
name=epel
baseurl=https://mirrors.aliyun.com/epel/7/x86_64/
gpgcheck=0
~              

配置完毕后使用yum安装

[root@localhost ~]# yum install ansible -y

ansible的相关配置文件

配置文件

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

程序

/usr/bin/ansible                #主程序,临时命令执行工具
/usr/bin/ansible-doc            #查看配置文档,模块功能查看工具
/usr/bin/ansible-galaxy         #下载/上传优秀代码或Roles模块的官网平台
/usr/bin/ansible-playbook       #定制自动化任务,编排剧本工具/usr/bin/ansiblepull 远程执行命令的工具
/usr/bin/ansible-vault          #文件加密工具
/usr/bin/ansible-console        #基于Console界面与用户交互的执行工具

配置文件ansible.cfg

[defaults]
#inventory      = /etc/ansible/hosts                        #主机列表配置文件
#library        = /usr/share/my_modules/                    #库文件存放目录
#remote_tmp     = ~/.ansible/tmp                            #临时py命令文件存放在远程主机目录
#local_tmp      = ~/.ansible/tmp                            #本机的临时命令执行目录
#forks          = 5                                         #默认的并发数
#sudo_user      = root                                      #默认sudo用户
#ask_sudo_pass = True                                       
#ask_pass      = True                                       #每次执行ansible命令是否询问ssh密码
#remote_port    = 22                                        #目标主机端口默认22
#host_key_checking = False                                  #检查对应服务器的host_key
#log_path = /var/log/ansible.log                            #日志文件
#module_name = command                                      #默认使用模块

以上为ansible的配置文件,一般保持默认无需改变
但建议将以下配置做修改(以下所有案例都基于这3项被修改的情况)

host_key_checking = False                           #此行注释去除,否则每次将检查主机的host_key
log_path = /var/log/ansible.log                     #将日志文件打开,方便查看操作日志
module_name = shell                                 #将默认的模块改为shell,command模块功能太弱

inventory主机清单

ansible的主要功能在于批量主机操作,为了便捷地使用其中的部分主机,可以在inventroy file中将棋分组命名
ansible中默认的inventory file为/etc/ansible/hosts
inventory file可以手动生成,也可以动态生成

主机清单的格式

inventry文件遵循INI文件风格
例:

[websever]                      #中括号中的字符为组名
192.168.73.134
192.168.73.135:9527             #如果目标主机使用了非标的ssh端口可以在主机名后跟上端口号
[appsever]                      #
192.168.73.134                  #同一主机可以归类至不同的组中。
192.168.73.[01:10]              #如果主机名遵循相似的命名模式,还可以使用列表的方式来标识各主机

ansible的基本使用

在ansible使用之前需要先配置好主机文件
配置主机文件

[root@ansible ~]# vim /etc/ansible/hosts 
[webserver]
192.168.73.134
192.168.73.135

[appserver]
192.168.73.135

主机配置完毕,开始执行管理命令

ansible的用法

ansible通过ssh实现配置管理、应用部署、任务执行等功能。
语法:

ansible <host-patten> [-m module_name] [-a args]
选项说明
--version显示版本
-m module指定模块,默认为command,可以通过修改配置文件进行修改
-v显示详细过程 -vv -vvv可以显示更加详细的内容
--list-hosts显示主机列表,可以缩写--list
-k提示输入ssh连接密码,默认KEY验证
-C检查不执行
-T,--timeout=TIMEOUT执行命令的超时时长
-u,--user=REMOTE_USER指定远程执行的用户
-b,--become代替旧版的sudo其替换
--become-user=USERNAME指定sudo的runas用户,默认为root
-K,--ask-become-pass提示输入sudo时的口令

ansible模块

ping模块

ping 用来测试主机的连通性
使用ansible-doc命令可以查看模块用法,使用-s可以简单的查看简单相关用法

[root@ansible ~]# ansible-doc -s ping
- name: Try to connect to host, verify a usable python and return `pong' on success
  ping:
      data:                  # Data to return for the `ping' return value. If this
                               parameter is set to `crash',
                               the module will cause an
                               exception.

测试1:
使用ping模块进行测试时报错,提示错误,因为默认为key连接由于没有配置key所以报错

[root@ansible ~]# ansible 192.168.73.134 -m ping
192.168.73.134 | UNREACHABLE! => {
    "changed": false, 
    "msg": "Failed to connect to the host via ssh: Permission denied (publickey,password).", 
    "unreachable": true
}

测试2:
带上-k选项后

[root@ansible ~]# ansible 192.168.73.134 -m ping -k
SSH password: 
192.168.73.134 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}

测试3:
使用组名,由于此处只给与一次输入密码,所以要确保被管理的两台主机必须要密码相同

[root@ansible ~]# ansible webserver -m ping -k
SSH password: 
192.168.73.134 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
192.168.73.135 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}

测试4:
指定由哪个用户执行操作

[root@ansible ~]# ansible webserver -m ping -u masuri -k
SSH password: 
192.168.73.135 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
192.168.73.134 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}

测试5:
使用-b让普通用户用sudo的方法进行操作,如果没有授予sudo的权限,会失败

[root@ansible ~]# ansible webserver -m ping -u masuri -k -b
SSH password: 
192.168.73.134 | FAILED! => {
    "changed": false, 
    "module_stderr": "Shared connection to 192.168.73.134 closed.\r\n", 
    "module_stdout": "sudo: a password is required\r\n", 
    "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", 
    "rc": 1
}
192.168.73.135 | FAILED! => {
    "changed": false, 
    "module_stderr": "Shared connection to 192.168.73.135 closed.\r\n", 
    "module_stdout": "sudo: a password is required\r\n", 
    "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", 
    "rc": 1
}

测试6:
分别授予sudo权限后再次测试,此次带上-K选项,表示输入sudo口令执行命令,若要不输入口令,可以在sudo的配置文件中使用NOPASSWD选项。(一般不常用)

[root@ansible ~]# ansible webserver -m ping -u masuri -k -b -K
SSH password: 
SUDO password[defaults to SSH password]: 
192.168.73.135 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
192.168.73.134 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}

以上为基于密钥的验证方法,ansible真正在生产环境中使用时还是需要基于key的验证方法
基于key的验证方法
在ansible主机上创建私钥文件

[root@ansible ~]# ssh-keygen -t rsa -P "" -f .ssh/id_rsa
Generating public/private rsa key pair.
Your identification has been saved in .ssh/id_rsa.
Your public key has been saved in .ssh/id_rsa.pub.
The key fingerprint is:
SHA256:UAFYDd5EBqFIyC81+UYk9DZ3lRDZ3XUkr4K/FetFu+c root@ansible
The key's randomart image is:
+---[RSA 2048]----+
|..ooo+*B*+=.o o.=|
|.o =++ =...o . +.|
|  + =+o...      .|
| . ..oo..  .   . |
|  . .   S . . o .|
|           . . +.|
|            . o..|
|             + .o|
|            . .oE|
+----[SHA256]-----+

将公钥复制到被管理的主机

[root@ansible ~]# ssh-copy-id 192.168.73.134
/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.73.134's password: 

Number of key(s) added: 1

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

[root@ansible ~]# ssh-copy-id 192.168.73.135
/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.73.135's password: 

Number of key(s) added: 1

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

测试7:
此时再使用ping模块时不再需要带任何参数

[root@ansible ~]# ansible webserver -m ping 
192.168.73.134 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
192.168.73.135 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}

shell模块

shell模块用于执行shell命令
查看

[root@ansible ~]# ansible-doc -s shell
- name: Execute commands in nodes.
  shell:
      chdir:                 # cd into this directory before running the command
      creates:               # a filename, when it already exists, this step will *not* be
                               run.
      executable:            # change the shell used to execute the command. Should be an
                               absolute path to the
                               executable.
      free_form:             # (required) The shell module takes a free form command to
                               run, as a string.  There's
                               not an actual option named
                               "free form".  See the
                               examples!
      removes:               # a filename, when it does not exist, this step will *not* be
                               run.
      stdin:                 # Set the stdin of the command directly to the specified
                               value.
      warn:                  # if command warnings are on in ansible.cfg, do not warn about
                               this particular line if set
                               to no/false.

示例1:
使用shell来修改用户口令

[root@ansible ~]# ansible webserver -m shell -a 'echo 123456 | passwd --stdin masuri'
192.168.73.134 | CHANGED | rc=0 >>
Changing password for user masuri.
passwd: all authentication tokens updated successfully.

192.168.73.135 | CHANGED | rc=0 >>
Changing password for user masuri.
passwd: all authentication tokens updated successfully.

示例2:
在shell模块中使用变量时参数需要使用单引号,若使用双引号则变量指向的是本机的值

#单引号效果
[root@ansible ~]# ansible webserver -m shell -a 'echo $HOSTNAME'
192.168.73.134 | CHANGED | rc=0 >>
web1

192.168.73.135 | CHANGED | rc=0 >>
web2
#双引号的效果
[root@ansible ~]# ansible webserver -m shell -a "echo $HOSTNAME"
192.168.73.135 | CHANGED | rc=0 >>
ansible

192.168.73.134 | CHANGED | rc=0 >>
ansible

示例3:
使用shell重定向

[root@ansible ~]# ansible webserver -m shell -a 'chdir=/data echo welcome to magedu > test.log'
192.168.73.135 | CHANGED | rc=0 >>

192.168.73.134 | CHANGED | rc=0 >>

#查看重定向是否成功
[root@ansible ~]# ansible webserver -m shell -a 'chdir=/data cat test.log'
192.168.73.135 | CHANGED | rc=0 >>
welcome to magedu

192.168.73.134 | CHANGED | rc=0 >>
welcome to magedu

示例4:
使用sed对文件进行修改

[root@ansible ~]# ansible webserver -m shell -a 'sed -i "s/welcome to magedu/welcome to mylinuxops/" /data/test.log'
 [WARNING]: Consider using the replace, lineinfile or template module rather than running
'sed'.  If you need to use command because replace, lineinfile or template 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.73.134 | CHANGED | rc=0 >>

192.168.73.135 | CHANGED | rc=0 >>

#验证是否修改
[root@ansible ~]# ansible webserver -m shell -a 'cat /data/test.log'
192.168.73.134 | CHANGED | rc=0 >>
welcome to mylinuxops

192.168.73.135 | CHANGED | rc=0 >>
welcome to mylinuxops

script模块

script 模块是在远程主机上运行ansible服务器上的脚本
示例1:

[root@ansible ~]# vim hello.sh      #构建出一个简单的脚本
#!/bin/bash
echo "hello world"
[root@ansible ~]# chmod +x hello.sh
[root@ansible ~]# ansible webserver -m script -a '/root/hello.sh'
192.168.73.134 | CHANGED => {
    "changed": true, 
    "rc": 0, 
    "stderr": "Shared connection to 192.168.73.134 closed.\r\n", 
    "stderr_lines": [
        "Shared connection to 192.168.73.134 closed."
    ], 
    "stdout": "hello world\r\n", 
    "stdout_lines": [
        "hello world"
    ]
}
192.168.73.135 | CHANGED => {
    "changed": true, 
    "rc": 0, 
    "stderr": "Shared connection to 192.168.73.135 closed.\r\n", 
    "stderr_lines": [
        "Shared connection to 192.168.73.135 closed."
    ], 
    "stdout": "hello world\r\n", 
    "stdout_lines": [
        "hello world"
    ]
}

copy模块

copy 从主控端复制文件到远程主机

参数说明
src本机的源文件位置
dest目标主机存放文件位置
owner修改属主
group修改属组
mode修改权限
backup备份,copy时文件若是存在会直接覆盖
content指定生成文件的内容

示例1:
复制本机文件到远程主机,并修改属主,修改权限,

[root@ansible ~]# ansible webserver -m copy -a 'src=/etc/fstab dest=/data/fstab2 owner=masuri mode=666 backup=yes'
192.168.73.134 | CHANGED => {
    "changed": true, 
    "checksum": "e18dfdc22b5e67945358018dfcca8f1c8b25722c", 
    "dest": "/data/fstab2", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "4c98128827229df5554dee614d84d607", 
    "mode": "0666", 
    "owner": "masuri", 
    "size": 595, 
    "src": "/root/.ansible/tmp/ansible-tmp-1556157419.7-268980429666588/source", 
    "state": "file", 
    "uid": 1000
}
192.168.73.135 | CHANGED => {
    "changed": true, 
    "checksum": "e18dfdc22b5e67945358018dfcca8f1c8b25722c", 
    "dest": "/data/fstab2", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "4c98128827229df5554dee614d84d607", 
    "mode": "0666", 
    "owner": "masuri", 
    "size": 595, 
    "src": "/root/.ansible/tmp/ansible-tmp-1556157419.7-28176178316202/source", 
    "state": "file", 
    "uid": 1000
}

示例2:
使用content直接生成文件

[root@ansible ~]# ansible webserver -m copy -a 'content="hello word\nwelcome to mylinuxops\n" dest=/data/test1'
192.168.73.134 | CHANGED => {
    "changed": true, 
    "checksum": "89b51930dc2793a1ea796637d25b982d1c93aa90", 
    "dest": "/data/test1", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "b16c04a75e320a9862568401301b6b02", 
    "mode": "0644", 
    "owner": "root", 
    "size": 33, 
    "src": "/root/.ansible/tmp/ansible-tmp-1556158261.88-98867568897388/source", 
    "state": "file", 
    "uid": 0
}
192.168.73.135 | CHANGED => {
    "changed": true, 
    "checksum": "89b51930dc2793a1ea796637d25b982d1c93aa90", 
    "dest": "/data/test1", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "b16c04a75e320a9862568401301b6b02", 
    "mode": "0644", 
    "owner": "root", 
    "size": 33, 
    "src": "/root/.ansible/tmp/ansible-tmp-1556158261.89-218330298518724/source", 
    "state": "file", 
    "uid": 0
}

#验证
[root@ansible ~]# ansible webserver -a 'cat /data/test1'
192.168.73.135 | CHANGED | rc=0 >>
hello word
welcome to mylinuxops

192.168.73.134 | CHANGED | rc=0 >>
hello word
welcome to mylinuxops

fetch模块

fetch 从远程主机提取文件至主控端,只能提取文件,若要提取目录可以将目录先打包

参数说明
dest在主控端存放文件的位置
src远程主机所要提取的文件

示例1:
将远程主机的/etc/fstab,抓取至本地的/data

[root@ansible ~]# ansible webserver -m fetch -a 'dest=/data src=/etc/fstab'
192.168.73.135 | CHANGED => {
    "changed": true, 
    "checksum": "e18dfdc22b5e67945358018dfcca8f1c8b25722c", 
    "dest": "/data/192.168.73.135/etc/fstab", 
    "md5sum": "4c98128827229df5554dee614d84d607", 
    "remote_checksum": "e18dfdc22b5e67945358018dfcca8f1c8b25722c", 
    "remote_md5sum": null
}
192.168.73.134 | CHANGED => {
    "changed": true, 
    "checksum": "e18dfdc22b5e67945358018dfcca8f1c8b25722c", 
    "dest": "/data/192.168.73.134/etc/fstab", 
    "md5sum": "4c98128827229df5554dee614d84d607", 
    "remote_checksum": "e18dfdc22b5e67945358018dfcca8f1c8b25722c", 
    "remote_md5sum": null
}

示例2:
将远程/etc/目录抓取至本地的/data

#抓取目录分两步走,先打包
[root@ansible ~]# ansible webserver -a 'tar Jcf /data/etc.tar.xz /etc'
 [WARNING]: Consider using the unarchive module rather than running 'tar'.  If you need to
use command because unarchive 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.73.135 | CHANGED | rc=0 >>
tar: Removing leading `/' from member names

192.168.73.134 | CHANGED | rc=0 >>
tar: Removing leading `/' from member names

#提取打包文件
[root@ansible ~]# ansible webserver -m fetch -a 'dest=/data  src=/data/etc.tar.xz'
192.168.73.135 | CHANGED => {
    "changed": true, 
    "checksum": "2c7d756eff60249623f58d2ebec290848c4dea89", 
    "dest": "/data/192.168.73.135/data/etc.tar.xz", 
    "md5sum": "b20b3a78bcfd25d09d9ce2c9b7beeba3", 
    "remote_checksum": "2c7d756eff60249623f58d2ebec290848c4dea89", 
    "remote_md5sum": null
}
192.168.73.134 | CHANGED => {
    "changed": true, 
    "checksum": "c95913f7a079f6c1fb31016105b524685a21cb2d", 
    "dest": "/data/192.168.73.134/data/etc.tar.xz", 
    "md5sum": "e075e6d2681d7dbedaf070ad81ebd3e3", 
    "remote_checksum": "c95913f7a079f6c1fb31016105b524685a21cb2d", 
    "remote_md5sum": null
}

File模块

File模块可以设置文件的属性

参数说明
access_time访问时间
access_time_format时间格式
attributesattr格式
force当软连接的源文件不存在时使用
group设置文件的属组
mode设置文件的权限
modification_time文件修改时间
modification_time_format文件修改时间格式
owner设置文件的属主
path被管理的文件路径
src指定软硬链接的源文件位置
state设置文件的类型,file:文件不存在时不会被创建,link:创建软连接,hard:创建硬连接,absent:删除文件,touch:创建空文件

示例1:
修改文件的属主,权限

[root@ansible data]# ansible webserver -m file -a 'path=/data/test1 owner=masuri mode=777'
192.168.73.134 | CHANGED => {
    "changed": true, 
    "gid": 0, 
    "group": "root", 
    "mode": "0777", 
    "owner": "masuri", 
    "path": "/data/test1", 
    "size": 33, 
    "state": "file", 
    "uid": 1000
}
192.168.73.135 | CHANGED => {
    "changed": true, 
    "gid": 0, 
    "group": "root", 
    "mode": "0777", 
    "owner": "masuri", 
    "path": "/data/test1", 
    "size": 33, 
    "state": "file", 
    "uid": 1000
}

#查看属性
[root@ansible data]# ansible webserver -a 'ls -l /data/test1'
192.168.73.135 | CHANGED | rc=0 >>
-rwxrwxrwx 1 masuri root 33 Apr 25 10:11 /data/test1

192.168.73.134 | CHANGED | rc=0 >>
-rwxrwxrwx 1 masuri root 33 Apr 25 10:11 /data/test1

示例2:
创建硬连接,state=hard

[root@ansible data]# ansible webserver -m file -a 'src=/data/test1 name=/data/test1.log state=hard'
192.168.73.134 | CHANGED => {
    "changed": true, 
    "dest": "/data/test1.log", 
    "gid": 0, 
    "group": "root", 
    "mode": "0777", 
    "owner": "masuri", 
    "size": 33, 
    "src": "/data/test1", 
    "state": "hard", 
    "uid": 1000
}
192.168.73.135 | CHANGED => {
    "changed": true, 
    "dest": "/data/test1.log", 
    "gid": 0, 
    "group": "root", 
    "mode": "0777", 
    "owner": "masuri", 
    "size": 33, 
    "src": "/data/test1", 
    "state": "hard", 
    "uid": 1000
}
#查看文件
[root@ansible data]# ansible webserver -a 'ls -l /data/test1.log'
192.168.73.134 | CHANGED | rc=0 >>
-rwxrwxrwx 2 masuri root 33 Apr 25 10:11 /data/test1.log

192.168.73.135 | CHANGED | rc=0 >>
-rwxrwxrwx 2 masuri root 33 Apr 25 10:11 /data/test1.log

示例3:
创建软连接,state=link

[root@ansible data]# ansible webserver -m file -a 'src=/data/test1 name=/data/123 state=link'
192.168.73.135 | CHANGED => {
    "changed": true, 
    "dest": "/data/123", 
    "gid": 0, 
    "group": "root", 
    "mode": "0777", 
    "owner": "root", 
    "size": 11, 
    "src": "/data/test1", 
    "state": "link", 
    "uid": 0
}
192.168.73.134 | CHANGED => {
    "changed": true, 
    "dest": "/data/123", 
    "gid": 0, 
    "group": "root", 
    "mode": "0777", 
    "owner": "root", 
    "size": 11, 
    "src": "/data/test1", 
    "state": "link", 
    "uid": 0
}
#验证
[root@ansible data]# ansible webserver -a 'ls -l /data/123'
192.168.73.135 | CHANGED | rc=0 >>
lrwxrwxrwx 1 root root 11 Apr 25 10:56 /data/123 -> /data/test1

192.168.73.134 | CHANGED | rc=0 >>
lrwxrwxrwx 1 root root 11 Apr 25 10:56 /data/123 -> /data/test1

示例4:
创建空文件,state=touch

[root@ansible data]# ansible webserver -m file -a 'path=/data/test2 state=touch'
192.168.73.134 | CHANGED => {
    "changed": true, 
    "dest": "/data/test2", 
    "gid": 0, 
    "group": "root", 
    "mode": "0644", 
    "owner": "root", 
    "size": 0, 
    "state": "file", 
    "uid": 0
}
192.168.73.135 | CHANGED => {
    "changed": true, 
    "dest": "/data/test2", 
    "gid": 0, 
    "group": "root", 
    "mode": "0644", 
    "owner": "root", 
    "size": 0, 
    "state": "file", 
    "uid": 0
}
#验证
[root@ansible data]# ansible webserver -a 'ls -l /data/test2'
192.168.73.135 | CHANGED | rc=0 >>
-rw-r--r-- 1 root root 0 Apr 25 10:59 /data/test2

192.168.73.134 | CHANGED | rc=0 >>
-rw-r--r-- 1 root root 0 Apr 25 10:59 /data/test2

示例5:
删除文件,state=absent

[root@ansible data]# ansible webserver -m file -a 'path=/data/test2 state=absent'
192.168.73.134 | CHANGED => {
    "changed": true, 
    "path": "/data/test2", 
    "state": "absent"
}
192.168.73.135 | CHANGED => {
    "changed": true, 
    "path": "/data/test2", 
    "state": "absent"
}
#验证
[root@ansible data]# ansible webserver -a 'ls -l /data/test2'
192.168.73.135 | FAILED | rc=2 >>
ls: cannot access /data/test2: No such file or directorynon-zero return code

192.168.73.134 | FAILED | rc=2 >>
ls: cannot access /data/test2: No such file or directorynon-zero return code

hostname 模块

hostname 管理主机名

参数说明
name设置主机名

示例:

[root@ansible data]# ansible 192.168.73.134 -m hostname -a 'name=mylinuxops.com'
192.168.73.134 | CHANGED => {
    "ansible_facts": {
        "ansible_domain": "com", 
        "ansible_fqdn": "mylinuxops.com", 
        "ansible_hostname": "mylinuxops", 
        "ansible_nodename": "mylinuxops.com"
    }, 
    "changed": true, 
    "name": "mylinuxops.com"
}

cron 模块

corn 计划任务模块

参数说明
backup在计划任务创建前先备份
day
hour小时
minute分钟
month
weekday星期
name计划任务的名称
reboot重启后执行
stateabsent:删除
job计划任务的内容
disabled启用和禁用

示例1:
创建计划任务,每天1点备份/etc/目录

[root@ansible data]# ansible webserver -m cron -a 'name=backupetc hour=1 job="/usr/bin/cp -a /etc /data/`date +%F`"'
192.168.73.135 | CHANGED => {
    "changed": true, 
    "envs": [], 
    "jobs": [
        "backupetc"
    ]
}
192.168.73.134 | CHANGED => {
    "changed": true, 
    "envs": [], 
    "jobs": [
        "backupetc"
    ]
}
#验证
[root@ansible data]# ansible webserver -a 'crontab -l'
192.168.73.134 | CHANGED | rc=0 >>
#Ansible: backupetc
* 1 * * * /usr/bin/cp -a /etc /data/`date +%F`

192.168.73.135 | CHANGED | rc=0 >>
#Ansible: backupetc
* 1 * * * /usr/bin/cp -a /etc /data/`date +%F`

示例2:
计划任务的禁用,disabled=true

[root@ansible data]# ansible webserver -m cron -a 'name=backupetc day=* hour=1 job="/usr/bin/cp -a /etc /data/`date +%F`" disabled=true'
192.168.73.135 | CHANGED => {
    "changed": true, 
    "envs": [], 
    "jobs": [
        "backupetc"
    ]
}
192.168.73.134 | CHANGED => {
    "changed": true, 
    "envs": [], 
    "jobs": [
        "backupetc"
    ]
}
#验证
[root@ansible data]# ansible webserver -a 'crontab -l'
192.168.73.135 | CHANGED | rc=0 >>
#Ansible: backupetc
#* 1 * * * /usr/bin/cp -a /etc /data/`date +%F`

192.168.73.134 | CHANGED | rc=0 >>
#Ansible: backupetc
#* 1 * * * /usr/bin/cp -a /etc /data/`date +%F`

示例3:
计划任务的启用,disabled=false

[root@ansible data]# ansible webserver -m cron -a 'name=backupetc day=* hour=1 job="/usr/bin/cp -a /etc /data/`date +%F`" disabled=false'
192.168.73.135 | CHANGED => {
    "changed": true, 
    "envs": [], 
    "jobs": [
        "backupetc"
    ]
}
192.168.73.134 | CHANGED => {
    "changed": true, 
    "envs": [], 
    "jobs": [
        "backupetc"
    ]
}
#验证:
[root@ansible data]# ansible webserver -a 'crontab -l'
192.168.73.135 | CHANGED | rc=0 >>
#Ansible: backupetc
* 1 * * * /usr/bin/cp -a /etc /data/`date +%F`

192.168.73.134 | CHANGED | rc=0 >>
#Ansible: backupetc
* 1 * * * /usr/bin/cp -a /etc /data/`date +%F

示例4:
删除计划任务,state=absent

[root@ansible data]# ansible webserver -m cron -a 'name=backupetc day=* hour=1 job="/usr/bin/cp -a /etc /data/`date +%F`" state=absent'
192.168.73.134 | CHANGED => {
    "changed": true, 
    "envs": [], 
    "jobs": []
}
192.168.73.135 | CHANGED => {
    "changed": true, 
    "envs": [], 
    "jobs": []
}
[root@ansible data]# ansible webserver -a 'crontab -l'
192.168.73.135 | CHANGED | rc=0 >>

192.168.73.134 | CHANGED | rc=0 >>

yum 模块

yum 包管理

参数说明
name包的名字
statepresent:安装(可缺省),absent:卸载

示例:
按装httpd

[root@ansible data]# ansible webserver -m yum -a 'name=httpd'
192.168.73.135 | CHANGED => {
    "ansible_facts": {
...省略...
}

#验证
[root@ansible data]# ansible webserver -a 'rpm -q 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.73.134 | CHANGED | rc=0 >>
httpd-2.4.6-88.el7.centos.x86_64

192.168.73.135 | CHANGED | rc=0 >>
httpd-2.4.6-88.el7.centos.x86_64

示例2:
卸载httpd

[root@ansible data]# ansible webserver -m yum -a 'name=httpd state=absent'
192.168.73.134 | CHANGED => {
    "ansible_facts": {
        "pkg_mgr": "yum"
    }, 
    "changed": true, 
    "msg": "", 
....省略

#验证
[root@ansible data]# ansible webserver -a 'rpm -q 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.73.134 | FAILED | rc=1 >>
package httpd is not installednon-zero return code

192.168.73.135 | FAILED | rc=1 >>
package httpd is not installednon-zero return code

service 模块

service 用来管理服务

参数说明
enabled是否开机启动
name服务名称
runlevel运行在哪个级别上
statestarted:启动,stopped:停止,reloaded:重读配置文件,restarted:重启服务

示例1:
启动httpd服务

[root@ansible ~]# ansible webserver -m service -a 'name=httpd state=started'
;^H192.168.73.135 | CHANGED => {
    "changed": true, 
    "name": "httpd", 
    "state": "started", 
    "status": {
        "ActiveEnterTimestampMonotonic": "0", 
        "ActiveExitTimestampMonotonic": "0", 
...省略
#验证
[root@ansible ~]# ansible webserver  -a 'ss -tnl | grep 80 '
192.168.73.134 | CHANGED | rc=0 >>
LISTEN     0      128         :::80                      :::*                  

192.168.73.135 | CHANGED | rc=0 >>
LISTEN     0      128         :::80                      :::*                  

user 模块

user 用户管理模块

参数说明
name指定用户名
system系统用户
create_home创建家目录
shell指定shell类型
group指定主组
groups指定附加组
remove删除用户是删除家目录
stateabsent:删除用户
uid指定Uid号

示例:
创建mysql用户,为系统用户,shell类型为/sbin/nologin

[root@ansible ~]# ansible webserver -m user -a 'name=mysql system=yes shell=/sbin/nologin'
192.168.73.135 | CHANGED => {
    "changed": true, 
    "comment": "", 
    "create_home": true, 
    "group": 996, 
    "home": "/home/mysql", 
    "name": "mysql", 
    "shell": "/sbin/nologin", 
    "state": "present", 
    "system": true, 
    "uid": 998
}
192.168.73.134 | CHANGED => {
    "changed": true, 
    "comment": "", 
    "create_home": true, 
    "group": 996, 
    "home": "/home/mysql", 
    "name": "mysql", 
    "shell": "/sbin/nologin", 
    "state": "present", 
    "system": true, 
    "uid": 998
#验证
[root@ansible ~]# ansible webserver -a 'getent passwd mysql'
192.168.73.135 | CHANGED | rc=0 >>
mysql:x:998:996::/home/mysql:/sbin/nologin

192.168.73.134 | CHANGED | rc=0 >>
mysql:x:998:996::/home/mysql:/sbin/nologin

示例2
删除账号,删除账号时需要带上remove参数,默认不会删除用户的家目录

[root@ansible ~]# ansible webserver -m user -a 'name=mysql remove=yes state=absent'
192.168.73.135 | CHANGED => {
    "changed": true, 
    "force": false, 
    "name": "mysql", 
    "remove": true, 
    "state": "absent", 
    "stderr": "userdel: mysql mail spool (/var/spool/mail/mysql) not found\n", 
    "stderr_lines": [
        "userdel: mysql mail spool (/var/spool/mail/mysql) not found"
    ]
}
192.168.73.134 | CHANGED => {
    "changed": true, 
    "force": false, 
    "name": "mysql", 
    "remove": true, 
    "state": "absent", 
    "stderr": "userdel: mysql mail spool (/var/spool/mail/mysql) not found\n", 
    "stderr_lines": [
        "userdel: mysql mail spool (/var/spool/mail/mysql) not found"
    ]
}

ansible-console

ansible-console为可交互的ansible工具

[root@ansible ~]# ansible-console
Welcome to the ansible console.
Type help or ? to list commands.

root@all (2)[f:5]$ 
#all:为当前的所有主机,切换组可以使用cd + 组名 的方式
#2:主机数
#f:5 并行执行数,设置并发数 fork + NUM

ansible的playbook

ansible playbook 为ansible的脚本,其是由yaml语言构成,这种语言对格式的要求非常高。

yaml语言格式要求

1.在单一档案中,可以用连续三个连字号(---)区分多个档案,另外,还有选择性的连续三个点号_(...)来表示档案的结尾
2.此行开始正常写playbook的内容,一般建议写明该playbook的功能
3.使用#注释代码
4.缩进必须统一的,不能空格和tab混用
5.缩进的级别也必须是一致的,同样的缩进代表同样的级别,程序判别配置的级别是通过缩进结合换行来实现的
6.YAML文件内容是区分大小写的,k/v的值均需大小写敏感
7.多个k/v可以同行写也可以换行写,同行使用,分割
8.v可以是个字符串,也可以是另一个列表
9.一个完整的代码块功能需最少元素包括name和task
10.一个name只能包括一个task
11.YAML文件扩展名通常为yaml或yml

示例1:

[root@ansible data]# vim hello.yaml
---
#hello world
  - host: webserver
    remote_user: root

    task:
      - name: hello world
        shell: /usr/bin/wall hello world
~                                   

示例2:
安装httpd
1.准备好httpd配置文件

[root@ansible data]# vim httpd.conf 
Listen 8080

2.编写yaml文件

---
#install httpd
  - hosts: webserver
    remote_user: root

    tasks:
      - name: install
        yum: name=httpd
      - name: config
        copy: src=/data/httpd.conf dest=/etc/httpd/httpd.conf
      - name: service
        service: name=httpd state=started
      - name: check
        shell: ss -tnl | grep 8080

3.检查是否有语法错误

[root@ansible data]# ansible-playbook -C httpd.yaml 

PLAY [webserver] ************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************
ok: [192.168.73.134]
ok: [192.168.73.135]

TASK [install] **************************************************************************************************
ok: [192.168.73.135]
ok: [192.168.73.134]

TASK [config] ***************************************************************************************************
changed: [192.168.73.134]
changed: [192.168.73.135]

TASK [service] **************************************************************************************************
ok: [192.168.73.134]
ok: [192.168.73.135]

PLAY RECAP ******************************************************************************************************
192.168.73.134             : ok=4    changed=1    unreachable=0    failed=0   
192.168.73.135             : ok=4    changed=1    unreachable=0    failed=0   

4.执行yaml脚本

[root@ansible data]# ansible-playbook httpd.yaml

PLAY [webserver] ************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************
ok: [192.168.73.134]
ok: [192.168.73.135]

TASK [install] **************************************************************************************************
changed: [192.168.73.135]
changed: [192.168.73.134]

TASK [config] ***************************************************************************************************
changed: [192.168.73.135]
changed: [192.168.73.134]

TASK [service] **************************************************************************************************
changed: [192.168.73.135]
changed: [192.168.73.134]

PLAY RECAP ******************************************************************************************************
192.168.73.134             : ok=4    changed=3    unreachable=0    failed=0   
192.168.73.135             : ok=4    changed=3    unreachable=0    failed=0   

5.校验

[root@ansible data]# ansible webserver -a 'ss -tnl | grep 8080'
192.168.73.134 | CHANGED | rc=0 >>
LISTEN     0      128         :::8080                    :::*                  

192.168.73.135 | CHANGED | rc=0 >>
LISTEN     0      128         :::8080                    :::*      

示例3:
创建mysql用户。
1.编写yaml文件

 [root@ansible data]# vim user.yml
---
#useradd
  - hosts: webserver
    remote_user: root

    tasks:
      - name: create group
        group: name=mysql gid=3306
      - name: create user
        user: name=mysql uid=3306 shell=/sbin/nologlin system=yes group=mysql create_home=no

2.检查语法

[root@ansible data]# ansible-playbook -C user.yml 

PLAY [webserver] ************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************
ok: [192.168.73.134]
ok: [192.168.73.135]

TASK [create group] *********************************************************************************************
changed: [192.168.73.134]
changed: [192.168.73.135]

TASK [create user] **********************************************************************************************
changed: [192.168.73.135]
changed: [192.168.73.134]

PLAY RECAP ******************************************************************************************************
192.168.73.134             : ok=3    changed=2    unreachable=0    failed=0   
192.168.73.135             : ok=3    changed=2    unreachable=0    failed=0   

3.执行

[root@ansible data]# ansible-playbook  user.yml 

PLAY [webserver] ************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************
ok: [192.168.73.134]
ok: [192.168.73.135]

TASK [create group] *********************************************************************************************
changed: [192.168.73.135]
changed: [192.168.73.134]

TASK [create user] **********************************************************************************************
changed: [192.168.73.135]
changed: [192.168.73.134]

PLAY RECAP ******************************************************************************************************
192.168.73.134             : ok=3    changed=2    unreachable=0    failed=0   
192.168.73.135             : ok=3    changed=2    unreachable=0    failed=0   

4.验证

[root@ansible data]# ansible webserver -a 'getent passwd mysql'
192.168.73.134 | CHANGED | rc=0 >>
mysql:x:3306:3306::/home/mysql:/sbin/nologlin

192.168.73.135 | CHANGED | rc=0 >>
mysql:x:3306:3306::/home/mysql:/sbin/nologlin

playbook中的notify和handler
当执行一个playbook时,第一次执行和第二次执行效果相同,当服务的配置文件发生变化时再次安装时已经启动的服务不会重启,此时就需要使用到notify。
notify的action可用于在每个play的最后被触发,这样可以避免多次有改变发生时每次都执行指定的操作,仅在所有的变化发生完成后一次性地执行指定操作。
notify是触发条件,headlers是执行的任务

示例1:
1.以httpd为例,刚才已经启动了HTTP服务,此时再次修改httpd.conf,将端口改为80

[root@ansible data]# vim /data/httpd.conf
Listen 80

2.对yaml文件进行修改,增加notify及handlers

[root@ansible data]# vim httpd.yaml 

---
#install httpd
  - hosts: webserver
    remote_user: root

    tasks:
      - name: install
        yum: name=httpd
      - name: config
        copy: src=/data/httpd.conf dest=/etc/httpd/conf/httpd.conf
        notify: restart service
      - name: service
        service: name=httpd state=started

    handlers:
      - name: restart service
        service: name=httpd state=restarted

3.检查语法

[root@ansible data]# ansible-playbook -C httpd.yaml 

PLAY [webserver] ************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************
ok: [192.168.73.135]
ok: [192.168.73.134]

TASK [install] **************************************************************************************************
ok: [192.168.73.135]
ok: [192.168.73.134]

TASK [config] ***************************************************************************************************
changed: [192.168.73.135]
changed: [192.168.73.134]

TASK [service] **************************************************************************************************
ok: [192.168.73.135]
ok: [192.168.73.134]

RUNNING HANDLER [restart service] *******************************************************************************
changed: [192.168.73.134]
changed: [192.168.73.135]

PLAY RECAP ******************************************************************************************************
192.168.73.134             : ok=5    changed=2    unreachable=0    failed=0   
192.168.73.135             : ok=5    changed=2    unreachable=0    failed=0 

4.执行

[root@ansible data]# ansible-playbook  httpd.yaml 

PLAY [webserver] ************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************
ok: [192.168.73.135]
ok: [192.168.73.134]

TASK [install] **************************************************************************************************
ok: [192.168.73.135]
ok: [192.168.73.134]

TASK [config] ***************************************************************************************************
changed: [192.168.73.135]
changed: [192.168.73.134]

TASK [service] **************************************************************************************************
ok: [192.168.73.135]
ok: [192.168.73.134]

RUNNING HANDLER [restart service] *******************************************************************************
changed: [192.168.73.134]
changed: [192.168.73.135]

PLAY RECAP ******************************************************************************************************
192.168.73.134             : ok=5    changed=2    unreachable=0    failed=0   
192.168.73.135             : ok=5    changed=2    unreachable=0    failed=0   

5.验证:

[root@ansible data]# ansible webserver -a 'ss -tnl |grep 80'
192.168.73.135 | CHANGED | rc=0 >>
LISTEN     0      128         :::80                      :::*                  

192.168.73.134 | CHANGED | rc=0 >>
LISTEN     0      128         :::80                      :::*  

ansible-playbook中标签的使用 tags

在playbook中添加标签可以让playbook在运行时,选择性的执行被标签的内容
示例:
再次将httpd.conf文件进行修改,将端口改为8080

[root@ansible data]# vim httpd.conf 
Listen 8080

对yaml文件进行贴标签

[root@ansible data]# vim httpd.yaml 
---
#install httpd
  - hosts: webserver
    remote_user: root

    tasks:
      - name: install
        yum: name=httpd
      - name: config
        copy: src=/data/httpd.conf dest=/etc/httpd/conf/httpd.conf
        notify: restart service
        tags: config
      - name: service
        service: name=httpd state=started

    handlers:
      - name: restart service
        service: name=httpd state=restarted

由于此时http服务已经安装,不需要再次安装此服务,我们只需要执行被标签的config部分就行,标签的config执行时,触发了handler的重启服务。

[root@ansible data]# ansible-playbook -t config httpd.yaml 

PLAY [webserver] ************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************
ok: [192.168.73.135]
ok: [192.168.73.134]

TASK [config] ***************************************************************************************************
changed: [192.168.73.135]
changed: [192.168.73.134]

RUNNING HANDLER [restart service] *******************************************************************************
changed: [192.168.73.135]
changed: [192.168.73.134]

PLAY RECAP ******************************************************************************************************
192.168.73.134             : ok=3    changed=2    unreachable=0    failed=0   
192.168.73.135             : ok=3    changed=2    unreachable=0    failed=0 

验证

[root@ansible data]# ansible webserver -a 'ss -tnl |grep 8080'
192.168.73.135 | CHANGED | rc=0 >>
LISTEN     0      128         :::8080                    :::*                  

192.168.73.134 | CHANGED | rc=0 >>
LISTEN     0      128         :::8080                    :::*  

我们也可以用贴多个相同的标签,让playbook执行标签时一次执行多个不同的操作
示例:
1.再次修改http端口将其改为80端口

[root@ansible data]# vim httpd.conf 
Listen 80

2.创建yaml文件

---
#install httpd
  - hosts: webserver
    remote_user: root

    tasks:
      - name: install
        yum: name=httpd
      - name: config
        copy: src=/data/httpd.conf dest=/etc/httpd/conf/httpd.conf
        tags: config
      - name: service       #service和restart service的标签相同
        service: name=httpd state=started
        tags: service
      - name: restart service
        service: name=httpd state=restarted
        tags: service

3.执行playbook

[root@ansible data]# ansible-playbook -t config -t service httpd.yaml 

PLAY [webserver] ************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************
ok: [192.168.73.134]
ok: [192.168.73.135]

TASK [config] ***************************************************************************************************
changed: [192.168.73.135]
changed: [192.168.73.134]

TASK [service] **************************************************************************************************
ok: [192.168.73.134]
ok: [192.168.73.135]

TASK [restart service] ******************************************************************************************
changed: [192.168.73.135]
changed: [192.168.73.134]

PLAY RECAP ******************************************************************************************************
192.168.73.134             : ok=4    changed=2    unreachable=0    failed=0   
192.168.73.135             : ok=4    changed=2    unreachable=0    failed=0 

4.验证

[root@ansible data]# ansible webserver -a 'ss -tnl |grep 80'
192.168.73.135 | CHANGED | rc=0 >>
LISTEN     0      128         :::80                      :::*                  

192.168.73.134 | CHANGED | rc=0 >>
LISTEN     0      128         :::80                      :::*   

playbook中的变量

变量命名规则:仅能由字母、数字和下划线组成,且只能以字母开头
变量来源:
1.ansible setup facts 远程主机的所有变量都可直接调用
示例:
此命令可以查看远程主机上所有已存在的各种变量,此处查看hostname的变量名

[root@ansible data]# ansible webserver -m setup -a 'filter=*hostname'
192.168.73.134 | SUCCESS => {
    "ansible_facts": {
        "ansible_hostname": "mylinuxops"
    }, 
    "changed": false
}
192.168.73.135 | SUCCESS => {
    "ansible_facts": {
        "ansible_hostname": "web2"
    }, 
    "changed": false
}

创建yaml文件,调用变量

[root@ansible data]# vim var.yaml

---
#test var
    - hosts: webserver
      remote_user: root

      tasks:
        - name: file
          file: name={{ansible_hostname}}.log state=touch

执行yaml

[root@ansible data]# ansible-playbook var.yaml 

PLAY [webserver] ************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************
ok: [192.168.73.135]
ok: [192.168.73.134]

TASK [file] *****************************************************************************************************
changed: [192.168.73.134]
changed: [192.168.73.135]

PLAY RECAP ******************************************************************************************************
192.168.73.134             : ok=2    changed=1    unreachable=0    failed=0   
192.168.73.135             : ok=2    changed=1    unreachable=0    failed=0 

验证

[root@ansible data]# ansible webserver -a 'ls  /root'
192.168.73.134 | CHANGED | rc=0 >>
anaconda-ks.cfg
mylinuxops.log

192.168.73.135 | CHANGED | rc=0 >>
anaconda-ks.cfg
web2.log

2.变量可以定义在主机清单中
主机清单中的变量分为两种,普通变量和公共变量
普通变量:主机组中主机单独定义,优先级高于公共变量
公共变量:针对主机组中所有主机定义的统一变量
示例:
修改主机清单

[root@ansible data]# vim /etc/ansible/hosts 
[webserver]
192.168.73.134 port=80
192.168.73.135 port=8080

[webserver:vars]    #通用变量
mark="-"

创建playbook

[root@ansible data]# vim var.yaml 
---
#test var
- hosts: webserver
  remote_user: root

  tasks:
    - name: file
      file: name={{ansible_hostname}}{{mask}}{{port}}.log state=touch

执行剧本

[root@ansible data]# ansible-playbook var.yaml 

PLAY [webserver] ************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************
ok: [192.168.73.135]
ok: [192.168.73.134]

TASK [file] *****************************************************************************************************
changed: [192.168.73.135]
changed: [192.168.73.134]

PLAY RECAP ******************************************************************************************************
192.168.73.134             : ok=2    changed=1    unreachable=0    failed=0   
192.168.73.135             : ok=2    changed=1    unreachable=0    failed=0  

验证:

[root@ansible data]# ansible webserver -a 'ls /root'
192.168.73.135 | CHANGED | rc=0 >>
anaconda-ks.cfg
web2-8080.log
web2.log

192.168.73.134 | CHANGED | rc=0 >>
anaconda-ks.cfg
mylinuxops-80.log
mylinuxops.log

3.变量可以通过-e来定义
示例:
依旧使用刚才的剧本,直接在命令行添加-e选项

[root@ansible data]# ansible-playbook -e port=1234 var.yaml 
 [WARNING]: Found variable using reserved name: port

PLAY [webserver] ************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************
ok: [192.168.73.134]
ok: [192.168.73.135]

TASK [file] *****************************************************************************************************
changed: [192.168.73.134]
changed: [192.168.73.135]

PLAY RECAP ******************************************************************************************************
192.168.73.134             : ok=2    changed=1    unreachable=0    failed=0   
192.168.73.135             : ok=2    changed=1    unreachable=0    failed=0 

验证:

[root@ansible data]# ansible webserver -a 'ls /root'
192.168.73.135 | CHANGED | rc=0 >>
anaconda-ks.cfg
web2-1234.log
web2-8080.log
web2.log

192.168.73.134 | CHANGED | rc=0 >>
anaconda-ks.cfg
mylinuxops-1234.log
mylinuxops-80.log
mylinuxops.log

由此可以发现,通过命令行指定的变量优先级高于主机文件中定义的变量

4.在剧本中定义变量
vars:
-var1:value1
-var2:value2
示例:
在playbook中添加变量

[root@ansible data]# vim var.yaml 
---
#test var
- hosts: webserver
  remote_user: root
  var:
    - port: 4321

  tasks:
    - name: file
      file: name={{ansible_hostname}}{{mark}}{{port}}.log state=touch

执行playbook

[root@ansible data]# ansible-playbook  var.yaml 
 [WARNING]: Found variable using reserved name: port

PLAY [webserver] ************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************
ok: [192.168.73.135]
ok: [192.168.73.134]

TASK [file] *****************************************************************************************************
changed: [192.168.73.135]
changed: [192.168.73.134]

PLAY RECAP ******************************************************************************************************
192.168.73.134             : ok=2    changed=1    unreachable=0    failed=0   
192.168.73.135             : ok=2    changed=1    unreachable=0    failed=0   

验证:

[root@ansible data]# ansible webserver -a 'ls /root'
192.168.73.134 | CHANGED | rc=0 >>
anaconda-ks.cfg
mylinuxops-1234.log
mylinuxops-4321.log
mylinuxops-80.log
mylinuxops.log

192.168.73.135 | CHANGED | rc=0 >>
anaconda-ks.cfg
web2-1234.log
web2-4321.log
web2-8080.log
web2.log

由此可以得出剧本中的变量优先级高于主机清单中的变量

5.变量定义在一个专用的变量文件中
示例:
创建一个存放变量的文件

[root@ansible data]# vim vars.yml
port: 9527

在playbook中调用变量

[root@ansible data]# vim var.yaml 
---
#test var
- hosts: webserver
  remote_user: root
  vars_files:
    - vars.yml
  vars:
    - port: 4321

  tasks:
    - name: file
      file: name={{ansible_hostname}}{{mark}}{{port}}.log state=touch

执行playbook

[root@ansible data]# ansible-playbook  var.yaml 
 [WARNING]: Found variable using reserved name: port

PLAY [webserver] ************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************
ok: [192.168.73.134]
ok: [192.168.73.135]

TASK [file] *****************************************************************************************************
changed: [192.168.73.135]
changed: [192.168.73.134]

PLAY RECAP ******************************************************************************************************
192.168.73.134             : ok=2    changed=1    unreachable=0    failed=0   
192.168.73.135             : ok=2    changed=1    unreachable=0    failed=0 

检查

[root@ansible data]# ansible webserver -a 'ls /root'
192.168.73.135 | CHANGED | rc=0 >>
anaconda-ks.cfg
web2-1234.log
web2-4321.log
web2-8080.log
web2-9527.log
web2.log

192.168.73.134 | CHANGED | rc=0 >>
anaconda-ks.cfg
mylinuxops-1234.log
mylinuxops-4321.log
mylinuxops-80.log
mylinuxops-9527.log
mylinuxops.log

由此可见使用变量文件定义的变量优先级高于playbook中定义的变量

变量优先级的总结:
命令-e指定 > 变量文件 > playbook指定 > hosts文件

ansible的模板template

template可以根据模块文件动态生成相对应的配置文件。
template对文件的存放和命名有要求,template文件必须存放在templates目录下,并且以.j2后缀命名。
yaml文件需要和templates目录平级,目录结构如下。

[root@ansible data]# tree yaml/
yaml/
├── hello.yaml
├── httpd.yaml
└── templates
    └── test.conf.j2

示例1:
为主机列表中的主机安装nginx
编写yaml文件

[root@ansible ~]# vim nginx.yml

---
#install nginx
- hosts: webserver
  remote_user: root

  tasks:
    - name: package
      yum: name=nginx
    - name: service
      service: name=nginx state=started enabled=yes

执行

[root@ansible ~]# ansible-playbook nginx.yml 

PLAY [webserver] ************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************
ok: [192.168.73.134]
ok: [192.168.73.135]

TASK [package] **************************************************************************************************
ok: [192.168.73.135]
ok: [192.168.73.134]

TASK [service] **************************************************************************************************
changed: [192.168.73.135]
changed: [192.168.73.134]

PLAY RECAP ******************************************************************************************************
192.168.73.134             : ok=3    changed=1    unreachable=0    failed=0   
192.168.73.135             : ok=3    changed=1    unreachable=0    failed=0 

示例1:
用模板文件实现cpu个数+2的进程数
1.获取nginx的配置文件,并改名为.j2后缀的文件存放在templates目录下

[root@ansible data]# mv nginx.conf /data/yaml/templates/nginx.conf.j2 

2.获取cpu个数的变量

[root@ansible data]# ansible 192.168.73.134 -m setup | grep cpu
        "ansible_processor_vcpus": 1,  #此为定义cpu的变量

3.修改模板文件

[root@ansible data]# vim yaml/templates/nginx.conf.j2 
worker_processes {{ansible_processor_vcpus+2}};  #此行定义了线程数,改为变量代替

4.在playbook中引用模板

[root@ansible yaml]# vim nginx.yml 

---
#install nginx
- hosts: webserver
  remote_user: root

  tasks:
    - name: package
      yum: name=nginx
    - name: config
      template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
      notify: restart service
    - name: service
      service: name=nginx state=started enabled=yes

  handlers:
    - name: restart service
      service: name=nginx state=restarted

5.执行playbook

[root@ansible yaml]# ansible-playbook nginx.yml 

PLAY [webserver] ************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************
ok: [192.168.73.134]
ok: [192.168.73.135]

TASK [package] **************************************************************************************************
ok: [192.168.73.134]
ok: [192.168.73.135]

TASK [config] ***************************************************************************************************
changed: [192.168.73.134]
changed: [192.168.73.135]

TASK [service] **************************************************************************************************
ok: [192.168.73.134]
ok: [192.168.73.135]

RUNNING HANDLER [restart service] *******************************************************************************
changed: [192.168.73.135]
changed: [192.168.73.134]

PLAY RECAP ******************************************************************************************************
192.168.73.134             : ok=5    changed=2    unreachable=0    failed=0   
192.168.73.135             : ok=5    changed=2    unreachable=0    failed=0   

验证:

[root@ansible yaml]# ansible webserver -a 'cat /etc/nginx/nginx.conf | grep work'
192.168.73.135 | CHANGED | rc=0 >>
worker_processes 3;
    worker_connections 1024;

192.168.73.134 | CHANGED | rc=0 >>
worker_processes 3;
    worker_connections 1024;

示例2:
修改模板中的端口

    server {
        listen       {{port}} default_server; 将此处的端口改为变量
        listen       [::]:80 default_server;

修改主机文件定义port

[webserver]
192.168.73.134 port=80
192.168.73.135 port=8080

重新执行yaml

[root@ansible yaml]# ansible-playbook nginx.yml 

PLAY [webserver] ************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************
ok: [192.168.73.134]
ok: [192.168.73.135]

TASK [package] **************************************************************************************************
ok: [192.168.73.134]
ok: [192.168.73.135]

TASK [config] ***************************************************************************************************
ok: [192.168.73.134]
changed: [192.168.73.135]

TASK [service] **************************************************************************************************
ok: [192.168.73.135]
ok: [192.168.73.134]

RUNNING HANDLER [restart service] *******************************************************************************
changed: [192.168.73.135]

PLAY RECAP ******************************************************************************************************
192.168.73.134             : ok=4    changed=0    unreachable=0    failed=0   
192.168.73.135             : ok=5    changed=2    unreachable=0    failed=0

校验

[root@ansible yaml]# ansible webserver -a 'ss -tnl |grep 80'
192.168.73.134 | CHANGED | rc=0 >>
LISTEN     0      128          *:80                       *:*                  
LISTEN     0      128         :::80                      :::*                  

192.168.73.135 | CHANGED | rc=0 >>
LISTEN     0      128          *:8080                     *:*                  
LISTEN     0      128         :::80                      :::*  

playbook中的流控制

when

when测试条件:如果需要根据变量、facts或此前任务的执行结果来作为某task执行与否的前提条件时,需要用到条件测试,通过when语句实现,在task中使用,jinja2语法。
示例:
当系统不同时,httpd的配置文件也不同
1.先查找系统中版本变量

[root@ansible yaml]# ansible webserver -m setup | grep distribution_major_version
        "ansible_distribution_major_version": "6", 
        "ansible_distribution_major_version": "7", 
        "ansible_distribution_major_version": "7", 

2.编写yaml文件

[root@ansible yaml]# vim httpd.yaml
---
#install httpd
  - hosts: webserver
    remote_user: root

    tasks:
      - name: install
        yum: name=httpd
      - name: config
        template: src=httpd6.conf.j2 dest=/etc/httpd/conf/httpd.conf
        when: ansible_distribution_major_version == "6"
        notify: restart service
      - name: config
        template: src=httpd7.conf.j2 dest=/etc/httpd/conf/httpd.conf
        when: ansible_distribution_major_version == "7"
        notify: restart service
      - name: service
        service: name=httpd state=started

    handlers:
      - name: restart service
        service: name=httpd state=restarted

3.修改模板文件

[root@ansible templates]# vi httpd6.conf.j2 
#Listen 12.34.56.78:80
Listen {{port}}

[root@ansible templates]# vi httpd7.conf.j2 
#Listen 12.34.56.78:80
Listen {{port}}

4.执行脚本

[root@ansible yaml]# ansible-playbook  httpd.yaml 

PLAY [webserver] ************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************
ok: [192.168.73.135]
ok: [192.168.73.132]
ok: [192.168.73.134]

TASK [install] **************************************************************************************************
changed: [192.168.73.135]
changed: [192.168.73.134]
changed: [192.168.73.132]

TASK [config] ***************************************************************************************************
skipping: [192.168.73.134]
skipping: [192.168.73.135]
changed: [192.168.73.132]

TASK [config] ***************************************************************************************************
skipping: [192.168.73.132]
ok: [192.168.73.134]
changed: [192.168.73.135]

TASK [service] **************************************************************************************************
changed: [192.168.73.132]
changed: [192.168.73.135]
changed: [192.168.73.134]

RUNNING HANDLER [restart service] *******************************************************************************
changed: [192.168.73.132]
changed: [192.168.73.135]

PLAY RECAP ******************************************************************************************************
192.168.73.132             : ok=5    changed=4    unreachable=0    failed=0   
192.168.73.134             : ok=4    changed=2    unreachable=0    failed=0   
192.168.73.135             : ok=5    changed=4    unreachable=0    failed=0 

with_items

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

示例:
创建多个文件
aaa.log
bbb.log
ccc.log

1.创建剧本

[root@ansible yaml]# vim file.yaml
---
#touch file
- hosts: webserver
  remote_user: root

  tasks:
    - name: touch file
      file: name=/data/{{item}}.log state=touch
      with_items:
        - aaa
        - bbb
        - ccc              

2.执行

[root@ansible yaml]# ansible-playbook  file.yaml 

PLAY [webserver] ************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************
ok: [192.168.73.132]
ok: [192.168.73.134]
ok: [192.168.73.135]

TASK [touch file] ***********************************************************************************************
changed: [192.168.73.132] => (item=aaa)
changed: [192.168.73.134] => (item=aaa)
changed: [192.168.73.135] => (item=aaa)
changed: [192.168.73.132] => (item=bbb)
changed: [192.168.73.134] => (item=bbb)
changed: [192.168.73.135] => (item=bbb)
changed: [192.168.73.132] => (item=ccc)
changed: [192.168.73.135] => (item=ccc)
changed: [192.168.73.134] => (item=ccc)

PLAY RECAP ******************************************************************************************************
192.168.73.132             : ok=2    changed=1    unreachable=0    failed=0   
192.168.73.134             : ok=2    changed=1    unreachable=0    failed=0   
192.168.73.135             : ok=2    changed=1    unreachable=0    failed=0   

校验:

[root@ansible yaml]# ansible webserver -a 'ls /data' 
192.168.73.132 | CHANGED | rc=0 >>
aaa.log
bbb.log
ccc.log
lost+found

示例:
创建不同的用户:
1.创建yaml文件

[root@ansible yaml]# vim createuser.yml
---
#createuser
- hosts: webserver
  remote_user: root

  tasks:
    - name: create user
      user: name={{item}}
      with_items:
        - alice
        - bob
        - clack            

2.执行

[root@ansible yaml]# ansible-playbook createuser.yml

PLAY [webserver] ************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************
ok: [192.168.73.135]
ok: [192.168.73.132]
ok: [192.168.73.134]

TASK [create user] **********************************************************************************************
changed: [192.168.73.135] => (item=alice)
changed: [192.168.73.134] => (item=alice)
changed: [192.168.73.132] => (item=alice)
changed: [192.168.73.132] => (item=bob)
changed: [192.168.73.135] => (item=bob)
changed: [192.168.73.134] => (item=bob)
changed: [192.168.73.132] => (item=clack)
changed: [192.168.73.134] => (item=clack)
changed: [192.168.73.135] => (item=clack)

PLAY RECAP ******************************************************************************************************
192.168.73.132             : ok=2    changed=1    unreachable=0    failed=0   
192.168.73.134             : ok=2    changed=1    unreachable=0    failed=0   
192.168.73.135             : ok=2    changed=1    unreachable=0    failed=0 

3.校验

[root@ansible yaml]# ansible webserver -a 'getent passwd | tail -3'
192.168.73.132 | CHANGED | rc=0 >>
alice:x:500:500::/home/alice:/bin/bash
bob:x:501:501::/home/bob:/bin/bash
clack:x:502:502::/home/clack:/bin/bash

192.168.73.135 | CHANGED | rc=0 >>
alice:x:3307:3307::/home/alice:/bin/bash
bob:x:3308:3308::/home/bob:/bin/bash
clack:x:3309:3309::/home/clack:/bin/bash

192.168.73.134 | CHANGED | rc=0 >>
alice:x:3307:3307::/home/alice:/bin/bash
bob:x:3308:3308::/home/bob:/bin/bash
clack:x:3309:3309::/home/clack:/bin/bash

创建组和用户的对应关系
将用户名和组名做字典对应

[root@ansible yaml]# vim usergroup.yaml
---
- hosts: webserver
  remote_user: root

  tasks:
    - name: create group
      group: name={{item}}
      with_items:
        - agroup
        - bgroup
        - cgroup
    - name: create user
      user: name={{item.name}} group={{item.group}}
      with_item:
        - { name: "aaa",group: "agroup"}
        - { name: "bbb",group: "bgroup"}
        - { name: "ccc",group: "cgroup"}

执行脚本:

[root@ansible yaml]# ansible-playbook usergroup.yaml 

PLAY [webserver] ************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************
ok: [192.168.73.135]
ok: [192.168.73.132]
ok: [192.168.73.134]

TASK [create group] *********************************************************************************************
changed: [192.168.73.132] => (item=agroup)
changed: [192.168.73.134] => (item=agroup)
changed: [192.168.73.135] => (item=agroup)
changed: [192.168.73.132] => (item=bgroup)
changed: [192.168.73.135] => (item=bgroup)
changed: [192.168.73.134] => (item=bgroup)
changed: [192.168.73.132] => (item=cgroup)
changed: [192.168.73.135] => (item=cgroup)
changed: [192.168.73.134] => (item=cgroup)

TASK [create user] **********************************************************************************************
changed: [192.168.73.134] => (item={u'group': u'agroup', u'name': u'aaa'})
changed: [192.168.73.132] => (item={u'group': u'agroup', u'name': u'aaa'})
changed: [192.168.73.135] => (item={u'group': u'agroup', u'name': u'aaa'})
changed: [192.168.73.132] => (item={u'group': u'bgroup', u'name': u'bbb'})
changed: [192.168.73.135] => (item={u'group': u'bgroup', u'name': u'bbb'})
changed: [192.168.73.134] => (item={u'group': u'bgroup', u'name': u'bbb'})
changed: [192.168.73.132] => (item={u'group': u'cgroup', u'name': u'ccc'})
changed: [192.168.73.134] => (item={u'group': u'cgroup', u'name': u'ccc'})
changed: [192.168.73.135] => (item={u'group': u'cgroup', u'name': u'ccc'})

PLAY RECAP ******************************************************************************************************
192.168.73.132             : ok=3    changed=2    unreachable=0    failed=0   
192.168.73.134             : ok=3    changed=2    unreachable=0    failed=0   
192.168.73.135             : ok=3    changed=2    unreachable=0    failed=0 

校验:

[root@ansible yaml]# ansible webserver -a 'id aaa'
192.168.73.132 | CHANGED | rc=0 >>
uid=503(aaa) gid=503(agroup) groups=503(agroup)

192.168.73.134 | CHANGED | rc=0 >>
uid=3310(aaa) gid=3310(agroup) groups=3310(agroup)

192.168.73.135 | CHANGED | rc=0 >>
uid=3310(aaa) gid=3310(agroup) groups=3310(agroup)

template中的for

生成以下文件内容:

server{
        listen 81
        server_name www.a.com
        root /app/websitea/    
}
server{
        listen 82
        server_name www.a.com
        root /app/websitea/    
}
server{
        listen 83
        server_name www.a.com
        root /app/websitea/    
}

1.创建模板文件

[root@ansible yaml]# vim templates/test1.j2
{%for i in test_ports %}
server {
        listen {{i}}
        server_name www.a.com
        root /app/websitea
}

{%endfor%}

2.创建yaml文件

[root@ansible yaml]# vim test1.yaml

---
- hosts: webserver
  remote_user: root
  vars:
    test_ports:
      - 81
      - 82
      - 83

  tasks:
    - name: tempate
      template: src=test1.j2 dest=/data/test.conf
~                                                      

3.执行脚本

[root@ansible yaml]# ansible-playbook test1.yaml

PLAY [webserver] ************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************
ok: [192.168.73.132]
ok: [192.168.73.135]
ok: [192.168.73.134]

TASK [tempate] **************************************************************************************************
changed: [192.168.73.132]
changed: [192.168.73.135]
changed: [192.168.73.134]

PLAY RECAP ******************************************************************************************************
192.168.73.132             : ok=2    changed=1    unreachable=0    failed=0   
192.168.73.134             : ok=2    changed=1    unreachable=0    failed=0   
192.168.73.135             : ok=2    changed=1    unreachable=0    failed=0 

校验:

[root@mylinuxops ~]# cat /data/test.conf 
server {
    listen 81
    server_name www.a.com
    root /app/websitea
}

server {
    listen 82
    server_name www.a.com
    root /app/websitea
}

server {
    listen 83
    server_name www.a.com
    root /app/websitea
}

示例2:
生成以下文件:

server{
        listen 81
        server_name www.a.com
        root /app/websitea    
}
server{
        listen 82
        server_name www.b.com
        root /app/websiteb    
}
server{
        listen 83
        server_name www.a.com
        root /app/websitec    
}

使用字典绑定
1.修改模板:

[root@ansible yaml]# vim templates/test1.j2 

{%for i in vhosts %}
server {
        listen {{i.port}}
        server_name {{i.name}}
        root {{i.dir}}
}

{%endfor%}

2.修改剧本

[root@ansible yaml]# vim test1.yaml 

---
- hosts: webserver
  remote_user: root
  vars:
    vhosts:
      - web1:
        port: 81
        name: www.a.com
        dir: /data/websitea
      - web2:
        port: 82
        name: www.b.com
        dir: /data/websiteb
      - web3:
        port: 83
        name: www.c.com
        dir: /data/websitec

  tasks:
    - name: tempate
      template: src=test1.j2 dest=/data/test2.conf

3.执行脚本

[root@ansible yaml]# ansible-playbook test1.yaml

PLAY [webserver] ************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************
ok: [192.168.73.135]
ok: [192.168.73.132]
ok: [192.168.73.134]

TASK [tempate] **************************************************************************************************
changed: [192.168.73.132]
changed: [192.168.73.135]
changed: [192.168.73.134]

PLAY RECAP ******************************************************************************************************
192.168.73.132             : ok=2    changed=1    unreachable=0    failed=0   
192.168.73.134             : ok=2    changed=1    unreachable=0    failed=0   
192.168.73.135             : ok=2    changed=1    unreachable=0    failed=0 

4.校验

[root@web2 data]# vi test2.conf 

server {
        listen 81
        server_name www.a.com
        root /data/websitea
}

server {
        listen 82
        server_name www.b.com
        root /data/websiteb
}

server {
        listen 83
        server_name www.c.com
        root /data/websitec
}

template中的if

if可以判断变量是否定义,定了就引用,若是没有定义则不引用

示例:
1.修改模板

[root@ansible yaml]# vim templates/test1.j2 

{%for i in vhosts %}
server {
        listen {{i.port}}
{%if i.name is defined %}
        server_name {{i.name}}
{%endif%}
        root {{i.dir}}
}

{%endfor%}

2.修改yaml

[root@ansible yaml]# vim test1.yaml 

---
- hosts: webserver
  remote_user: root
  vars:
    vhosts:
      - web1:
        port: 81
        #name: www.a.com        #将name注释,此时变相没有设定,将不引用
        dir: /data/websitea
      - web2:
        port: 82
        #name: www.b.com
        dir: /data/websiteb
      - web3:
        port: 83
        name: www.c.com
        dir: /data/websitec

  tasks:
    - name: tempate
      template: src=test1.j2 dest=/data/test2.conf

执行剧本

[root@ansible yaml]# ansible-playbook test1.yaml 

PLAY [webserver] ************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************
ok: [192.168.73.135]
ok: [192.168.73.132]
ok: [192.168.73.134]

TASK [tempate] **************************************************************************************************
changed: [192.168.73.132]
changed: [192.168.73.135]
changed: [192.168.73.134]

PLAY RECAP ******************************************************************************************************
192.168.73.132             : ok=2    changed=1    unreachable=0    failed=0   
192.168.73.134             : ok=2    changed=1    unreachable=0    failed=0   
192.168.73.135             : ok=2    changed=1    unreachable=0    failed=0 

验证

[root@ansible yaml]# ansible webserver -a "cat /data/test2.conf"
192.168.73.132 | CHANGED | rc=0 >>
server {
    listen 81
    root /data/websitea
}

server {
    listen 82
    root /data/websiteb
}

server {
    listen 83
    server_name www.c.com
    root /data/websitec
}

ansible的roles
roles用于层次性、结构化地组织playbook。roles能够更具层次结构自动装载变量文件,task以及handlers等。要使用roles只需要在playbook中使用include指令即可,简单来讲,roles就是通过分别将变量、文件、任务、模板以及处理器放置于单独的目录中,并可以便捷地include他们的一种机制。角色一般用于基于主机构建服务的场景中,但也可以时用于构建守护进程等守护场景中。
roles就是按照不同的分类和功能进行目录化,模块化,能够实现代码的符合使用。

roles的目录结构
每个角色都有特定的层级目录结构进行组织
roles目录结构及作用

playbook.yml
roles/            
└──project/           #项目名称
   ├──tasks/          #定义task,role的基本元素,至少包含一个名为main.yml的文件
   ├──files/          #存放由copy或script模块等需要模板文件的目录
   ├──vars/           #定义变量,至少应该包含一个名为main.yml的文件;其它的文件需要在此文件中通过include进行包含
   ├──templates/      #template模块查找所需要模板文件的目录
   ├──handlers/       #至少应该包含一个名为main.yml的文件;其它的文件需要在此文件中通过include进行包含
   ├──default/        #设定默认变量时使用此目录中的main.yml文件(不常用)
   └──meta/           #定义当前角色的特殊设定及其依赖关系,至少应该包含一个名为main.yml的文件,其它文件需在此文件中通过include进行包含(不常用)

role的创建步骤:
1.创建以roles命名的目录
2.在roles目录中分别创建以各角色命名的目录
3.在每个角色命名的目录中分别创建files、handlers、meta、tasks、templates和vars目录;用不到的目录可以创建为空目录,也可以不创建
4.在playbook文件中,调用各角色

示例:
创建httpd的角色
1.创建相应的目录结构

[root@ansible data]# mkdir -pv roles/httpd/{templates,tasks,files,vars,handlers}
mkdir: created directory ‘roles’
mkdir: created directory ‘roles/httpd’
mkdir: created directory ‘roles/httpd/templates’
mkdir: created directory ‘roles/httpd/tasks’
mkdir: created directory ‘roles/httpd/files’
mkdir: created directory ‘roles/httpd/vars’
mkdir: created directory ‘roles/httpd/handlers’

2.创建所需的task

[root@ansible data]# vim roles/httpd/tasks/install.yaml
- name: install httpd
  yum: name=httpd

[root@ansible data]# vim roles/httpd/tasks/config.yaml
- name: config
  copy: src=httpd.conf dest=/etc/httpd.conf

[root@ansible data]# vim roles/httpd/tasks/html.yaml
- name: index.html
  copy: src=index.html dest=/var/www/html

[root@ansible data]# vim roles/httpd/tasks/service.yaml
- name: service start
  service: name=httpd state=started

3.创建task的执行顺序文件

[root@ansible data]# vim roles/httpd/tasks/main.yaml
- include: install.yaml
- include: config.yaml
- include: html.yaml
- include: service.yaml
~                         

4.将所需要用到的配置文件放至file目录下,对配置文件稍做修改

[root@ansible data]# cp /etc/httpd/conf/httpd.conf /data/roles/httpd/files/
[root@ansible data]# vim roles/httpd/files/httpd.conf
Listen 8080

5.在file目录下创建,index.html文件

[root@ansible data]# echo "<h1>welcome to mylinuxops.com</h1>" > roles/httpd/files/index.html

6.创建playbook调用文件。

[root@ansible data]# vim httpd.yaml
---
#install httpd
- hosts: webserver

  roles:
    - role: httpd

7.测试检查

[root@ansible data]# ansible-playbook -C httpd.yaml 

PLAY [webserver] ***********************************************************************************************

TASK [Gathering Facts] *****************************************************************************************
ok: [192.168.73.135]
ok: [192.168.73.134]

TASK [httpd : install httpd] ***********************************************************************************
changed: [192.168.73.134]
changed: [192.168.73.135]

TASK [httpd : config] ******************************************************************************************
changed: [192.168.73.134]
changed: [192.168.73.135]

TASK [httpd : index.html] **************************************************************************************
changed: [192.168.73.134]
changed: [192.168.73.135]

TASK [httpd : service start] ***********************************************************************************
changed: [192.168.73.134]
changed: [192.168.73.135]

PLAY RECAP *****************************************************************************************************
192.168.73.134             : ok=5    changed=4    unreachable=0    failed=0   
192.168.73.135             : ok=5    changed=4    unreachable=0    failed=0  

8.执行playbook

[root@ansible data]# ansible-playbook  httpd.yaml 

PLAY [webserver] ***********************************************************************************************

TASK [Gathering Facts] *****************************************************************************************
ok: [192.168.73.135]
ok: [192.168.73.134]

TASK [httpd : install httpd] ***********************************************************************************
changed: [192.168.73.134]
changed: [192.168.73.135]

TASK [httpd : config] ******************************************************************************************
changed: [192.168.73.134]
changed: [192.168.73.135]

TASK [httpd : index.html] **************************************************************************************
changed: [192.168.73.134]
changed: [192.168.73.135]

TASK [httpd : service start] ***********************************************************************************
changed: [192.168.73.135]
changed: [192.168.73.134]

PLAY RECAP *****************************************************************************************************
192.168.73.134             : ok=5    changed=4    unreachable=0    failed=0   
192.168.73.135             : ok=5    changed=4    unreachable=0    failed=0   

9.验证

[root@ansible data]# curl 192.168.73.134:8080
<h1>welcome to mylinuxops.com</h1>
[root@ansible data]# curl 192.168.73.135:8080
<h1>welcome to mylinuxops.com</h1>

roles中使用template模板
创建Nginx角色
1.创建相应的角色目录

[root@ansible data]# mkdir -pv roles/nginx/{tasks,templates,files,vars,handlers}
mkdir: created directory ‘roles/nginx’
mkdir: created directory ‘roles/nginx/tasks’
mkdir: created directory ‘roles/nginx/templates’
mkdir: created directory ‘roles/nginx/files’
mkdir: created directory ‘roles/nginx/vars’
mkdir: created directory ‘roles/nginx/handlers’

2.将模板文件放入templates目录中,并对模板进行修改

[root@ansible data]# cp /etc/nginx/nginx.conf /data/roles/nginx/templates/nginx.conf.j2
[root@ansible data]# vim /data/roles/nginx/templates/nginx.conf.j2
    server {
        listen       {{port}} default_server;             #此处使用变量代替端口号
        listen       [::]:{{port}} default_server;        #此处使用变量代替端口号

3.在vars目录中创建变量的定义文件

[root@ansible data]# vim /data/roles/nginx/vars/main.yaml
port: 9527

4.在tasks目录下创建各task

[root@ansible data]# vim roles/nginx/tasks/install.yaml
- name: install
  yum: name=nginx

[root@ansible data]# vim roles/nginx/tasks/config.yaml
- name: config
  template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf

[root@ansible data]# vim roles/nginx/tasks/html.yaml
- name: html
  copy: src=roles/httpd/files/index.html dest=/usr/share/nginx/html/index.html

[root@ansible data]# vim roles/nginx/tasks/service.yaml
- name: service
  service: name=nginx state=started

5.在tasks目录下创建执行顺序文件main.yaml

[root@ansible data]# vim roles/nginx/tasks/main.yaml
- include: install.yaml
- include: config.yaml
- include: html.yaml
- include: service.yaml

6.创建roles调用目录

[root@ansible data]# vim nginx.yaml
---
#install nginx
  - hosts: webserver

    roles:
      - role: nginx

7.测试检查

[root@ansible data]# ansible-playbook -C  nginx.yaml
 [WARNING]: Found variable using reserved name: port

PLAY [webserver] ***********************************************************************************************

TASK [Gathering Facts] *****************************************************************************************
ok: [192.168.73.134]
ok: [192.168.73.135]

TASK [nginx : install] *****************************************************************************************
changed: [192.168.73.134]
changed: [192.168.73.135]

TASK [nginx : config] ******************************************************************************************
changed: [192.168.73.134]
changed: [192.168.73.135]

TASK [nginx : html] ********************************************************************************************
changed: [192.168.73.134]
changed: [192.168.73.135]

TASK [nginx : service] *****************************************************************************************
changed: [192.168.73.135]
changed: [192.168.73.134]

PLAY RECAP *****************************************************************************************************
192.168.73.134             : ok=5    changed=4    unreachable=0    failed=0   
192.168.73.135             : ok=5    changed=4    unreachable=0    failed=0   

8.执行playbook

[root@ansible data]# ansible-playbook   nginx.yaml
 [WARNING]: Found variable using reserved name: port

PLAY [webserver] ***********************************************************************************************

TASK [Gathering Facts] *****************************************************************************************
ok: [192.168.73.135]
ok: [192.168.73.134]

TASK [nginx : install] *****************************************************************************************
changed: [192.168.73.135]
changed: [192.168.73.134]

TASK [nginx : config] ******************************************************************************************
changed: [192.168.73.135]
changed: [192.168.73.134]

TASK [nginx : html] ********************************************************************************************
changed: [192.168.73.134]
changed: [192.168.73.135]

TASK [nginx : service] *****************************************************************************************
changed: [192.168.73.135]
changed: [192.168.73.134]

PLAY RECAP *****************************************************************************************************
192.168.73.134             : ok=5    changed=4    unreachable=0    failed=0   
192.168.73.135             : ok=5    changed=4    unreachable=0    failed=0   

9.验证

[root@ansible data]# curl 192.168.73.134:9527
<h1>welcome to mylinuxops.com</h1>
[root@ansible data]# curl 192.168.73.135:9527
<h1>welcome to mylinuxops.com</h1>

在roles中触发hander的使用方法
1.创建在handlers目录下创建handler

[root@ansible data]# vim roles/nginx/handlers/main.yaml
- name: restart service
  service: name=nginx state=restarted

2.在tasks中添加触发条件

[root@ansible data]# vim roles/nginx/tasks/config.yaml 
- name: config
  template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
  notify: restart service

3.对变量稍作修改

[root@ansible data]# vim roles/nginx/vars/main.yaml 
port: 1234

4.检查测试

[root@ansible data]# ansible-playbook -C  nginx.yaml
 [WARNING]: Found variable using reserved name: port

PLAY [webserver] ***********************************************************************************************

TASK [Gathering Facts] *****************************************************************************************
ok: [192.168.73.135]
ok: [192.168.73.134]

TASK [nginx : install] *****************************************************************************************
ok: [192.168.73.134]
ok: [192.168.73.135]

TASK [nginx : config] ******************************************************************************************
changed: [192.168.73.135]
changed: [192.168.73.134]

TASK [nginx : html] ********************************************************************************************
ok: [192.168.73.135]
ok: [192.168.73.134]

TASK [nginx : service] *****************************************************************************************
ok: [192.168.73.135]
ok: [192.168.73.134]

RUNNING HANDLER [nginx : restart service] **********************************************************************
changed: [192.168.73.135]
changed: [192.168.73.134]

PLAY RECAP *****************************************************************************************************
192.168.73.134             : ok=6    changed=2    unreachable=0    failed=0   
192.168.73.135             : ok=6    changed=2    unreachable=0    failed=0   

5.执行playbook

[root@ansible data]# ansible-playbook  nginx.yaml
 [WARNING]: Found variable using reserved name: port

PLAY [webserver] ***********************************************************************************************

TASK [Gathering Facts] *****************************************************************************************
ok: [192.168.73.135]
ok: [192.168.73.134]

TASK [nginx : install] *****************************************************************************************
ok: [192.168.73.135]
ok: [192.168.73.134]

TASK [nginx : config] ******************************************************************************************
changed: [192.168.73.135]
changed: [192.168.73.134]

TASK [nginx : html] ********************************************************************************************
ok: [192.168.73.135]
ok: [192.168.73.134]

TASK [nginx : service] *****************************************************************************************
ok: [192.168.73.134]
ok: [192.168.73.135]

RUNNING HANDLER [nginx : restart service] **********************************************************************
changed: [192.168.73.135]
changed: [192.168.73.134]

PLAY RECAP *****************************************************************************************************
192.168.73.134             : ok=6    changed=2    unreachable=0    failed=0   
192.168.73.135             : ok=6    changed=2    unreachable=0    failed=0   

6.验证

[root@ansible data]# curl 192.168.73.134:1234
<h1>welcome to mylinuxops.com</h1>
[root@ansible data]# curl 192.168.73.135:1234
<h1>welcome to mylinuxops.com</h1>

在role中使用条件判断when
此处以httpd的角色加以修改,将其实现在centos6和centos7上使用不同的配置文件
192.168.73.132为1台centos6主机
1.将httpd2.2的配置文件存放至file目录下

[root@ansible data]# cp ~/httpd6.conf roles/httpd/files/httpd6.conf 

2.在tasks目录下添加centos6的task

[root@ansible data]# vim roles/httpd/tasks/config6.yaml

- name: config6
  copy: src=httpd6.conf dest=/etc/httpd/conf/httpd.conf

3.修改tasks目录下main.yaml的执行次序,加入条件判断

[root@ansible data]# vim roles/httpd/tasks/main.yaml 
- include: install.yaml
- include: config.yaml
  when: ansible_distribution_major_version == "7"
  notify: restart service
- include: config6.yaml
  when: ansible_distribution_major_version == "6"
  notfiy: restart service
- include: html.yaml
- include: service.yaml
~                       

4.在handlers目录下加入handler

[root@ansible data]# vim roles/httpd/handlers/main.yaml
- name: restart service
  service: name=httpd state=restarted

5.检查测试

[root@ansible data]# ansible-playbook -C httpd.yaml 
[DEPRECATION WARNING]: Specifying include variables at the top-level of the task is deprecated. Please see: 
https://docs.ansible.com/ansible/playbooks_roles.html#task-include-files-and-encouraging-reuse   for currently 
supported syntax regarding included files and variables. This feature will be removed in version 2.12. 
Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.

PLAY [webserver] ***********************************************************************************************

TASK [Gathering Facts] *****************************************************************************************
ok: [192.168.73.135]
ok: [192.168.73.132]
ok: [192.168.73.134]

TASK [httpd : install httpd] ***********************************************************************************
ok: [192.168.73.132]
ok: [192.168.73.135]
ok: [192.168.73.134]

TASK [httpd : config] ******************************************************************************************
skipping: [192.168.73.132]
ok: [192.168.73.134]
ok: [192.168.73.135]

TASK [httpd : config6] *****************************************************************************************
skipping: [192.168.73.134]
skipping: [192.168.73.135]
ok: [192.168.73.132]

TASK [httpd : index.html] **************************************************************************************
changed: [192.168.73.132]
ok: [192.168.73.134]
ok: [192.168.73.135]

TASK [httpd : service start] ***********************************************************************************
ok: [192.168.73.132]
ok: [192.168.73.135]
ok: [192.168.73.134]

PLAY RECAP *****************************************************************************************************
192.168.73.132             : ok=5    changed=1    unreachable=0    failed=0   
192.168.73.134             : ok=5    changed=0    unreachable=0    failed=0   
192.168.73.135             : ok=5    changed=0    unreachable=0    failed=0   

6.执行playbook

[root@ansible data]# ansible-playbook  httpd.yaml 
[DEPRECATION WARNING]: Specifying include variables at the top-level of the task is deprecated. Please see: 
https://docs.ansible.com/ansible/playbooks_roles.html#task-include-files-and-encouraging-reuse   for currently 
supported syntax regarding included files and variables. This feature will be removed in version 2.12. 
Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.

PLAY [webserver] ***********************************************************************************************

TASK [Gathering Facts] *****************************************************************************************
ok: [192.168.73.135]
ok: [192.168.73.132]
ok: [192.168.73.134]

TASK [httpd : install httpd] ***********************************************************************************
ok: [192.168.73.132]
ok: [192.168.73.135]
ok: [192.168.73.134]

TASK [httpd : config] ******************************************************************************************
skipping: [192.168.73.132]
ok: [192.168.73.134]
ok: [192.168.73.135]

TASK [httpd : config6] *****************************************************************************************
skipping: [192.168.73.134]
skipping: [192.168.73.135]
ok: [192.168.73.132]

TASK [httpd : index.html] **************************************************************************************
ok: [192.168.73.134]
ok: [192.168.73.135]
changed: [192.168.73.132]

TASK [httpd : service start] ***********************************************************************************
ok: [192.168.73.132]
ok: [192.168.73.134]
ok: [192.168.73.135]

PLAY RECAP *****************************************************************************************************
192.168.73.132             : ok=5    changed=1    unreachable=0    failed=0   
192.168.73.134             : ok=5    changed=0    unreachable=0    failed=0   
192.168.73.135             : ok=5    changed=0    unreachable=0    failed=0   

7.校验

[root@ansible data]# curl 192.168.73.132:9527
<h1>welcome to mylinuxops.com</h1>

也可以将条件判断放在role调用中,实现根据条件来执行不同的role
实现centos7安装nginx,centos6安装http

[root@ansible data]# vim web.yaml
---
#intsall web
- hosts: webserver

  roles:
    - role: nginx
      when: ansible_distribution_major_version == "7"
    - role: httpd
      when: ansible_distribution_major_version == "6"

检查测试

[root@ansible data]# ansible-playbook -C  web.yaml
[DEPRECATION WARNING]: Specifying include variables at the top-level of the task is deprecated. Please see: 
https://docs.ansible.com/ansible/playbooks_roles.html#task-include-files-and-encouraging-reuse   for currently 
supported syntax regarding included files and variables. This feature will be removed in version 2.12. 
Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
 [WARNING]: Found variable using reserved name: port

PLAY [webserver] ***********************************************************************************************

TASK [Gathering Facts] *****************************************************************************************
ok: [192.168.73.135]
ok: [192.168.73.132]
ok: [192.168.73.134]

TASK [nginx : install] *****************************************************************************************
skipping: [192.168.73.132]
changed: [192.168.73.135]
changed: [192.168.73.134]

TASK [nginx : config] ******************************************************************************************
skipping: [192.168.73.132]
changed: [192.168.73.134]
changed: [192.168.73.135]

TASK [nginx : html] ********************************************************************************************
skipping: [192.168.73.132]
changed: [192.168.73.134]
changed: [192.168.73.135]

TASK [nginx : service] *****************************************************************************************
skipping: [192.168.73.132]
changed: [192.168.73.135]
changed: [192.168.73.134]

TASK [httpd : install httpd] ***********************************************************************************
skipping: [192.168.73.134]
skipping: [192.168.73.135]
changed: [192.168.73.132]

TASK [httpd : config] ******************************************************************************************
skipping: [192.168.73.134]
skipping: [192.168.73.135]
skipping: [192.168.73.132]

TASK [httpd : config6] *****************************************************************************************
skipping: [192.168.73.134]
skipping: [192.168.73.135]
changed: [192.168.73.132]

TASK [httpd : index.html] **************************************************************************************
skipping: [192.168.73.134]
skipping: [192.168.73.135]
ok: [192.168.73.132]

TASK [httpd : service start] ***********************************************************************************
skipping: [192.168.73.134]
skipping: [192.168.73.135]
changed: [192.168.73.132]

RUNNING HANDLER [nginx : restart service] **********************************************************************
changed: [192.168.73.134]
changed: [192.168.73.135]

PLAY RECAP *****************************************************************************************************
192.168.73.132             : ok=5    changed=3    unreachable=0    failed=0   
192.168.73.134             : ok=6    changed=5    unreachable=0    failed=0   
192.168.73.135             : ok=6    changed=5    unreachable=0    failed=0   

执行playbook

[root@ansible data]# ansible-playbook  web.yaml
[DEPRECATION WARNING]: Specifying include variables at the top-level of the task is deprecated. Please see: 
https://docs.ansible.com/ansible/playbooks_roles.html#task-include-files-and-encouraging-reuse   for currently 
supported syntax regarding included files and variables. This feature will be removed in version 2.12. 
Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
 [WARNING]: Found variable using reserved name: port

PLAY [webserver] ***********************************************************************************************

TASK [Gathering Facts] *****************************************************************************************
ok: [192.168.73.135]
ok: [192.168.73.132]
ok: [192.168.73.134]

TASK [nginx : install] *****************************************************************************************
skipping: [192.168.73.132]
changed: [192.168.73.134]
changed: [192.168.73.135]

TASK [nginx : config] ******************************************************************************************
skipping: [192.168.73.132]
changed: [192.168.73.135]
changed: [192.168.73.134]

TASK [nginx : html] ********************************************************************************************
skipping: [192.168.73.132]
changed: [192.168.73.134]
changed: [192.168.73.135]

TASK [nginx : service] *****************************************************************************************
skipping: [192.168.73.132]
changed: [192.168.73.134]
changed: [192.168.73.135]

TASK [httpd : install httpd] ***********************************************************************************
skipping: [192.168.73.134]
skipping: [192.168.73.135]
changed: [192.168.73.132]

TASK [httpd : config] ******************************************************************************************
skipping: [192.168.73.134]
skipping: [192.168.73.135]
skipping: [192.168.73.132]

TASK [httpd : config6] *****************************************************************************************
skipping: [192.168.73.134]
skipping: [192.168.73.135]
changed: [192.168.73.132]

TASK [httpd : index.html] **************************************************************************************
skipping: [192.168.73.134]
skipping: [192.168.73.135]
ok: [192.168.73.132]

TASK [httpd : service start] ***********************************************************************************
skipping: [192.168.73.134]
skipping: [192.168.73.135]
changed: [192.168.73.132]

RUNNING HANDLER [nginx : restart service] **********************************************************************
changed: [192.168.73.135]
changed: [192.168.73.134]

PLAY RECAP *****************************************************************************************************
192.168.73.132             : ok=5    changed=3    unreachable=0    failed=0   
192.168.73.134             : ok=6    changed=5    unreachable=0    failed=0   
192.168.73.135             : ok=6    changed=5    unreachable=0    failed=0   

在roles的调用中也可以使用tags标签来实现按需调用

[root@ansible data]# vim web.yaml
---
#intsall web
- hosts: webserver

  roles:
    - role: nginx
      when: ansible_distribution_major_version == "7"
      tags: web1
    - role: httpd
      when: ansible_distribution_major_version == "6"
      tags: web2

练习:
建立memcache角色,将内存的1/4当缓存使用
1.创建角色目录

[root@ansible data]# mkdir -pv roles/memcadhed/{templates,tasks,vars}
mkdir: created directory ‘roles/memcadhed’
mkdir: created directory ‘roles/memcadhed/templates’
mkdir: created directory ‘roles/memcadhed/tasks’
mkdir: created directory ‘roles/memcadhed/vars’

2.安装memeche获取配置文件

[root@ansible data]# yum install memcached -y
[root@ansible data]# cp /etc/sysconfig/memcached roles/memcadhed/templates/memcached.j2

3.修改模板文件

[root@ansible data]# vim roles/memcadhed/templates/memcached.j2
PORT="11211"
USER="memcached"
MAXCONN="1024"
CACHESIZE="{{ansible_memtotal_mb//4}}"  #缓存大小使用系统内置变量
OPTIONS=""

4.在tasks目录下创建各task

[root@ansible data]# vim roles/memcadhed/tasks/install.yaml
- name: install
  yum: name=memcached

[root@ansible data]# vim roles/memcadhed/tasks/config.yaml
- name: config
  template: src=memcached.j2 dest=/etc/sysconfig/memcached

[root@ansible data]# vim roles/memcadhed/tasks/service.yaml
- name: service
  service: name=memcached state=started

5.在tasks目录下创建执行顺序文件

[root@ansible data]# vim roles/memcadhed/tasks/main.yaml

- include: install.yaml
- include: config.yaml
- include: service.yaml

6.创建调用role文件

[root@ansible data]# vim memcached.yaml
---
# install memcached
- hosts: webserver

  roles:
    - role: memcached

7.测试

[root@ansible data]# ansible-playbook -C memcached.yaml 

PLAY [webserver] ***********************************************************************************************

TASK [Gathering Facts] *****************************************************************************************
ok: [192.168.73.132]
ok: [192.168.73.134]
ok: [192.168.73.135]

TASK [memcached : install] *************************************************************************************
changed: [192.168.73.132]
changed: [192.168.73.135]
changed: [192.168.73.134]

TASK [memcached : config] **************************************************************************************
changed: [192.168.73.132]
changed: [192.168.73.134]
changed: [192.168.73.135]

TASK [memcached : service] *************************************************************************************
changed: [192.168.73.132]
changed: [192.168.73.134]
changed: [192.168.73.135]

PLAY RECAP *****************************************************************************************************
192.168.73.132             : ok=4    changed=3    unreachable=0    failed=0   
192.168.73.134             : ok=4    changed=3    unreachable=0    failed=0   
192.168.73.135             : ok=4    changed=3    unreachable=0    failed=0   

执行roles

[root@ansible data]# ansible-playbook memcached.yaml 

PLAY [webserver] ***********************************************************************************************

TASK [Gathering Facts] *****************************************************************************************
ok: [192.168.73.132]
ok: [192.168.73.134]
ok: [192.168.73.135]

TASK [memcached : install] *************************************************************************************
changed: [192.168.73.135]
changed: [192.168.73.134]
changed: [192.168.73.132]

TASK [memcached : config] **************************************************************************************
changed: [192.168.73.132]
changed: [192.168.73.135]
changed: [192.168.73.134]

TASK [memcached : service] *************************************************************************************
changed: [192.168.73.132]
changed: [192.168.73.135]
changed: [192.168.73.134]

PLAY RECAP *****************************************************************************************************
192.168.73.132             : ok=4    changed=3    unreachable=0    failed=0   
192.168.73.134             : ok=4    changed=3    unreachable=0    failed=0   
192.168.73.135             : ok=4    changed=3    unreachable=0    failed=0   

练习:
使用ansible在centos6主机上部署ntp服务,centos7上部署chrony
1.分别创建ntp和chrony角色目录

[root@ansible data]# mkdir -pv roles/{ntpd,chrony}/{templates,tasks,vars,files,handlers}
mkdir: created directory ‘roles/ntpd’
mkdir: created directory ‘roles/ntpd/templates’
mkdir: created directory ‘roles/ntpd/tasks’
mkdir: created directory ‘roles/ntpd/vars’
mkdir: created directory ‘roles/ntpd/files’
mkdir: created directory ‘roles/ntpd/handlers’
mkdir: created directory ‘roles/chrony’
mkdir: created directory ‘roles/chrony/templates’
mkdir: created directory ‘roles/chrony/tasks’
mkdir: created directory ‘roles/chrony/vars’
mkdir: created directory ‘roles/chrony/files’
mkdir: created directory ‘roles/chrony/handlers’

2.准备ntpd配置文件
2.1对ntp配置文件修改

[root@CentOS6 ~]# vim /etc/ntp.conf 
restrict default kod nomodify
restrict 192.168.73.0 mask 255.255.255.0 nomodify notrap
server 172.22.0.1 iburst

2.2将ntp配置文件存放至role相关目录下

[root@ansible data]# mv ntp.conf roles/ntpd/files/

3.准备chrony配置文件
3.1修改配置文件

[root@ansible data]# vim /etc/chrony.conf 
server 192.168.73.132 iburst

3.2将chrony配置文件存放至role相关目录下

[root@ansible data]# cp /etc/chrony.conf roles/chrony/files/

4.创建ntpd的tasks

[root@ansible data]# vim roles/ntpd/tasks/install.yaml
- name: install
  yum: name=ntp

[root@ansible data]# vim roles/ntpd/tasks/config.yaml
- name: config
  copy: src=ntp.conf dest=/etc/ntp.conf
  notify: restart service

[root@ansible data]# vim roles/ntpd/tasks/service.yaml
- name: service
  service: name=ntpd state=started

[root@ansible data]# vim roles/ntpd/tasks/main.yaml
- include: install.yaml
- include: config.yaml
- include: service.yaml

5.创建ntpd的handler

[root@ansible data]# vim roles/ntpd/handlers/main.yaml
- name: restart service
  service: name=ntpd state=restarted

6.创建chrony的tasks

[root@ansible data]# vim roles/chrony/tasks/install.yaml
- name: install
  yum: name=chrony

  [root@ansible data]# vim roles/chrony/tasks/config.yaml
- name: config
  copy: src=chrony.conf dest=/etc/chrony.conf
  notify: restart service

[root@ansible data]# vim roles/chrony/tasks/service.yaml
- name: service
  service: name=chronyd state=started

[root@ansible data]# vim roles/chrony/tasks/main.yaml
- include: install.yaml
- include: config.yaml
- include: service.yaml

7.创建chrony的handler

[root@ansible data]# vim roles/chrony/handlers/main.yaml
- name: restart service
  service: name=chronyd state=restarted

8.创建带条件判断的role调用剧本

[root@ansible data]# vim roles_time.yaml

---
#install ntp chorny
- hosts: webserver
  roles:
    - role: ntpd
      when: ansible_distribution_major_version == "6"
    - role: chrony
      when: ansible_distribution_major_version == "7"

9.测试

[root@ansible data]# ansible-playbook -C roles_time.yaml 

PLAY [webserver] ***********************************************************************************************

TASK [Gathering Facts] *****************************************************************************************
ok: [192.168.73.132]
ok: [192.168.73.135]
ok: [192.168.73.134]

TASK [ntpd : install] ******************************************************************************************
skipping: [192.168.73.134]
skipping: [192.168.73.135]
ok: [192.168.73.132]

TASK [ntpd : config] *******************************************************************************************
skipping: [192.168.73.134]
skipping: [192.168.73.135]
ok: [192.168.73.132]

TASK [ntpd : service] ******************************************************************************************
skipping: [192.168.73.134]
skipping: [192.168.73.135]
changed: [192.168.73.132]

TASK [chrony : install] ****************************************************************************************
skipping: [192.168.73.132]
changed: [192.168.73.134]
changed: [192.168.73.135]

TASK [chrony : config] *****************************************************************************************
skipping: [192.168.73.132]
changed: [192.168.73.135]
changed: [192.168.73.134]

TASK [chrony : service] ****************************************************************************************
skipping: [192.168.73.132]
changed: [192.168.73.135]
changed: [192.168.73.134]

RUNNING HANDLER [ntpd : restart service] ***********************************************************************
skipping: [192.168.73.135]
skipping: [192.168.73.134]

PLAY RECAP *****************************************************************************************************
192.168.73.132             : ok=4    changed=1    unreachable=0    failed=0   
192.168.73.134             : ok=4    changed=3    unreachable=0    failed=0   
192.168.73.135             : ok=4    changed=3    unreachable=0    failed=0   

10.执行

[root@ansible data]# ansible-playbook  roles_time.yaml 

PLAY [webserver] ***********************************************************************************************

TASK [Gathering Facts] *****************************************************************************************
ok: [192.168.73.135]
ok: [192.168.73.132]
ok: [192.168.73.134]

TASK [ntpd : install] ******************************************************************************************
skipping: [192.168.73.134]
skipping: [192.168.73.135]
ok: [192.168.73.132]

TASK [ntpd : config] *******************************************************************************************
skipping: [192.168.73.134]
skipping: [192.168.73.135]
ok: [192.168.73.132]

TASK [ntpd : service] ******************************************************************************************
skipping: [192.168.73.134]
skipping: [192.168.73.135]
ok: [192.168.73.132]

TASK [chrony : install] ****************************************************************************************
skipping: [192.168.73.132]
ok: [192.168.73.135]
ok: [192.168.73.134]

TASK [chrony : config] *****************************************************************************************
skipping: [192.168.73.132]
ok: [192.168.73.135]
ok: [192.168.73.134]

TASK [chrony : service] ****************************************************************************************
skipping: [192.168.73.132]
ok: [192.168.73.134]
changed: [192.168.73.135]

PLAY RECAP *****************************************************************************************************
192.168.73.132             : ok=4    changed=0    unreachable=0    failed=0   
192.168.73.134             : ok=4    changed=0    unreachable=0    failed=0   
192.168.73.135             : ok=4    changed=1    unreachable=0    failed=0   

转载于:https://blog.51cto.com/11886307/2385720

相关文章:

  • LeetCode每日一题: 移除元素(No.27)
  • 秒杀系统流量削峰这事儿应该怎么做?
  • jenkins测试配置
  • 20189317 《网络攻防技术》 第十周作业
  • SpringBoot RabbitMQ 集成 二 Work queues
  • 75条笑死人的知乎神回复,用60行代码就爬完了
  • Windows server 2012 利用ntdsutil工具实现AD角色转移及删除域控方法
  • Linux学习
  • 面试官:说说双亲委派模型?
  • 北京
  • yocto添加层简介
  • 渐变文件夹,一定要收下这两套超级精美的文件夹图标!
  • 博客
  • 学习python的第一天-模拟用户登录接口,输入错误三次锁定
  • 如何测量距离?ABViewer热门技术问答精选合集!
  • android图片蒙层
  • codis proxy处理流程
  • Consul Config 使用Git做版本控制的实现
  • FastReport在线报表设计器工作原理
  • Iterator 和 for...of 循环
  • JAVA SE 6 GC调优笔记
  • JS学习笔记——闭包
  • laravel5.5 视图共享数据
  • October CMS - 快速入门 9 Images And Galleries
  • PaddlePaddle-GitHub的正确打开姿势
  • 看域名解析域名安全对SEO的影响
  • 力扣(LeetCode)21
  • 鱼骨图 - 如何绘制?
  • 再谈express与koa的对比
  • 最近的计划
  • 看到一个关于网页设计的文章分享过来!大家看看!
  • 阿里云重庆大学大数据训练营落地分享
  • 关于Kubernetes Dashboard漏洞CVE-2018-18264的修复公告
  • ​一、什么是射频识别?二、射频识别系统组成及工作原理三、射频识别系统分类四、RFID与物联网​
  • # 再次尝试 连接失败_无线WiFi无法连接到网络怎么办【解决方法】
  • #QT项目实战(天气预报)
  • (第9篇)大数据的的超级应用——数据挖掘-推荐系统
  • (二) Windows 下 Sublime Text 3 安装离线插件 Anaconda
  • (二)【Jmeter】专栏实战项目靶场drupal部署
  • (学习日记)2024.01.09
  • (一)VirtualBox安装增强功能
  • .NET/C# 使用反射调用含 ref 或 out 参数的方法
  • .NET使用HttpClient以multipart/form-data形式post上传文件及其相关参数
  • .NET是什么
  • @Conditional注解详解
  • [ C++ ] STL_list 使用及其模拟实现
  • [2019/05/17]解决springboot测试List接口时JSON传参异常
  • [2021ICPC济南 L] Strange Series (Bell 数 多项式exp)
  • [2024最新教程]地表最强AGI:Claude 3注册账号/登录账号/访问方法,小白教程包教包会
  • [Angular 基础] - 指令(directives)
  • [BZOJ1877][SDOI2009]晨跑[最大流+费用流]
  • [BZOJ3211]:花神游历各国(小清新线段树)
  • [BZOJ4016][FJOI2014]最短路径树问题
  • [c++] 什么是平凡类型,标准布局类型,POD类型,聚合体
  • [C++进阶篇]STL中vector的使用