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. nodpad++正则替换

    则表达式是一个查询的字符串,它包含一般的字符和一些特殊的字符,特殊字符可以扩展查找字符串的能力,正则表达式在查找和替换字符串的作用不可忽视,它 能很好提高工作效率. EditPlus的查找,替换,文件 ...

  2. 日期工具类 - DateUtil.java

    日期工具类,提供对日期的格式化和转换方法.获取区间日期.指定日期.每月最后一天等. 源码如下:(点击下载 -DateUtil.java.commons-lang-2.6.jar ) import ja ...

  3. make clean vs make clobber

    make is pretty smart, and picks up what has changed from the last build, so if you run repo sync and ...

  4. 二、理解over()函数

    1.1.两个order by的执行时机分析函数是在整个sql查询结束后(sql语句中的order by的执行比较特殊)再进行的操作, 也就是说sql语句中的order by也会影响分析函数的执行结果: ...

  5. SQL注入与Java

    前面这篇文章介绍了SQL注入,并且主要就PHP的内容做了实验: http://www.cnblogs.com/charlesblc/p/5987951.html 还有这篇文章对处理方案做了介绍(Pre ...

  6. 瞎折腾之 Lucene.Net + MVC 搜索功能(上)

    前言 首先,关于Lucene.Net 的文章已经很多了.我这次决定写出来只是为了练练手,虽然在别人看来没什么用,但是自己确实是手动实践了一把.我个人觉得还是有意义的.爱折腾.敢于实践.才能有所收获,才 ...

  7. HDU 1513 Palindrome

    题目就是给一个字符串问最少插入多少个字符能让原字符串变为回文字符串. 算法: 用原串的长度减去原串与翻转后的串的最大公共字串的长度,就是所求答案. //#define LOCAL #include & ...

  8. PhpStorm 获取注册码

    另一种方法是:直接用浏览器打开 http://idea.lanyus.com/ ,点击页面中的“获得注册码”,然后在注册时切换至Activation Code选项,输入获得的注册码一长串字符串,便可以 ...

  9. poj 1465 Multiple(bfs+余数判重)

    题意:给出m个数字,要求组合成能够被n整除的最小十进制数. 分析:用到了余数判重,在这里我详细的解释了.其它就没有什么了. #include<cstdio> #include<cma ...

  10. HDU 5319 Painter (模拟)

    题意: 一个画家画出一张,有3种颜色的笔,R.G.B.R看成'\',B看成'/',G看成这两种的重叠(即叉形).给的是一个矩阵,矩阵中只有4种符号,除了3种颜色还有'.',代表没有涂色.问最小耗费多少 ...