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. HDU 4643 GSM 算术几何

    当火车处在换基站的临界点时,它到某两基站的距离相等.因此换基站的位置一定在某两个基站的中垂线上, 我们预处理出任意两基站之间的中垂线,对于每次询问,求询问线段与所有中垂线的交点. 检验这些交点是否满足 ...

  2. Android之开发杂记(一)

    1.cygwin环境变量设置 可在Cygwin.bat 中设置 set NDK_ROOT=P:/android/android-ndk-r8e 或者在home\Administrator\.bash_ ...

  3. C# 读取指定URL的内容

    #region 读取指定URL的内容 /// <summary> /// 读取指定URL的内容 /// </summary> /// <param name=" ...

  4. echo "hello" | nc -4t -w1 localhost 8001

    TCP4: echo "hello" | nc -4t -w1 localhost 8001 UDP4: echo "hello" | nc -4u -w1 l ...

  5. Android gingerbread eMMC booting

    Android gingerbread eMMC booting This page is currently under construction. The content of this page ...

  6. Java 基础-反射

    反射-Reflect 测试用到的代码 1.接口 Person.java public interface Person { Boolean isMale = true; void say(); voi ...

  7. 好,开始没做出来 guess-number-higher-or-lower-ii

    https://leetcode.com/mockinterview/session/result/xsicjnm/ https://leetcode.com/problems/guess-numbe ...

  8. Android实现分享内容到微信朋友圈

    原文地址:http://yanwushu.sinaapp.com/android_wechat_share/ 由于需求,要实现在应用中实现分享文字+图片到微信朋友圈.在网上找了一些资料,总结如下: 思 ...

  9. Android activity 周期图

  10. Codeforces 435 B Pasha Maximizes【贪心】

    题意:给出一串数字,给出k次交换,每次交换只能交换相邻的两个数,问最多经过k次交换,能够得到的最大的一串数字 从第一个数字往后找k个位置,找出最大的,往前面交换 有思路,可是没有写出代码来---sad ...