变量与模板

AnsibleBeginner
立即练习

简介

如果你管理着 100 台服务器,就不希望它们完全相同。每台服务器可能都需要独特的主机名、IP 地址或特定的配置设置。

Ansible 通过变量和模板来处理这种需求。

  • 变量:用于表示数据的占位符,例如 port: 8080 或 server_name: "web-01"。
  • 模板:包含「空位」的文本文件。Ansible 会使用变量填充这些空位,生成最终文件。

这种组合让自动化变得可复用,而不是重复执行相同的工作。你可以为多个主机保留同一种通用结构,同时根据不同环境或机器替换其中的数据。

Ansible 使用一种名为 Jinja2 的模板语言。借助它,同一个模板可以根据提供的变量生成不同的最终配置文件,从而提高自动化的复用性。

最终可以生成这样的内容:Welcome to web-01

在本实验中,你将使用变量和模板为服务器生成自定义 HTML 网页。

创建模板

首先,整理实验文件。Ansible 会在名为 templates 的特定目录中查找模板。

这是 Ansible 设计理念的一部分。Ansible 倾向于使用可预测的目录结构,让自动化内容更易于阅读,也便于团队共享。

在项目目录中创建该目录:

mkdir -p ~/project/templates

接下来创建模板文件。模板文件通常以 .j2 结尾,表示使用 Jinja2。

使用 nano 创建 index.html.j2:

nano ~/project/templates/index.html.j2

添加以下 HTML 代码。注意其中特殊的 {{ }} 花括号。这是告诉 Ansible「在这里填入变量」的写法。

<html>
  <head>
    <title>{{ page_title }}</title>
  </head>
  <body>
    <h1>Welcome to {{ inventory_hostname }}</h1>
    <p>This file was generated by Ansible.</p>
  </body>
</html>

理解变量:

  • {{ page_title }}:这是一个自定义变量。稍后将在 Playbook 中定义它的值。
  • {{ inventory_hostname }}:这是一个魔法变量。Ansible 会自动识别它,它表示 Ansible 当前正在操作的服务器名称;在本实验中,该名称是 localhost。

区分这两类值很有帮助。有些变量由你定义,另一些变量则由 Ansible 根据清单和执行上下文自动提供。

保存并退出文件(按 Ctrl+X、Y、Enter)。

定义变量

现在需要创建一个使用此模板的 Playbook。在 Playbook 中定义自定义变量 page_title 的值。

创建名为 playbook.yml 的新文件:

nano ~/project/playbook.yml

先定义 Play 和变量:

---
- name: Deploy Web Page
  hosts: localhost
  vars:
    page_title: "My LabEx Web Server"
  tasks:

理解代码:

  • vars::用于列出变量的部分。
  • page_title: "...":告诉 Ansible,只要在模板中看到 {{ page_title }},就将其替换为 "My LabEx Web Server"。

保持文件打开,继续完成下一步。

使用 Template 模块

现在添加真正执行操作的任务。这里使用 template 模块。该模块会读取 .j2 文件,填充其中的变量,然后将结果保存到服务器。

在实际环境中,许多配置文件都通过 Template 模块部署。你无需复制静态文件,而是可以根据通用模板渲染出适用于特定主机的版本。

将以下任务添加到 playbook.yml。注意缩进!

---
- name: Deploy Web Page
  hosts: localhost
  become: yes
  vars:
    page_title: "My LabEx Web Server"
  tasks:
    - name: Create index.html from template
      template:
        src: templates/index.html.j2
        dest: /var/www/html/index.html
        mode: "0644"

理解代码:

  • template::要使用的模块。
  • src:源文件,即包含占位符的模板。
  • dest:目标位置,即最终 HTML 文件应保存的位置。
  • mode: "0644":设置文件权限,确保 Web 服务器可以读取该文件。
  • become: yes:写入 /var/www/html 需要 root 权限,因此添加此设置。

保存并退出文件。

部署并验证

运行 Playbook,查看模板的实际效果。

执行 Playbook:

ansible-playbook -i inventory playbook.yml

如果执行成功,你会看到 changed 状态。

现在查看 Ansible 创建的最终文件。占位符应该已经消失,并被实际文本替换。

读取生成的 HTML 文件:

cat /var/www/html/index.html

预期结果:

<html>
  <head>
    <title>My LabEx Web Server</title>
  </head>
  <body>
    <h1>Welcome to localhost</h1>
    <p>This file was generated by Ansible.</p>
  </body>
</html>

可以看到,{{ page_title }} 变成了 "My LabEx Web Server",{{ inventory_hostname }} 变成了 "localhost"。

总结

在本实验中,你学习了如何让配置变得动态。

  1. 模板:创建包含 {{ placeholders }} 的 .j2 文件。
  2. 变量:在 Playbook 的 vars 部分定义值。
  3. 魔法变量:使用 Ansible 自动提供的 inventory_hostname。
  4. Template 模块:使用 template 模块将变量和模板组合成最终配置文件。

借助这一强大功能,你可以使用单个模板配置数千台服务器,同时为每台服务器设置各自的具体信息。