果冻想
认真玩技术的地方

Ansible Playbook中的循环

Ansible是一个系列文章,我会尽量以通俗易懂、诙谐幽默的总结方式给大家呈现这些枯燥的知识点,让学习变的有趣一些。
Ansible系列博文直达链接:Ansible入门系列

前言

接上回《Ansible Playbook中的条件控制》咱继续说。循环是每门语言必不可少的特性,在Ansible中,循环的玩法更是多,但是莫怕,我们常用的循环就那么几类,下面我们就对我们常用的几种Ansible循环展开一番总结。

本文中涉及的试验环境信息如下:

服务器信息如下:
192.168.5.2 # 管理主机
192.168.5.3 # 被管理远程主机
192.168.5.4 # 被管理远程主机

inventory文件内容如下:
[web]
192.168.5.3
192.168.5.4

标准循环

标准循环是指使用with_items来迭代list类型变量,不仅支持简单的字符串列表,还支持哈希列表。下面通过两个简单的例子进行说明。

---
- hosts: web
  gather_facts: False
  tasks: 
    - name: loops demo
      debug: msg="Echo loops item {{item}}"
      with_items:
        - message1
        - message2

上面的代码会将with_items中的内容依次代入debug中进行输出,上述代码的输出内容如下:

ok: [192.168.5.3] => (item=message1) => {
    "msg": "Echo loops item message1"
}
ok: [192.168.5.3] => (item=message2) => {
    "msg": "Echo loops item message2"
}
ok: [192.168.5.4] => (item=message1) => {
    "msg": "Echo loops item message1"
}
ok: [192.168.5.4] => (item=message2) => {
    "msg": "Echo loops item message2"
}

对于哈希列表同样也是可以的,比如这样子:

---

- hosts: web
  gather_facts: False
  tasks:
    - name: loops demo
      debug: msg="name={{item.name}}, age={{item.age}}"
      with_items:
        - {name: "Yanggd", age: "27"}
        - {name: "Yanglx", age: "5"}

对于这段代码,输出是这个样子的:

ok: [192.168.5.3] => (item={u'age': u'27', u'name': u'Yanggd'}) => {
    "msg": "name=Yanggd, age=27"
}
ok: [192.168.5.3] => (item={u'age': u'5', u'name': u'Yanglx'}) => {
    "msg": "name=Yanglx, age=5"
}
ok: [192.168.5.4] => (item={u'age': u'27', u'name': u'Yanggd'}) => {
    "msg": "name=Yanggd, age=27"
}
ok: [192.168.5.4] => (item={u'age': u'5', u'name': u'Yanglx'}) => {
    "msg": "name=Yanglx, age=5"
}

如果同时使用whenwith_items(或其它循环声明),那么when声明会为每次循环都单独判断依次。

嵌套循环

嵌套循环就是循环里套循环,在我们用Java或者其它语言时,在Ansible中使用with_nested进行的演义,那这个嵌套循环怎么玩呢?通过一个简单的例子来演示一下,一看就懂了。

---

- hosts: "192.168.5.3"
  gather_facts: False
  tasks:
    - name: loop and loop
      debug: msg="outside loop {{item[0]}}, inside loop {{item[1]}}"
      with_nested: 
        - ['A', 'B']
        - [1, 2, 3]

由于输出会很多,所以这里只用了一台远程服务器进行演示。如果一眼看不明白,把输出结果贴上,就可以更清楚了:

ok: [192.168.5.3] => (item=[u'A', 1]) => {
    "msg": "outside loop A, inside loop 1"
}
ok: [192.168.5.3] => (item=[u'A', 2]) => {
    "msg": "outside loop A, inside loop 2"
}
ok: [192.168.5.3] => (item=[u'A', 3]) => {
    "msg": "outside loop A, inside loop 3"
}
ok: [192.168.5.3] => (item=[u'B', 1]) => {
    "msg": "outside loop B, inside loop 1"
}
ok: [192.168.5.3] => (item=[u'B', 2]) => {
    "msg": "outside loop B, inside loop 2"
}
ok: [192.168.5.3] => (item=[u'B', 3]) => {
    "msg": "outside loop B, inside loop 3"
}

对哈希表使用循环

相比于上面的标准循环,哈希表循环能支持更丰富的数据结构。通过上面的总结,我们知道,标准的循环最外层数据必须是Python的list数据类型,而哈希表循环可以直接支持yaml格式的数据变量。来个小小的例子解读一下:

---

- hosts: "192.168.5.3"
  gather_facts: False
  vars:
    website:
      www.jellythink.com:
        author: Yanggd
        type: IT
      www.qq.com:
        author: Pony
        type: General
  tasks:
    - name: loops demo
      debug: msg="website name:{{item.key}}, author is {{item.value.author}}, type is {{item.value.type}}"
      with_dict: "{{website}}"

通过with_dict来玩转这个哈希表循环,上面代码的输出如下所示:

ok: [192.168.5.3] => (item={'value': {u'type': u'General', u'author': u'Pony'}, 'key': u'www.qq.com'}) => {
    "msg": "website name:www.qq.com, author is Pony, type is General"
}
ok: [192.168.5.3] => (item={'value': {u'type': u'IT', u'author': u'Yanggd'}, 'key': u'www.jellythink.com'}) => {
    "msg": "website name:www.jellythink.com, author is Yanggd, type is IT"
}

有没有品出什么???

对文件列表使用循环

有些时候,我们需要针对某一目录下指定格式的文件进行处理,这个时候使用with_fileglob循环去匹配我们需要处理的文件就非常方便了。比如这样子:

---

- hosts: "192.168.5.3"
  gather_facts: False
  tasks:
    - name: file loops
      debug: msg="file name is {{item}}"
      with_fileglob:
        - /etc/*.conf

with_fileglob会匹配etc目录下所有以conf结尾的文件,当做item变量。输出内容有点多,这里就不展示了。

总结

呵呵,这么简单的一个循环,总结了这么长的一篇文章,不要怪我,我的文章就是这么实在,没有一点点水分,少了一些干瘪的文字,多了一些实际的代码,希望你喜欢这样的文章。如果觉的还不错,可以点击下方的“打赏”哦,又或扫描右边的二维码,关注一波也是不错的。

哎,中午又喝了酒,抽了烟,糟蹋了自己的身体;但人生不就是这样么~~~

果冻想,认真玩技术的地方。

2020年5月17日,于内蒙古呼和浩特。

赞(3) 打赏
未经允许不得转载:果冻想 » Ansible Playbook中的循环
分享到: 更多 (0)

评论 2

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
  1. #-49

    with_fileglob只匹配本机的文件,补充一下,折腾了半天…

    ptrees3周前 (11-13)回复

玩技术,我们是认真的

联系我们关于果冻

感谢支持果冻想

支付宝扫一扫打赏

微信扫一扫打赏