管理多台服务器和环境的配置是使用Ansible的一个巨大好处。但是当配置文件在服务器之间有所不同时会发生什么呢?与其为每台服务器或环境创建单独的配置文件,不如研究一下Ansible模板。
在本教程中,您将学习什么是Ansible模板,它们如何工作以及如何使用Ansible模板模块来节省大量时间。
先决条件
本文将是一个逐步教程。如果您想跟着做,请确保您有一个Ansible控制器主机。本教程将使用Ansible v2.9.18
什么是Ansible模板?
有时您需要将文本文件传输到远程主机。这些文本文件通常是某种配置文件。例如,如果您正在使用单个服务器,您可能需要创建一个名为app.conf的配置文件,某些服务将使用它。
该配置文件可能包含与该服务器特定的信息,如主机名、IP地址等。由于你正在使用单个服务器,你可以在Ansible控制器上创建该文件,然后使用复制模块在剧本中将其复制到服务器。
但是,如果你有多个需要该配置文件的web服务器,每个服务器都有其特定的值怎么办?你不能只是将配置文件复制到所有机器;它只是为具有特定主机名、IP地址等的单个服务器构建的。你需要一个Ansible模板。
Ansible模板允许你定义带有变量的文本文件,而不是静态值,然后在剧本运行时替换这些变量。
Ansible模板是什么样子的呢?
Ansible模板是一个使用Jinja2模板语言构建的文本文件,带有j2文件扩展名。一个Jinja2模板看起来就像你想放到远程主机上的文本文件一模一样。唯一的区别是,文件包含的是变量,而不是静态值。
例如,也许您需要在所有的网络服务器上获取一个名为app.conf的配置文件,其中包含对每个相应服务器 IP 地址、Ansible 主机和 Ansible 用户的引用。单个服务器的app.conf文件可能如下所示。
您不能将此文件复制到每个网络服务器上,因为每个项目将是唯一的,这取决于远程主机的 IP、Ansible 控制器的主机名和 Ansible 用户。
与其静态设置这些值,Ansible 模板允许您定义在运行时解释并替换为远程主机上的变量。
下面是app.conf.j2模板文件的示例。现在您可以看到,每个静态值都已被替换为双大括号括起的变量。在这种情况下,这些变量来自Ansible facts。
模板文件始终具有J2文件扩展名,并且通常与它们在目标主机上创建的文件具有相同的名称。
如何在远程主机上创建模板文件?
创建模板后,您需要将该模板文件传输到远程主机,并将其“转换”为其应该看起来的实际文本文件。为此,您需要在 playbook 中引用模板文件。
大多数 Ansible 管理员使用 copy 模块 将文件传输到远程主机,但如上所述,这在使用模板时并不可行。
下面你可以看到一个简单的例子,参考自一个剧本,该剧本将 app.conf 文件复制到所有剧本目标主机上的 /opt 目录中。
现在假设你已经将 app.conf 配置文件制作成了前一节中介绍的 app.conf.j2 模板文件,并放在了你的 Ansible 控制器上。现在你需要确保 app.conf 仍然传输到 /opt 目录,但变量已被实际值替换。
为了告诉剧本在 /opt 目录中创建 app.conf 文件,只需将 copy
引用替换为如下所示的 template
。当你这样做时,Ansible 将调用 template 模块 来传输模板并用静态值替换变量。
一旦剧本中的上述任务执行完毕,Ansible 将把 app.conf.j2 复制到远程主机的 /opt 目录中,用静态值替换其中的所有变量,并将文件重命名为 app.conf。
当您提供带有目录路径的模板
src
时,Ansible会在 /<ansible_installation_directory>/files/ 目录中查找模板。如果您只提供文件名,Ansible将在 /<ansible_installation_directory>/templates/ 目录中查找模板。
渲染配置文件: 模板示例
现在,让我们通过演示来看看如何设置Ansible模板并使用Ansible模板模块动态生成配置文件。在此示例中,您将在名为app.conf的文件中创建一个文件,该文件位于服务器/etc目录中,服务器名为SRV1。
本节中的步骤适用于任何类型的文本文件。本教程将使用配置文件作为单一示例。
1. 使用您通常用于管理Ansible的用户,通过SSH登录到Ansible控制主机。
2. 在您的主目录中创建一个文件夹,用于保存本教程的演示文件,并将工作目录更改为该文件夹。
3. 在看起来像下面的目录中创建一个名为app.conf.j2的模板文件。
您还可以在模板中使用特定于Ansible模板模块的各种变量。
4. 在同一目录中创建一个名为my_playbook.yml的简单playbook。此playbook将在/etc目录中创建app.conf文件。
5. 调用Ansible playbook,以目标是SRV1的远程主机。

6. 现在确认/etc/app.conf配置文件是否存在并具有预期的值。

使用模板模块更新文件权限
现在您已经了解了使用模板模块的基础知识,让我们进一步深入。在这个演示中,您将创建与之前显示的相同的app.conf文件。但是这一次,您将设置该文件的所有者和权限。
要更改模板模块创建的文件的权限,您必须在playbook内部使用三个参数:
- owner – 文件所有者
- group – 文件应属于的组
- mode – 权限。该字符串可以用符号表示,也可以用八进制数字表示
在符号模式中,
u
表示“用户”,g
表示“组”,o
表示“其他”。
假设您仍然创建了〜/ansible_template_demo文件夹,请打开my_playbook.yml剧本,并将内容替换为以下内容。在此示例中,Ansible将使用连接变量将所有者和组设置为Ansible用户。然后,它将文件权限设置为0644
,代表:
- 所有者具有读/写权限
- 组中的用户和其他所有人具有读权限
您可以在Ansible模板模块文档中找到所有可用的模板模块参数。
现在,再次执行剧本如下所示。
现在,您可以看到app.conf已分配了预期的文件权限。

使用循环模板化多个文件
有时单个文件不足够;您需要在远程主机上添加多个文件。在这种情况下,您可以使用模板模块与循环。使用loop
参数定义循环,可以添加存储在目录中的多个文本文件。
假设您仍然创建了〜/ansible_template_demo文件夹,您应该已经有app.conf.j2在其中。
1. 如下所示,在〜/ansible_template_demo文件夹中创建第二个模板文件,名为app2.conf.j2。
2. 打开my_playbook.yml书并用下面的YAML替换所有内容。这个剧本使用{{item}}
变量来表示循环处理中的每个模板文件。loop
参数然后定义循环要处理的每个模板文件。
3. 现在再次运行剧本。ansible-playbook my_playbook.yml --inventory SRV1

结论
Ansible模板和模板模块可以为你节省大量时间,并在你所有的远程主机上创建动态文本文件。复制模块提供了类似的功能,但如果需要创建动态文本文件,模板模块是你的好朋友。