管理变量(二) 主机变量和组变量直接应用于主机的清单变量分为两大类主机变量应用于特定主机以及组变量应用于一个主机组或一组主机组中的所有主机。主机变量优先于组变量但 playbook 中定义的变量的优先级比这两者更高。若要定义主机变量和组变量一种方法是直接在清单文件中定义。定义demo.example.com的ansible_user主机变量[servers] demo.example.com ansible_userjoe定义 servers 主机组的 user 组变量。[servers] demo1.example.com demo2.example.com [servers:vars] userjoe定义 servers 组的 user 组变量该组由两个主机组组成每个主机组有两个服务器。[servers1] demo1.example.com demo2.example.com [servers2] demo3.example.com demo4.example.com [servers:children] servers1 servers2 [servers:vars] userjoe此做法存在的一些缺点它使得清单文件更难以处理在同一文件中混合提供了主机和变量信息而且采用的也是过时的语法。使用目录填充主机和组变量要定义主机和主机组的变量您可在与清单文件或 playbook 相同的工作目录中创建group_vars和host_vars两个目录。这两个目录分别包含用于定义组变量和主机变量的文件。要定义 servers 组的组变量需要创建名为group_vars/servers的 YAML 文件然后该文件的内容将使用与 playbook 相同的语法将变量设置为值user: joe类似地为了定义用于特定主机的主机变量需要在host_vars目录中创建名称与主机匹配的文件来存放主机变量。下面的示例更加详细地说明了这一做法。例如在一个场景中您需要管理两个数据中心并在~/project/inventory清单文件中定义数据中心主机[datacenter1] demo1.example.com demo2.example.com [datacenter2] demo3.example.com demo4.example.com [datacenters:children] datacenter1 datacenter2如果需要为两个数据中心的所有服务器定义一个通用值可以为 datacenters 主机组设置一个组变量# ~/project/group_vars/datacenters package: httpd如需为每个数据中心定义不同的值可以为每个数据中心主机组设置组变量# ~/project/group_vars/datacenter1 package: httpd# ~/project/group_vars/datacenter2 package: apache如需为每一数据中心的各个受管主机定义不同的值则在单独的主机变量文件中定义变量# ~/project/host_vars/demo1.example.com package: httpd # ~/project/host_vars/demo2.example.com package: apache # ~/project/host_vars/demo3.example.com package: mariadb‑server # ~/project/host_vars/demo4.example.com package: mysql‑server从命令行覆盖变量清单变量可被 playbook 中设置的变量覆盖这两种变量又可通过在命令行中传递参数到ansible‑navigator run命令来覆盖。在命令行上设置的变量称为额外变量。当您需要覆盖一次性运行的 playbook 的变量的已定义值时额外变量非常有用。例如ansible-navigator run main.yml -e packageapache将字典用作变量除了将与同一元素相关的配置数据分配到多个变量外管理员也可以使用字典。字典是一个包含键值对的数据结构其中的值也可以是字典。示例原始分散变量user1_first_name: Bob user1_last_name: Jones user1_home_dir: /users/bjones user2_first_name: Anne user2_last_name: Cook user2_home_dir: /users/acook改写成名为users的字典users: bjones: first_name: Bob last_name: Jones home_dir: /users/bjones acook: first_name: Anne last_name: Cook home_dir: /users/acook然后您可以使用以下变量来访问用户数据# Returns Bob users.bjones.first_name # Returns /users/acook users.acook.home_dir由于变量被定义为 Python 字典因此可以使用替代语法。# Returns Bob users[bjones][first_name] # Returns /users/acook users[acook][home_dir]使用已注册变量捕获命令输出您可使用register语句来捕获命令的输出或有关模块执行的其他信息。输出会保存到一个变量中稍后在 playbook 中可用于调试用途或者达成其他目的例如基于命令输出应用特定配置设置。以下 play 演示了如何为调试用途捕获命令输出--- - name: Installs a package and prints the result hosts: all tasks: - name: Install the package ansible.builtin.dnf: name: httpd state: installed register: install_result - debug: var: install_result运行该 play 时debug 模块用于将 install_result 注册变量的值转储到终端。ansible-navigator run playbook.yml -m stdoutPLAY [Installs a package and prints the result] ************************ TASK [setup] *********************************************************** ok: [demo.example.com]