ansible 中的循环(一)---with-items

1.ansible 中循环的介绍

在使用ansible的过程中,我们经常需要处理一些返回信息,而这些返回信息中,通常可能不是单独的一条返回信息,而是一个信息列表,如果我们想要循环的处理信息列表中的每一条信息,我们该怎么办呢?这样空口白话的描述有些费力,不如通过一些小示例,结合场景来描述。

假设,我的清单配置如下

172.25.1.1
testB.westos.com ansible_host=172.25.1.2
testC.redhat.com ansible_host=172.25.1.3

[testA]
test1 ansible_host=172.25.1.1
test2 ansible_host=172.25.1.2

[testB]
test3 ansible_host=172.25.1.3

[test:children]
testA
testB

如果我想要获取到清单中所有未分组的主机的主机名,则可以执行如下命令

[root@server4 ~]# ansible testB -m debug -a "msg={{groups.ungrouped}}"

在这里插入图片描述
从返回信息可以看出,一共有3个未分组主机,上例的返回信息中就不只有一条信息记录,如果我们想要获取到上述返回信息中的第二条信息,则可以使用如下方法

[root@server4 ~]# ansible testB -m debug -a "msg={{groups.ungrouped[1]}}"

在这里插入图片描述
但是问题是,我们通常不能确定返回信息有几条,我们可能需要循环的处理返回信息中的每一条信息,那么怎么才能循环处理返回信息中的每一条信息呢?示例playbook如下

[root@server4 ~]# vim xh1.yml
[root@server4 ~]# cat xh1.yml 
---
- hosts: testB
  remote_user: root
  gather_facts: no
  tasks:
  - debug:
      msg: "{{item}}"
    with_items: "{{groups.ungrouped}}"

上例中,我们通过”{{groups.ungrouped}}”获取到了未分组的返回信息,并使用关键字”with_items”接收了返回信息,然后使用debug模块输出了名为”item”变量的变量值,”with_items”关键字会把返回的列表信息自动处理,将每一条信息单独放在一个名为”item”的变量中,我们只要获取到名为”item”变量的变量值,即可循环的获取到列表中的每一条信息,所以,上例中返回信息中的每一条信息都会循环的被debug模块处理,执行上述playbook后结果如下

[root@server4 script]# ansible-playbook xh1.yml 

在这里插入图片描述
从执行playbook的结果可以看出,debug模块对每条信息都单独输出了一次,而不是三条信息同时一次输出,由于对应play是针对testB主机操作的,所以上例中debug模块的三次操作都是在testB主机上进行的,只不过debug模块只是输出信息,并不会对testB主机做出什么实际的改动而已,通过上述方法,就能够符合我们循环操作的要求了。

上例中,我们使用的是返回值中的信息,那么我们能不能自定义一个列表,然后循环使用列表中的值呢?必须能的,示例如下

[root@server4 ~]# vim xh2.yml 
[root@server4 ~]# cat xh2.yml 
---
- hosts: testB
  remote_user: root
  gather_facts: no
  tasks:
  - debug:
      msg: "{{item}}"
    with_items:
    - 1
    - 2
    - 3

如上例所示,我们自定义了3个值,分别是1、2、3,debug模块会循环的输出这三个值:

[root@server4 ~]# ansible-playbook xh2.yml 

在这里插入图片描述
或者我们换一种写法,如下写法与上述写法的效果完全相同。

[root@server4 ~]# vim xh2.yml 
[root@server4 ~]# cat xh2.yml 
---
- hosts: testB
  remote_user: root
  gather_facts: no
  tasks:
  - debug:
      msg: "{{item}}"
    with_items: [ 1, 2, 3 ]
[root@server4 ~]# ansible-playbook xh3.yml 

我们还能够自定义稍微复杂些的列表,示例如下

[root@server4 ~]# vim xh3.yml 
[root@server4 ~]# cat xh3.yml 
---
- hosts: testB
  remote_user: root
  gather_facts: no
  tasks:
  - debug:
      msg: "{{item.test1}}"
    with_items:
    - { test1: a,test2: b }
    - { test1: c,test2: d }

