Ansible 循环示例和介绍 - Linux 自动化
在上一篇文章中,我们讨论了 Ansible,这是一个用 Python 编写的非常有用的配置免费开源软件,我们可以使用它在多台计算机上自动执行任务。我们了解了如何在一些最常用的 Linux 发行版上安装它以及其使用背后的基本概念。在本文中,我们重点介绍如何在 Ansible playbook 中使用循环,以便使用不同的数据多次执行单个任务。
在本教程中您将学习:
如何在 Ansible playbook 中使用循环
如何循环遍历项目列表
如何循环哈希列表
如何指定循环迭代之间的时间间隔
如何跟踪循环索引
使用的软件要求和约定
引入循环
让我们从一个简单的单一任务开始。假设我们想要确保某个文件应用了一组特定的权限。要将这个概念转化为 Ansible 任务,我们将使用 ansible.builtin.file 模块并编写:
- name: Apply permissions
ansible.builtin.file:
path: /foo.conf
mode: '600'
通过上面的任务定义,我们声明了一个状态:/foo.conf
文件必须应用 600
权限模式(其所有者应该能够读取和写入它)给它;不应向其群体和世界其他地区分配任何特权)。假设我们想对多个文件做同样的事情;我们应该如何着手?
当然,为每个文件编写完全相同的任务将是一个非常糟糕的主意,因为我们会重复自己。理想的情况是使用相同的任务,但使用不同的数据。这是一个典型的情况,正确的做法是使用循环。我们可以这样写:
- name: Set permissions
ansible.builtin.file:
path: "{{ item }}"
mode: '600'
loop:
- /foo.conf
- /bar.conf
- /baz.conf
任务执行时,控制台返回如下输出:
TASK [Apply permissions] *******************************************************
changed: [localhost] => (item=/foo.conf)
changed: [localhost] => (item=/bar.conf)
changed: [localhost] => (item=/baz.conf)
我们上面所做的是 Ansible playbook 中循环的一个非常简单的示例。正如您所看到的,我们在任务名称的相同缩进级别上使用了 loop
关键字。在本例中,我们使用 yaml 语法提供了路径列表;然后,在任务本身中,我们使用 item
变量来引用它们中的每一个。在每次迭代中,该变量将引用我们指定的列表中的一个元素。
挺容易!在这个简单的示例中,我们为列表中的所有文件分配了相同的权限;如果我们想为每个人分配不同的权限模式怎么办?
通过迭代哈希列表来指定多个参数
正如我们所说,在前面的示例中,我们简单地迭代了一个列表;然而,在某些情况下,我们需要在每次迭代时指定多个参数。在这些情况下,我们希望定义并迭代哈希列表。
假设我们想要为同一个任务设置多个文件的权限,就像我们之前所做的那样,但是我们想要为每个文件分配不同的权限模式。我们怎样才能做到呢?在这种情况下,迭代一个简单的列表是不够的。我们想要做的是迭代哈希列表。在每个哈希中,我们指定应使用的参数及其值。这是一个例子:
- name: Set permissions
ansible.builtin.file:
path: "{{ item.path }}"
mode: "{{ item.mode }}"
loop:
- { path: '/foo.conf', mode: '600' }
- { path: '/bar.conf', mode: '640' }
- { path: '/baz.conf', mode: '640' }
让我们看看上面我们做了什么。就像在前面的示例中一样,我们使用loop
指令来创建循环,但这一次,我们指定了一个哈希列表。在每个散列中,我们使用 path
和 mode
键,并为每个文件分配适当的值。
请注意,这里的键名称完全是任意的:它们不一定对应于任务中使用的参数。在任务本身内部,就像以前一样,在循环的每次迭代中分配的值是通过 item
变量引用的。在这种情况下,每个item
将是我们指定的哈希值之一;为了访问每个哈希中的键,我们使用 .
,就像访问 Python 对象的属性一样,因此每次都使用 item.path
> 将引用哈希中分配给该键的值。
控制迭代之间的时间
在某些情况下,我们可能想要设置循环迭代之间应该经过的时间量。我们如何在剧本中做到这一点?我们所要做的就是在 loop_control
部分中使用 pause
指令。这是一个简单的 ansible 循环示例,其中每次迭代在前一次迭代后运行 5
秒:
- name: Print message
ansible.builtin.debug:
msg: "{{ item }}"
loop:
- Hello
- World
loop_control:
pause: 5
跟踪迭代索引
就像我们在前面的示例中所做的那样,我们可以使用loop_control
部分来跟踪循环迭代计数。我们所要做的就是使用 index_var
指令。我们指定为此指令的值的变量将包含当前迭代的索引(从零开始)。这是一个例子:
- name: Print message
ansible.builtin.debug:
msg: "The item is {{ item }} and loop index is {{ i }}"
loop:
- hello
- world
loop_control:
index_var: i
我们在上面的例子中定义的任务非常琐碎,没有实际用途;然而,显示迭代索引如何增加可能很有用。如果我们执行它,我们会得到以下输出:
TASK [Print message] ***********************************************************
ok: [localhost] => (item=Hello) => {
"msg": "The item is Hello and loop index is 0"
}
ok: [localhost] => (item=World) => {
"msg": "The item is World and loop index is 1"
}
结论
在本文中,我们学习了 Ansible playbook 中循环的基本用法,并向读者提供了一些介绍性 Ansible 循环示例。我们了解了如何迭代一个简单的项目列表和一个哈希列表,每个列表都包含一组键值对。
我们还了解了如何指定循环的每次迭代之间应该经过多少秒,以及如何分别使用 loop_control
部分和 pause 来跟踪变量中的迭代索引
和 index_var
指令。在这里,我们仅仅触及了循环可以实现的功能的皮毛。如需更深入的知识,请查阅 Ansible 官方文档!