Ansible的循环

1、       前言

有可能在一个任务中,可能要做很多事情,例如创建多个用户,安装很多个包等,那么就有可能用到循环。

2、       标准循环

重复的任务可以用下面的方式:

- name: add several users

user: name={{ item }} state=present groups=wheel

with_items:

- testuser1

- testuser2

如果你定义了一个变量文件创建了一个YAML的列表,或者是在var节中,那么可以使用以下的方式:

with_items:"{{somelist}}"

上面的和下面的表示为相同的含义,如下:

-name:add user testuser1
user:name=testuser1 state=present groups=wheel
-name:add user testuser2
user:name=testuser2 state=present groups=wheel

Yum和apt模块在使用with_items的时候,可以减少包管理事务。

在遍历的各项中,可以不是简单的列表,如果是hash列表的时候,你可以使用子健,如下:

-name:add several users
user:name={{ item.name }} state=present groups={{ item.groups }}
with_items:
-{name:'testuser1',groups:'wheel'}
-{name:'testuser2',groups:'root'}

3、       嵌套循环

嵌套循环如下所示:

-name:give users access to multiple databases
mysql_user:name={{ item[0] }} priv={{ item[1] }}.*:ALL append_privs=yes password=foo
with_nested:
-['alice','bob']
-['clientdb','employeedb','providerdb']

在上面的with_items中,也可以使用以前定义的变量,如下所示:

-name:here, 'users' contains the above list of employees
mysql_user:name={{ item[0] }} priv={{ item[1] }}.*:ALL append_privs=yes password=foo
with_nested:
-"{{users}}"
-['clientdb','employeedb','providerdb']

4、       遍历hash

假设存在以下变量:

---
users:
alice:
name:Alice Appleworth
telephone:123-456-7890
bob:
name:Bob Bananarama
telephone:987-654-3210

你要打印每个用户的名称和手机号码,那么可以用循环的关键字“with_dict”,如下:

tasks:
-name:Print phone records
debug:msg="User {{ item.key }} is {{ item.value.name }} ({{ item.value.telephone }})"
with_dict:"{{users}}"

5、       遍历文件

“with_file”迭代建立在一系列文件的内容之上,item将被设置为序列中每个文件的内容,如下所示:

---
-hosts:all
 
tasks:
 
# emit a debug message containing the content of each file.
-debug:
msg:"{{item}}"
with_file:
-first_example_file
-second_example_file

假设first_example_file包含语句“hello”并且second_example_file包含文本“world”,那么如下所示:

TASK [debug msg={{item}}] ******************************************************
ok: [localhost] => (item=hello) => {
    "item": "hello",
    "msg": "hello"
}
ok: [localhost] => (item=world) => {
    "item": "world",
    "msg": "world"
}

6、       遍历文件夹(fileglobs)

with_fileglob对应于单一目录下的所有文件,不递归的匹配模式,如下:

---
-hosts:all
 
tasks:
 
# first ensure our target directory exists
-file:dest=/etc/fooapp state=directory
 