上例中自定义列表中的每一个条目都是一个对象,我们可以通过对象的属性对应的”键”,获取到对应的”值”,如上例所示,第一个条目的test1键对应的值是a,第二个条目的test1键对应的值是c,所以执行上例playbook以后,”a”和”c”会被输出:
在这里插入图片描述
学会使用循环,能够让我们事半功倍。

比如,在没有学会使用循环之前,如果想要在同一主机中创建四个文件,那么你可能会编写如下playbook

[root@server4 ~]# vim xh4.yml
[root@server4 ~]# cat xh4.yml 
--
- hosts: testB
  remote_user: root
  gather_facts: no
  tasks:
  - file:
      path: "/opt/a"
      state: touch
  - file:
      path: "/opt/b"
      state: touch
  - file:
      path: "/opt/c"
      state: touch
  - file:
      path: "/opt/d"
      state: touch

我们重复的书写了file模块4次,其实每次只是改变了file模块的path参数的值而已,如果使用循环,上例的playbook则可以改写成如下

[root@server4 ~]# vim xh4.yml 
[root@server4 ~]# cat xh4.yml 
---
- hosts: testB
  remote_user: root
  gather_facts: no
  tasks:
  - file:
      path: "{{item}}"
      state: touch
    with_items: [ /opt/a, /opt/b, /opt/c, /opt/d ]

在这里插入图片描述
正如上述示例所示,重复的操作越多,使用循环则越方便。

2.

那么我们再来看一个小示例,这个示例与循环没有直接关系,但是可以引出我们要说的话题,示例playbook如下:

[root@server4 ~]# vim xh6.yml
[root@server4 ~]# cat xh6.yml 
---
- hosts: testB
  gather_facts: no
  tasks:
  - shell: "ls /opt"
    register: returnvalue
  - debug:
      var: returnvalue

在这里插入图片描述
看到上例,你一定不会觉得陌生,在之前总结变量的文章中,我们已经总结过”register”的用法,我们可以通过”register”获取到模块执行后的”返回值”信息,如果你忘记了”register”的用法,请回顾前文,上例中,我们将shell模块执行后的返回值写入了名为”returnvalue”的变量中,然后使用debug模块输出了”returnvalue”变量的值,上述playbook执行后结果如下:

可以看到shell模块的返回值信息如上,但是,上例并没有借助循环重复调用shell模块,如果使用循环多次调用shell模块执行不同的命令,返回信息的格式还会和原来一样吗?我们来实验一下,我们将上例的playbook修改如下:

[root@server4 ~]# vim xh5.yml
[root@server4 ~]# cat xh5.yml 
---
- hosts: testB
  gather_facts: no
  tasks:
  - shell: "{{item}}"
    #register: returnvalue
    with_items:
    - "ls /opt"
    - "ls /mnt"
    register: returnvalue
  - debug:
      var: returnvalue

在这里插入图片描述
在这里插入图片描述
我们可以发现,当使用了循环以后,每次shell模块执行后的返回值都会放入一个名为”results”的序列中,其实,”results”也是一个返回值,当模块中使用了循环时,模块每次执行的返回值都会追加存放到”results”这个返回值中,所以,我们可以通过”results”关键字获取到每次模块执行后的返回值,示例如下

[root@server4 ~]# vim xh5.yml
[root@server4 ~]# cat xh5.yml 
---
- hosts: testB
  gather_facts: no
  tasks:
  - shell: "{{item}}"
    with_items:
    - "ls /opt"
    - "ls /mnt"
    register: returnvalue
  - debug:
      msg: "{{item.stdout}}"
    with_items: "{{returnvalue.results}}"

上例中,我们先使用循环重复的调用了shell模块,然后将shell模块每次执行后的返回值注册到了变量”returnvalue”中,之后,在使用debug模块时,通过返回值”results”获取到了之前每次执行shell模块的返回值(shell每次执行后的返回值已经被放入到item变量中),最后又通过返回值”stdout”获取到了每次shell模块执行后的标准输出,你可以执行一下上例的playbook,执行后,输出结果的msg关键字对应的值就是每次shell模块执行后的标准输出:

