一、Ansible介绍
Ansible 简单的说是一个配置管理系统(configuration management system)。你只需要可以使用 ssh 访问你的服务器或设备就行。它也不同于其他工具,因为它使用推送的方式,而不是像 puppet 等 那样使用拉取安装agent的方式。你可以将代码部署到任意数量的服务器上!
1.1、Ansible能做什么
ansible可以帮助我们完成一些批量任务,或者完成一些需要经常重复的工作。
比如:同时在100台服务器上安装nginx服务,并在安装后启动它们。
比如:将某个文件一次性拷贝到100台服务器上。
比如:每当有新服务器加入工作环境时,你都要为新服务器部署某个服务,也就是说你需要经常重复的完成相同的工作。
这些场景中我们都可以使用到ansible。
1.2、Ansible特性
模块化:调用特定的模块,完成特定任务
有Paramiko,PyYAML,Jinja2(模板语言)三个关键模块
支持自定义模块
基于Python语言实现
部署简单,基于python和SSH(默认已安装),agentless
安全,基于OpenSSH
支持playbook编排任务
幂等性:一个任务执行1遍和执行n遍效果一样,不因重复执行带来意外情况
无需代理不依赖PKI(无需ssl)
可使用任何编程语言写模块
YAML格式,编排任务,支持丰富的数据结构
较强大的多层解决方案
1.3、Ansible架构
clip_image0026
Ansible核心组件说明:
Ansible:Ansible的核心程序
Host Lnventory:记录了每一个由Ansible管理的主机信息,信息包括ssh端口,root帐号密码,ip地址等等。可以通过file来加载,可以通过CMDB加载
Playbooks:YAML格式文件,多个任务定义在一个文件中,使用时可以统一调用,“剧本”用来定义那些主机需要调用那些模块来完成的功能.
Core Modules:Ansible执行任何管理任务都不是由Ansible自己完成,而是由核心模块完成;Ansible管理主机之前,先调用core Modules中的模块,然后指明管理Host Lnventory中的主机,就可以完成管理主机。
Custom Modules:自定义模块,完成Ansible核心模块无法完成的功能,此模块支持任何语言编写。
Connection Plugins:连接插件,Ansible和Host通信使用
二、配置elep源
2.1、RHEL/Centos6
2.2、RHEL/Centos7
三、安装ansible
补充、用户密码、密钥登录
补充1、用户密码登录
1.1、安装ssh_pass包
Ubuntu安装方式 apt-get install sshpass
Centos 安装方式 yum install sshpass
1.2、ansible配置文件修改
ansible.cfg配置文件修改
##资产信息列表文件
inventory = /etc/ansible/hosts
##允许并发的数量为5个并发,也就是可以可以同时进行5个任务
forks = 5
##默认为root用户执行
sudo_user = root
##默认端口为22端口
remote_port = 22
##取消注释以禁用SSH密钥主机检查
host_key_checking = False
##超时时间
timeout = 10
##日志存放时间
log_path = /var/log/ansible.log
##私钥的目录
#private_key_file = /path/to/file
hosts资产信息列表文件修改
[aliyun]
106.14.220.53 ansible_ssh_user=root ansible_ssh_pass=‘XUchangming1993285’
1.3、测试登录
106.14.220.53 | SUCCESS | rc=0 >>
ansible.cfg
ansible.cfg.bak
hosts
hosts.bak
roles
[root@iZuf6e15robw9amyc9qt1lZ ansible]#
补充2、密钥登录
2.1、生成并配置ssh公钥、私钥
公钥文件为公钥id_rsa.pub,私钥文件为id_rsa
clip_image0046
使用ssh-copy-id IP命令把公钥发送到指定主机
clip_image0066
测试使用ssh登录远程主机看是否能登录
clip_image0086
2.2、配置ansible的hosts资产列表文件
hosts资产信息列表文件修改
[aliyun]
106.14.220.53 ansible_ssh_user=root ansible_ssh_key_file=/root/.ssh/id_rsa
四、ansible命令
4.1查看ansible帮助文档
4.2、格式选项
ansible [options]
options选项:
选项
注释
实例
-u
登录远程主机用户名,默认为root (可省略)
-i
指定用户清单,对那些清单进行操作,默认为(/etc/ansible/hosts)文件中的主机 (可省略)
-m
指定模块的名称
-a
指定模块的参数,具体执行的指令
-k
提示输入远程主机的密码
-C
只是测试一下会改变什么内容,不会真正去执行;相反,试图预测一些可能发生的变化
–list-hosts
输出匹配主机的列表
ansible all --list-hosts
–version
显示程序版本号
-v
输出执行的详细信息,使用-vvv获得更多,-vvvv 启用连接调试
五、添加远程主机
添加远程主机的配置文件为/etc/ansible/hosts文件。
添加一个组名称为aliyun,添加阿里云服务器IP,如下:
[aliyun]
106.14.220.53
六、第一个列子
SSH password:
106.14.220.53 | SUCCESS | rc=0 >>
backup.sh
www
xuchangming.txt
七、ansible常用模块
7.1、使用ansible-doc –l查看本身自带的模块
7.2、setup模块
Setup模块主要用卡查看远程主机的一些基本信息
clip_image0106
7.3、ping模块
主要用于ping主机是否能ping通网络,如果主机在线则返回pong
clip_image0126
7.4、file文件模块
file模块主要用于远程主机上的文件操作,file模块包含如下选项:
– force:需要在两种情况下强制创建软链接,一种是源文件不存在但之后会建立的情况下;另一种是目标软链接已存在,需要先取消之前的软链,然后创建新的软链,有两个选项:yes|no
– group:定义文件/目录的属组
– mode:定义文件/目录的权限
– owner:定义文件/目录的属主
– path:必选项,定义文件/目录的路径
– recurse:递归的设置文件的属性,只对目录有效
– src:要被链接的源文件的路径,只应用于state=link的情况
– dest:被链接到的路径,只应用于state=link的情况
– state:
directory:如果目录不存在,创建目录
file:即使文件不存在,也不会被创建
link:创建软链接
hard:创建硬链接
touch:如果文件不存在,则会创建一个新的文件,如果文件或目录已存在,则更新其最后修改时间
absent:删除目录、文件或者取消链接文件
7.4.1、创建软连接
clip_image0146
7.4.2、删除文件
clip_image0166
7.4.3、创建文件
clip_image0186
7.4.4、创建目录
7.4.4.1、创建默认权限,默认属组属主的目录
clip_image0206
7.4.4.2、创建权限为777,属组属主为root的目录
clip_image0226
7.5、copy复制模块
复制文件到远程主机,copy模块包含如下选项:
· backup:在覆盖之前将原文件备份,备份文件包含时间信息。有两个选项:yes|no
· content:用于替代"src",可以直接设定指定文件的值
· dest:必选项。要将源文件复制到的远程主机的绝对路径,如果源文件是一个目录,那么该路径也必须是个目录
· directory_mode:递归的设定目录的权限,默认为系统默认权限
· -group:定义文件/目录的属组
– mode:定义文件/目录的权限
– owner:定义文件/目录的属主
· force:如果目标主机包含该文件,但内容不同,如果设置为yes,则强制覆盖,如果为no,则只有当目标主机的目标位置不存在该文件时,才复制。默认为yes
· others:所有的file模块里的选项都可以在这里使用
· src:要复制到远程主机的文件在本地的地址,可以是绝对路径,也可以是相对路径。如果路径是一个目录,它将递归复制。在这种情况下,如果路径使用"/“来结尾,则只复制目录里的内容,如果没有使用”/"来结尾,则包含目录在内的整个内容全部复制,类似于rsync。
· validate :The validation command to run before copying into place. The path to the file to validate is passed in via ‘%s’ which must be present as in the visudo example below.
· clip_image0246
7.5.1、复制文件
clip_image0266
7.5.2、复制文件并修改属组属主和权限
clip_image0286
7.5.3、复制相同文件时,覆盖时并备份
目标主机的源文件
clip_image0306
当前主机更改后的源文件
clip_image0326
通过Ansible复制文件到目标主机
clip_image0346
查看目标主机的文件目录和复制后的文件及备份后的文件内容
clip_image0366clip_image0386
7.6、command命令模块
功能:命令模块,默认模块,用于在远程主机执行命令,缺点:运行的命令中无法使用变量,管道。变量和操作符号 “<”, “>”, “|”, “;” and “&” 不能正常工作。如果需要使用,请使用 shell 模块。省略不写模块信息名称则默认为command模块
action: command
chdir # 在执行命令之前,先切换到该目录
creates # 一个文件名,当这个文件存在,则该命令不执行
executable # 切换shell来执行命令,该执行路径必须是一个绝对路径
free_form= #要执行的Linux指令,一般使用Ansible的-a参数代替。
removes #一个文件名,这个文件不存在,则该命令不执行
7.6.1、creates使用,当文件存在则该命令不执行,不存在则执行
clip_image0406
7.6.2、chdir在执行命令之前,先切换到该目录
ansible aliyun -k -m command -a ‘ls /mnt/zhang’
ansible -k aliyun -m command -a ‘chdir=/mnt/zhang/ ls’
以上两条命令是等价的,第一条是通过绝对路径进行查询,第二条命令是先进入目录在进行查询相当于cd /mnt/zhang 和 ls两条命令的结合体
clip_image0426
7.7、shell模块
功能:在远程节点上执行命令。
与command模快使用一致,但是,变量 和操作符号 “<”, “>”, “|”, “;” and “&” 能正常工作。示例:
ansible test -m shell -a “somescript.sh >> somelog.txt”
我这里使用通配符,使用command模块是不行的。
10.0.0.4 | FAILED | rc=2 >>
ls: cannot access /usr/local/tomcat0[1-3]: No such file or directorynon-zero return code
10.0.0.9 | FAILED | rc=2 >>
ls: cannot access /usr/local/tomcat0[1-3]: No such file or directorynon-zero return code
改成shell模块就可以。
10.0.0.4 | SUCCESS | rc=0 >>
/usr/local/tomcat01
/usr/local/tomcat02
/usr/local/tomcat03
10.0.0.9 | SUCCESS | rc=0 >>
/usr/local/tomcat01
/usr/local/tomcat02
/usr/local/tomcat03
7.8、service管理服务模块
用于管理服务
该模块包含如下选项:
· arguments:给命令行提供一些选项
· name:必选项,服务名称
· state:对当前服务执行启动,停止、重启、重新加载等操作(started,stopped,restarted,reloaded)
· sleep:如果执行了restarted,在则stop和start之间沉睡几秒钟
· enabled:是否开机启动 yes|no
· pattern:定义一个模式,如果通过status指令来查看服务的状态时,没有响应,就会通过ps指令在进程中根据该模式进行查找,如果匹配到,则认为该服务依然在运行
· runlevel:运行级别
7.8.1、启动vsftpd
clip_image0446
7.8.2、停止vsftpd
clip_image0466
7.9、cron计划任务模块
用于管理计划任务
包含如下选项:
backup:对远程主机上的原任务计划内容修改之前做备份
cron_file:如果指定该选项,则用该文件替换远程主机上的cron.d目录下的用户的任务计划
day:日(1-31,*,*/2,……)
hour:小时(0-23,*,*/2,……)
minute:分钟(0-59,*,*/2,……)
month:月(1-12,*,*/2,……)
weekday:周(0-7,*,……)
job:要执行的任务,依赖于state=present
name:该任务的描述
special_time:指定什么时候执行,参数:reboot,yearly,annually,monthly,weekly,daily,hourly
state:确认该任务计划是创建还是删除。默认为创建,删除为state=absent
user:以哪个用户的身份执行
7.9.1、添加计划任务
添加计划任务每天的2点执行ls命令,注释为ls /mnt
clip_image0486
查看计划任务
[root@iZuf6e15robw9amyc9qt1lZ zhang]# ansible -k aliyun -m command -a ‘crontab -l’
clip_image0506
7.9.2、删除计划任务
clip_image0526
查看是否被删掉了
clip_image0546
8.0、filesystem模块
在块设备上创建文件系统
选项:
dev:目标块设备
force:在一个已有文件系统的设备上强制创建
fstype:文件系统的类型
opts:传递给mkfs命令的选项
8.1、yum模块
使用yum包管理器来管理软件包
选项:
config_file:yum的配置文件
disable_gpg_check:关闭gpg_check
disablerepo:不启用某个源
enablerepo:启用某个源
list
name:要进行操作的软件包的名字,也可以传递一个url或者一个本地的rpm包的路径
state:状态(absent, installed, latest, present, removed)
8.1.1、yum安装软件
clip_image0566
8.1.2、使用yum安装软件包组
8.1.3、安装网络rpm包
8.2、user用户管理模块
管理用户
createhome: 是否创建家目录
home: 家目录
groups: 组
uid: uid
password: 登录密码
name: 用户名称
system:
remove: 配合state=absent使用,删除用户的家目录->remove=yes
state: present创建,absent删除
shell: 用户的shell设定
需要特别说明的是,password后面指定的密码不能是明文,后面这一串密码会被直接传送到被管理主机的/etc/shadow文件中,而登陆的时候输入的密码会被hash加密以后再去与/etc/shadow中存放的密码去做对比,会出现不一致的现象。所以需要先将密码字符串进行加密处理:openssl passwd -salt -1 “123456”,然后将得到的字符串放到password中即可。
8.2.1、创建用户
clip_image0586
clip_image0606
8.2.2、删除用户
8.3、synchronize同步文件模块
使用sync同步文件
src: 源,同步的数据源
dest=: 目标地址
dest_port: 目标接受的端口,ansible配置文件中的ansible_ssh_port变量优先级高于该dest_port变量
group: 文件属组
owner: 文件属主
mode:(push, pull): 模式,rsync同步的方式PUSH / PULL,默认都是推送push,如果你在使用拉取pull功能的时候,可以参考如下来实现mode=pull更改推送模式为拉取模式
dirs: 以非递归的方式传输目录,默认为no,即进行目录递归
archive: 是否采用归档模式同步,即以源文件相同属性同步到目标地址
checksum: 是否校验
compress: 开启压缩,默认为开启
copy_links: 同步的时候是否复制连接
delete: 删除源中没有而目标存在的文件(即以推送方为主)
existing_only: skip createing new files on receiver
links
recursive: 是否递归yes / no
rsync_path: 服务的路径,指定rsync命令在远程服务器上运行。这个参考rsync命令的—sync-path参数,–rsync-path=PATH指定远程服务器上rsync命令所在的路径信息
times: 保持时间属性
8.3.1、同步文件
clip_image0646
8.3.2、同步目录
clip_image0666
8.4、mount分区挂载模块
配置挂载点
选项:
dump
fstype:必选项,挂载文件的类型
name:必选项,挂载点
opts:传递给mount命令的参数
passno
src:必选项,要挂载的文件
state:必选项
present:只处理fstab中的配置
absent:删除挂载点
mounted:自动创建挂载点并挂载之
umounted:卸载
示例:
name=/mnt/dvd src=/dev/sr0 fstype=iso9660 opts=ro state=present
name=/srv/disk src='LABEL=SOME_LABEL' state=present
name=/home src='UUID=b3e48f45-f933-4c8e-a700-22a159ec9077' opts=noatime state=present
ansible test -a 'dd if=/dev/zero of=/disk.img bs=4k count=1024'
ansible test -a 'losetup /dev/loop0 /disk.img'
ansible test -m filesystem 'fstype=ext4 force=yes opts=-F dev=/dev/loop0'
ansible test -m mount 'name=/mnt src=/dev/loop0 fstype=ext4 state=mounted opts=rw'
8.5、get_url下载模块
get_url模块主要用于下载,类似于 shell 命令 curl 或者 wget
参数
必填
默认值
注解
url
yes
url地址
dest
no
下载存放的路径
8.5.1、下载网络rpm包并保存在/opt目录下
clip_image0686
八、Playbook
8.1、Playbooks 简介
Playbooks 与 adhoc 相比,是一种完全不同的运用 ansible 的方式,是非常之强大的.
简单来说,playbooks 是一种简单的配置管理系统与多机器部署系统的基础.与现有的其他系统有不同之处,且非常适合于复杂应用的部署.
Playbooks 可用于声明配置,更强大的地方在于,在 playbooks 中可以编排有序的执行过程,甚至于做到在多组机器间,来回有序的执行特别指定的步骤.并且可以同步或异步的发起任务.
我们使用 adhoc 时,主要是使用 /usr/bin/ansible 程序执行任务.而使用 playbooks 时,更多是将之放入源码控制之中,用之推送你的配置或是用于确认你的远程系统的配置是否符合配置规范.
clip_image0706
8.2、playbook的组成
Paly:定义的是主机的角色
Task:定义的是具体执行的任务
Playboot:由一个或多个play组成,一个play可以包含多个task
clip_image0726
8.3、playbook的优势
1、功能比abhoc更全
2、控制依赖关系比较好
3、展现更直观
4、持久使用
8.4、playbook的配置语法
8.4.1、基本使用
1、playbook基础使用
Playbook的语法格式:ansible-playbook [options] playbook.yml [playbook2 …]
Options参数:
l -u REMOTE_USER, --user=REMOTE_USER # ssh 连接的用户名
l -k, --ask-pass #ssh登录认证密码
l -s, --sudo #sudo 到root用户,相当于Linux系统下的sudo命令
l -U SUDO_USER, --sudo-user=SUDO_USER #sudo 到对应的用户
l -K, --ask-sudo-pass #用户的密码(—sudo时使用)
l -T TIMEOUT, --timeout=TIMEOUT # ssh 连接超时,默认 10 秒
l -C, --check # 指定该参数后,执行 playbook 文件不会真正去执行,而是模拟执行一遍,然后输出本次执行会对远程主机造成的修改
l -e EXTRA_VARS, --extra-vars=EXTRA_VARS # 设置额外的变量如:key=value 形式 或者 YAML or JSON,以空格分隔变量,或用多个-e
l -f FORKS, --forks=FORKS # 进程并发处理,默认 5
l -i INVENTORY, --inventory-file=INVENTORY # 指定 hosts 文件路径,默认 default=/etc/ansible/hosts
l -l SUBSET, --limit=SUBSET #指定一个 pattern,对- hosts:匹配到的主机再过滤一次
l --list-hosts #只打印有哪些主机会执行这个 playbook 文件,不是实际执行该 playbook
l --list-tasks #列出该 playbook 中会被执行的 task
l --private-key=PRIVATE_KEY_FILE # 私钥路径
l --step # 同一时间只执行一个 task,每个 task 执行前都会提示确认一遍
l --syntax-check # 只检测 playbook 文件语法是否有问题,不会执行该 playbook
l -t TAGS, --tags=TAGS #当 play 和 task 的 tag 为该参数指定的值时才执行,多个 tag 以逗号分隔
l --skip-tags=SKIP_TAGS #当 play 和 task 的 tag 不匹配该参数指定的值时,才执行
l -v, --verbose #输出更详细的执行过程信息,-vvv可得到所有执行过程信息。
2、使用场景
Ø Playbook的配置
演示列子:
[root@iZuf6e15robw9amyc9qt1lZ ansible]# cat ce.yml
remote_user: root
vars:
touch_file: zhang.file
tasks:
date
by hostname
>/tmp/hello.logshell: "touch /opt/{{touch_file}}"clip_image0746
功能为:在192.168.1.101主机上在tmp目录下创建一个imoocc.file文件
Ø Playbook命令的执行
Ø 执行结果返回
clip_image0765
#ansible-playbook -i /etc/ansible/hosts --list-hosts ./f1.yml结果为:
clip_image0785
clip_image0805
8.4.2、yaml语法和变量
8.4.2.1、yaml语法
1、yaml语法注意项
l 大小写敏感
l 使用缩进表示层级关系(只能使用空格不能使用tab)
l yaml文件以“- - -”作为文档的开始
2、支持的数据结构
数据结构可以为字典,列表,纯量三种
字典 列表 纯量:数字、布尔、字符串
{name:jeson} -Aple
-Orange
-strawberry
-Mango
3、yaml变量的应用
myname:jeson
name:“{{myname}}”
8.4.2.2、playbook变量
变量的定义
l playbook的yaml文件中定义变量赋值
列子:
使用# ansible-playbook ./ce.yml命令执行即可
clip_image0815
l --extra-vars执行参数付给变量
使用–extra-vars参数进行赋值变量
列子:
clip_image0835
clip_image0855
l 在文件中定义变量
文件中定义变量是指在hosts资产列表文件中添加变量
clip_image0875
l 注册变量
register关键字可以存储指定命令的输出结果到一个自定义的变量中
-name:get time
command:date
register:date_output
clip_image0895
8.4.3、基本语句
实例请查看本文后面的《playbook基本语句实例》
1、条件语句
when语句
列子:
clip_image0915
2、循环语句
循环类型
关键字
标准循环
with_items
嵌套循环
with_nested
遍历字典
with_dict
并行遍历列表
with_together
遍历列表和索引
with_indexed_items
遍历文件列表的内容
with_file
遍历目录文件
with_fileglob
重试循环
until
查找第一个匹配文件
with_first_found
随机选择
with_random_choice
在序列中循环
with_sequence
3、条件循环语句复用
8.4.4、异常处理和相关操作
1、异常处理
Ø 忽略错误
默认会检查命令和模块的返回状态,遇到错误就中断playbook的执行
加入参数:ignore_errors:yes 进行忽略错误
例子:
说明:/bin/false返回状态为1,即错误信息,touch文件命令正常工作
clip_image0935
执行命令之后报错
clip_image0955
添加忽略错误信息并执行clip_image0975
clip_image0995
Ø 自定义错误
Ø 自定义change状态
例子:
不添加changed标签的状态
clip_image1015
clip_image1035
添加运行changed标签的结果
clip_image1055 clip_image1075
2、tags标签处理
意义:通过tags和任务对象进行捆绑,控制部分或者指定的task执行
Ø 打标签
对一个对象打一个标签
对一个对象打多个标签
打标签的对象包括:单个task任务、include对象、roles对象等
例子:
clip_image1095
Ø 标签的使用
-t:执行指定的tag标签任务
–skip-tags:执行—skip-tags之外的标签任务
例子:
只执行cfile1标签,执行结果如下
clip_image1115
只执行除了cfile1之外的标签,结果如下
clip_image1135
8.4.5、roles角色和场景演练
1、使用roles
a) 、include的用法
include_tasks/include:动态的包含tasks任务列表执行clip_image1155
实例:
添加touchf1.yml文件
clip_image1175
添加touchf2.yml文件
clip_image1195
添加include文件
clip_image1215
执行结果即可
b) 、为什么需要使用到roles
c) 、官方建议的剧本结构
d) 、剧本涉及的思路
2、场景演练
错误解决
1、在第一次使用时,报下面错误
[root@localhost ~]# ansible -k aliyun -m command -a ‘ls’
SSH password:
192.168.1.101 | FAILED | rc=-1 >>
Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this. Please add this host’s fingerprint to your known_hosts file to manage this host.
[root@localhost ~]#
解决方法:使用ssh 手动连接下就可以
playbook基本语句实例
种类一、标准循环
添加多个用户
user: name={{ item }} state=present groups=wheel
with_items:
testuser1
testuser2
添加多个用户,并将用户加入不同的组内。
user: name={{ item.name }} state=present groups={{ item.groups }}
with_items:
{ name: ‘testuser1’, groups: ‘wheel’ }
{ name: ‘testuser2’, groups: ‘root’ }
种类二、锚点嵌套循环
分别给用户授予3个数据库的所有权限
mysql_user: name={{ item[0] }} priv={{ item[1] }}.*:ALL append_privs=yes password=foo
with_nested:
[ ‘alice’, ‘bob’ ]
[ ‘clientdb’, ‘employeedb’, ‘providerdb’ ]
种类三、锚点遍历字典
输出用户的姓名和电话
tasks:
debug: msg=“User {{ item.key }} is {{ item.value.name }} ({{ item.value.telephone }})”
with_dict: {‘alice’:{‘name’:‘Alice Appleworth’, ‘telephone’:‘123-456-789’},‘bob’:{‘name’:‘Bob Bananarama’, ‘telephone’:‘987-654-3210’} }
种类四、锚点并行遍历列表
tasks:
with_together:
[ ‘a’, ‘b’, ‘c’, ‘d’,‘e’ ]
[ 1, 2, 3, 4 ]
如果列表数目不匹配,用None补全
种类五、锚点遍历列表和索引
debug: “msg=‘at array position {{ item.0 }} there is a value {{ item.1 }}’”
with_indexed_items: [1,2,3,4]
item.0 为索引,item.1为值
种类六、锚点遍历文件列表的内容
tasks:
with_file:
first_example_file
second_example_file
种类七、锚点遍历目录文件
with_fileglob匹配单个目录中的所有文件,非递归匹配模式。
tasks:
file: dest=/etc/fooapp state=directory
copy: src={{ item }} dest=/etc/fooapp/ owner=root mode=600
with_fileglob:
当在role中使用with_fileglob的相对路径时,Ansible解析相对于roles//files目录的路径。
种类八、锚点遍历ini文件
lookup.ini
[section1]
value1=section1/value1
value2=section1/value2
[section2]
value1=section2/value1
value2=section2/value2
with_ini: value[1-2] section=section1 file=lookup.ini re=true
获取section1 里的value1和value2的值
种类九、锚点重试循环 until
register: result
until: result.stdout.find(“all systems go”) != -1
retries: 5
delay: 10
“重试次数retries” 的默认值为3,"delay"为5。
锚点查找第一个匹配文件
tasks:
with_first_found:
“/tmp/a”
“/tmp/b”
“/tmp/default.conf”
依次寻找列表中的文件,找到就返回。如果列表中的文件都找不到,任务会报错。
种类十、锚点随机选择with_random_choice
随机选择列表中得一个值
with_random_choice:
“go through the door”
“drink from the goblet”
“press the red button”
“do nothing”
循环程序的结果
tasks:
· debug: “msg={{ item }}”
with_lines: ps aux
种类十一、锚点循环子元素
定义好变量
#varfile
users:
authorized:
/tmp/alice/onekey.pub
/tmp/alice/twokey.pub
mysql:
password: mysql-password
hosts:
“%”
“127.0.0.1”
“::1”
“localhost”
privs:
“.:SELECT”
“DB1.*:ALL”
name: bob
authorized:
mysql:
password: other-mysql-password
hosts:
privs:
“.:SELECT”
“DB2.*:ALL”
vars_files: varfile
tasks:
with_items: “{{ users }}”
with_subelements:
“{{ users }}”
authorized
name: Setup MySQL users
mysql_user: name={{ item.0.name }} password={{ item.0.mysql.password }} host={{ item.1 }} priv={{ item.0.mysql.privs | join(’/’) }}
with_subelements:
“{{ users }}”
mysql.hosts
{{ lookup(‘file’, item.1) }} 是查看item.1文件的内容
with_subelements 遍历哈希列表,然后遍历列表中的给定(嵌套)的键。
种类十二、锚点在序列中循环with_sequence
with_sequence以递增的数字顺序生成项序列。 您可以指定开始,结束和可选步骤值。 参数应在key = value对中指定。 'format’是一个printf风格字符串。
数字值可以以十进制,十六进制(0x3f8)或八进制(0600)指定。 不支持负数。
tasks:
group: name=evens state=present
group: name=odds state=present
with_sequence: start=0 end=32 format=testuser%02x
with_sequence: start=4 end=16 stride=2
with_sequence: count=4
种类十三、锚点随机选择with_random_choice
随机选择列表中得一个值
with_random_choice:
“go through the door”
“drink from the goblet”
“press the red button”
“do nothing”
合并列表
安装所有列表中的软件
yum: name={{ item }} state=installed
with_flattened:
[ ‘foo-package’, ‘bar-package’ ]
[ [‘one-package’, ‘two-package’ ]]
[ [‘red-package’], [‘blue-package’]]
注册变量使用循环
with_items:
one
two
register: echo
fail:
msg: “The command ({{ item.cmd }}) did not have a 0 return code”
when: item.rc != 0
with_items: “{{ echo.results }}”
循环主机清单
输出所有主机清单里的主机
with_items: “{{ groups[‘all’] }}”
输出所有执行的主机
with_items: play_hosts
输出所有主机清单里的主机
· debug: msg={{ item }}
with_inventory_hostnames: all
输出主机清单中不在www中的所有主机
· debug: msg={{ item }}
with_inventory_hostnames: all:!www
改变循环的变量项
with_items:
1
2
3
loop_control:
loop_var: outer_item
with_items:
a
b
c