# copy each file over that matches the given pattern
-copy:src={{ item }} dest=/etc/fooapp/ owner=root mode=600
with_fileglob:
-/playbooks/files/fooapp/*

注意:当在role里使用with_fileglob的时候,ansible会将路径解析为

roles/<rolename>/files 路径

7、       遍历数据的并行集

假设存在以下的变量:

---
alpha:['a','b','c','d']
numbers:[1,2,3,4]

并且你想将结果合并为(a,1),(b,2)的样子,那么使用关键字with_together,如下:

tasks:
-debug:msg="{{ item.0 }} and {{ item.1 }}"
with_together:
-"{{alpha}}"
-"{{numbers}}"

8、       遍历子元素

假设你想遍历一个用户列表,创建他们,并且用特定的ssh key来进行登录,假设存在以下的变量内容:

---
users:
-name:alice
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:
-/tmp/bob/id_rsa.pub
mysql:
password:other-mysql-password
hosts:
-"db1"
privs:
-"*.*:SELECT"
-"DB2.*:ALL"

那么将会像如下所示:

-user:name={{ item.name }} state=present generate_ssh_key=yes
with_items:"{{users}}"
 
-authorized_key:"user={{item.0.name}}key='{{lookup('file',item.1)}}'"
with_subelements:
-users
-authorized

给出mysql的主机并且提供ssh密钥的列表,那么将可以遍历一个嵌套的子健:

-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

子元素会沿着哈希表遍历并且给出ssh密钥在记录之内

9、       遍历整数系列

with_sequence生成项目数字的序列,也可以指定开始,结束,或者一个步长值。

参数也可以指定为key=value的格式,如果提供了,那么会格式化为printf的类型字符串。

数字值可以指定为2进制,10进制,16进制,负数不支持,如下:

---
-hosts:all
 
tasks:
 
# create groups
-group:name=evens state=present
-group:name=odds state=present
 
# create some test users
-user:name={{ item }} state=present groups=evens
with_sequence:start=0 end=32 format=testuser%02x
 
# create a series of directories with even numbers for some reason
-file:dest=/var/stuff/{{ item }} state=directory
with_sequence:start=4 end=16 stride=2
 
# a simpler way to use the sequence plugin
# create 4 groups
-group:name=group{{ item }} state=present
with_sequence:count=4

10、  随机选择

random_choice表示为随机的选择,但是不是一个负载均衡,在有的程度上相当于负载均衡,如下:

-debug:msg={{ item }}
with_random_choice:
-"gothroughthedoor"
-"drinkfromthegoblet"
-"presstheredbutton"
-"donothing"

提供的字符串将会有一个被随机选中。

11、  Do-until循环

有的时候会去尝试一个任务在特定的条件下,如下:

-action:shell /usr/bin/foo
register:result
until:result.stdout.find("all systems go") != -1
retries:5
delay:10

在默认情况下,retries值为3,delay为5秒,在查看的时候,可以使用-vv的选项来查看变量的值

12、  找到第一个匹配的文件

这不是一个循环,但是很接近。当你在引用一个文件的时候,取决于上一个文件的内容或者是名称,那么可以如下:

-name:INTERFACES | Create Ansible header for /etc/network/interfaces
template:src={{ item }} dest=/etc/foo.conf
with_first_found:
-"{{ansible_virtualization_type}}_foo.conf"
-"default_foo.conf"

也有一个长形的版本,从而允许配置搜索的路径:

-name:some configuration template
template:src={{ item }} dest=/etc/file.cfg mode=0444 owner=root group=root
with_first_found:
-files:
-"{{inventory_hostname}}/etc/file.cfg"
paths:
-../../../templates.overwrites
-../../../templates
-files:
-etc/file.cfg
paths:
-templates

13、  迭代程序执行的结果

在有的时候,需要遍历执行的结果,需要注意的是,这是在远程机器上执行的,而不是在本机器上执行的,如下:

-name:Example of looping over a command result
shell:/usr/bin/frobnicate {{ item }}
with_lines:/usr/bin/frobnications_per_host --param {{ inventory_hostname }}

当需要远程执行命令的时候,那么可以像以下方法做:

-name:Example of looping over a REMOTE command result
shell:/usr/bin/something
register:command_result
 
-name:Do something with each result
shell:/usr/bin/something_else --param {{ item }}
with_items:"{{command_result.stdout_lines}}"

14、  在ini文件中遍历

可以遍历以下集合,如下:

[section1]
value1=section1/value1
value2=section1/value2
 
[section2]
value1=section2/value1
value2=section2/value2

如下演示使用with_ini:

-debug:msg="{{item}}"
with_ini:value[1-2] section=section1 file=lookup.ini re=true

返回值如下所示:

{
"changed":false,
"msg":"Allitemscompleted",
"results":[
{
"invocation":{
"module_args":"msg=\"section1/value1\"",
"module_name":"debug"
},
"item":"section1/value1",
"msg":"section1/value1",
"verbose_always":true
},
{
"invocation":{
"module_args":"msg=\"section1/value2\"",
"module_name":"debug"
},
"item":"section1/value2",
"msg":"section1/value2",
"verbose_always":true
}
]
}

15、  在循环中使用register

当使用register来存储变量的时候,那么保存的是一个列表,整个属性为results

如下:

-shell:echo "{{ item }}"
with_items:
-one
-two
register:echo

当使用register而不使用循环的时候返回值如下:

{
"changed":true,
"msg":"Allitemscompleted",
"results":[
{
"changed":true,
"cmd":"echo\"one\"",
"delta":"0:00:00.003110",
"end":"2013-12-1912:00:05.187153",
"invocation":{
"module_args":"echo\"one\"",
"module_name":"shell"
},
"item":"one",
"rc":0,
"start":"2013-12-1912:00:05.184043",
"stderr":"",
"stdout":"one"
},
{
"changed":true,
"cmd":"echo\"two\"",
"delta":"0:00:00.002920",
"end":"2013-12-1912:00:05.245502",
"invocation":{
"module_args":"echo\"two\"",
"module_name":"shell"
},
"item":"two",
"rc":0,
"start":"2013-12-1912:00:05.242582",
"stderr":"",
"stdout":"two"
}
]
}

使用循环并使用register的结果如下:

-name:Fail if return code is not 0
fail:
msg:"Thecommand({{item.cmd}})didnothavea0returncode"
when:item.rc != 0
with_items:"{{echo.results}}"

16、  在inventory中使用循环

当你想在inventory中进行遍历,或者是一个子集,那么可以如下所示:

# show all the hosts in the inventory
-debug:msg={{ item }}
with_items:"{{groups['all']}}"
 
# show all the hosts in the current play
-debug:msg={{ item }}
with_items:play_hosts

而且可以使用插件inventory_hostname:

# show all the hosts in the inventory
-debug:msg={{ item }}
with_inventory_hostname:all
 
# show all the hosts matching the pattern, ie all but the group www
-debug:msg={{ item }}
with_inventory_hostname:all:!www

17、  在include中使用循环

在include中使用循环如下:

(注意:在included的任务中含有自己的with_loop值,会覆盖掉特定的item的值,如果既要使用include的item又要使用当前任务的item,必须使用set_fact去创建一个别名)

-include:test.yml
with_items:
-1
-2
-3

在test.yml中:

-set_fact:outer_loop="{{item}}"
 
-debug:msg="outer item={{outer_loop}} inner item={{item}}"
with_items:
-a
-b
-c

Ansible的循环的更多相关文章

  1. Ansible Playbook 循环

    Standard Loops 为了节省一些打字,重复的任务可以写成如下: - name: add several users user: name: "{{ item }}" st ...

  2. Ansible playbook循环实践总结<一>

    1.标准Loops 标准loops可以直接减少task的次数,如下: [root@zero01 playbook]# vi loops.yaml --- - hosts: all gather_fac ...

  3. ansible基础-playbooks

    1. playbooks介绍 如果说ansible的modules是工具,inventory配置文件是原材料,那么playbook就是一封说明书,这里会记录任务是如何如何执行的,当然如果你愿意,这里也 ...

  4. ansible 自动化管理

    1 什么样的情形需要批量部署 1.操作系统的安装 常见的有collber,red hat satelite(redhat)系统专用. 2.操作系统的配置 常见的有cfengine,puppet,che ...

  5. ansible运维工具(二)

    ansible playbook(二) 运行palybook时 要使用ansible-playbook命令 palybook执行任务的顺序是,在第一个主机上完成第一个任务,然后在第二个主机上完成第一个 ...

  6. Ansible之playbook的使用总结 - 运维笔记

    之前详细介绍了Ansible的安装, 配置, 以及Ansible常用模块的使用. 下面对Ansible的playbook用法做一小结. 为什么引入playbook?一般运维人员完成一个任务, 比如安装 ...

  7. 3、Ansible playbooks(Hosts、Users、tasks、handlers、变量、条件测试(when、迭代)、templates)

    Ansible playbooks playbook是由一个或多个“play”组成的列表.play的主要功能在于将事先归并为一组的主机装扮成事先通过ansible中的task定义好的角色.从根本上来讲 ...

  8. Linux运维之Ansible自动化运维管理工具

    Ansible简介:Ansible是一个简单高效的自动化运维管理工具,用Python开发,能大批量管理N多台机器,可以并发的在多台机器上部署应用.安装软件.执行命令.配置和编排任务.后面会提到批量安装 ...

  9. Ansible自动化部署入门到进阶笔记

    目录 一.基本部署 安装Ansible Ansible配置文件 定义Inventory 使用秘钥方式连接 使用帮助 Ansible命令应用基础 二.常见模块 三.Ansible playbook 四. ...

随机推荐

  1. ubuntu12.10升级至14.04

    之前执行apt-get 不管是什么软件或apt-get update都会遇到fail to fetch http://us.archive.ubuntu.com quantal-updates/mai ...

  2. 《Linux内核设计与实现》读书笔记(七)- 中断处理【转】

    转自:http://www.cnblogs.com/wang_yb/archive/2013/04/19/3030345.html 中断处理一般不是纯软件来实现的,需要硬件的支持.通过对中断的学习有助 ...

  3. 安装 jdk、tomcat

    jdk 下载地址:http://www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloads-java ...

  4. 深入浅出:Linux设备驱动之字符设备驱

    一.linux系统将设备分为3类:字符设备.块设备.网络设备.使用驱动程序: 字符设备:是指只能一个字节一个字节读写的设备,不能随机读取设备内存中的某一数据,读取数据需要按照先后数据.字符设备是面向流 ...

  5. hibernate.cfg.xml文件的说明

    <?xml version='1.0' encoding='UTF-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hi ...

  6. Linux同步机制(一) - 线程锁

    1 互斥锁 在线程实际运行过程中,我们经常需要多个线程保持同步. 这时可以用互斥锁来完成任务.互斥锁的使用过程中,主要有 pthread_mutex_init pthread_mutex_destor ...

  7. 1038: [ZJOI2008]瞭望塔

    半平面交. 半平面指的就是一条直线的左面(也不知道对不对) 半平面交就是指很多半平面的公共部分. 这道题的解一定在各条直线的半平面交中. 而且瞭望塔只可能在各个点或者半平面交折线的拐点处. 求出半平面 ...

  8. LA 3177 长城守卫

    n为偶数的时候比较简单,就是相邻两个守卫的礼物和的最大值. 首先这是个下限,其次这个值也满足题目要求,所以这就是答案了. 当n为奇数的时候上限是守卫索要礼物的最大值的三倍. 这也很容易理解,比如n=5 ...

  9. 安卓WebView中接口隐患与手机挂马利用(远程命令执行)

    安卓应用存在安全漏洞,浏览网站打开链接即可中招.目前有白帽子提交漏洞表明目前安卓平台上的应用普遍存在一个安全漏洞,用户打开一个链接就可导致远程安装恶意应用甚至完全控制用户手机,目前微信,手机QQ,QV ...

  10. openerp学习笔记 context 的应用

    1.在Action中定义,context用于传递搜索条件和分组条件,在搜索视图中默认显示: 示例代码: <record model="ir.actions.act_window&quo ...