[root@server4 ~]# ansible-playbook xh5.yml 

在这里插入图片描述
你可能还会看到有的人使用如下方法输出”{{returnvalue.results}}”列表中的信息

[root@server4 ~]# vim xh7.yml
[root@server4 ~]# cat xh7.yml 
---
- hosts: testB
  gather_facts: no
  tasks:
  - shell: "{{item}}"
    with_items:
    - "ls /opt"
    - "ls /home"
    register: returnvalue
  - debug:
      msg:
       "{% for i in returnvalue.results %}
          {{ i.stdout }}
        {% endfor %}"

在这里插入图片描述
我们可以看出,上例使用了一个for循环遍历了” returnvalue.results”列表,上例中for循环的语法为jinja2语言中的for循环语法,jinja2是一种模板语言,jinja2是一个基于python的模板引擎,所以,在ansible中,我们可以使用jinja2编写模板文件,然后再根据模板文件来生成配置文件,jinja2中也有一些控制语句结构,比如for循环,上例中使用的就是jinja2语法中的for循环,如果你执行了上例的playbook,你会发现,debug模块只执行了一次,msg中对应的信息是所有shell模块执行后的stdout返回值,因为debug模块只是输出了经过jinja2的for循环处理过的信息而已,debug模块并没有因为for循环而被重复的调用。

### 回答1: ansible with_itemsAnsible的一个模块,用于在循环迭代一个列表或字典。它可以用于在多个主机上执行相同的任务,每个主机都有不同的参数。使用with_items可以简化Ansible Playbook的编写,并提高代码的可读性和可维护性。 ### 回答2: Ansible的with_items是一个非常有用的模块参数,用于在执行任务时遍历一个列表或字典。它允许我们对列表的每个项目执行相同的任务。 通过使用with_items,我们可以避免编写重复的任务,以及可以在不同的主机上执行相同的任务。我们可以使用with_items来执行以下操作: 1. 遍历列表:我们可以通过提供一个列表来遍历其的每个项目,并对每个项目执行相同的任务。这对于需要在多个主机上执行相同操作的情况非常有用。 2. 遍历字典:除了列表之外,with_items还可以遍历字典的每个键值对。这使得我们可以根据字典的不同键值对执行特定的任务。 3. 相关任务:我们还可以将with_items与相应的任务结合使用,以根据列表每个项目的不同来执行不同的任务。这样我们就可以根据项目的不同需要执行不同的操作。 总之,with_itemsAnsible一个非常有用的参数,可以帮助我们通过遍历列表或字典的项目来执行相同的或相关的任务。它提供了一种简洁、高效且灵活的方法,使得我们能够更好地管理和自动化我们的服务器和网络设备。 ### 回答3: Ansible的with_items是一个循环结构,用于对一个列表的元素进行迭代操作。在Playbook,我们可以使用with_items循环遍历一个列表,执行相同的任务。 使用with_items的语法如下: ```yaml - name: Example ansible.builtin.command: cmd: echo "{{ item }}" with_items: - item1 - item2 - item3 ``` 在以上示例,`ansible.builtin.command`模块会执行三次,分别传入item1、item2和item3参数。通过逐个迭代列表的元素,我们可以针对每个元素执行相同的任务,例如处理配置文件、安装软件包等。 除了静态列表,with_items还可以接受动态列表,例如通过变量传入或从其他任务提取。以下是一个使用动态列表的示例: ```yaml - name: Get list dynamically ansible.builtin.command: cmd: some_command --list register: command_output - name: Process list items ansible.builtin.debug: msg: "Processing item: {{ item }}" with_items: "{{ command_output.stdout_lines }}" ``` 在以上示例,第一个任务使用ansible.builtin.command模块运行一个命令,其输出会通过register注册到变量command_output。接下来的任务使用with_items循环遍历command_output.stdout_lines列表的每个元素,并对每个元素执行一项任务。 通过with_items,我们可以更加灵活地处理不同的场景,根据不同的需求循环执行任务。这样的迭代操作使得Ansible变得强大且易于使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值