调试变量优先级问题

AnsibleBeginner
立即练习

介绍

当在多个位置定义同一个变量时,Ansible 会应用优先级规则。在修改 Playbook 之前,调试最终生效的值至关重要。

在本实验中,你将在 all、group、host 和 extra-var(额外变量)级别定义相同的变量,然后生成报告来验证哪个级别具有最高优先级。

创建优先级练习项目

在此步骤中,你将创建一个包含 all、group 和 host 变量目录的项目。

cd /home/labex/project
mkdir -p rhce-ansible/{inventory/group_vars,inventory/host_vars,playbooks,reports}
cd rhce-ansible
cat > ansible.cfg <<'EOF'
[defaults]
inventory = ./inventory/hosts
host_key_checking = False
retry_files_enabled = False
EOF
cat > inventory/hosts <<'EOF'
[web]
web1 ansible_connection=local
web2 ansible_connection=local
EOF

本实验特意在多个位置定义了相同的变量。报告将显示 Ansible 选择的最终值,而不是让你仅凭文件名来推断优先级。

定义 All 和 Group 变量

在此步骤中,你将在 group_vars/all.yml 中定义基准值,然后为 web 组覆盖这些值。 在执行此步骤中的命令之前,请返回 Ansible 项目目录。这样即使 LabEx 分步运行,命令也能保持稳定。

cd /home/labex/project/rhce-ansible
cat > inventory/group_vars/all.yml <<'EOF'
app_port: 8000
app_source: all
EOF
cat > inventory/group_vars/web.yml <<'EOF'
app_port: 8080
app_source: group
EOF

group_vars/all.yml 适用于所有主机,而 group_vars/web.yml 仅适用于 web 组。由于 web1 和 web2 都是 Web 主机,因此组变量的值应覆盖所有主机的基准值。

cat inventory/group_vars/all.yml inventory/group_vars/web.yml

定义主机变量覆盖

在此步骤中,你将仅为 web2 覆盖相同的变量。主机变量的优先级高于组变量。 在执行此步骤中的命令之前,请返回 Ansible 项目目录。

cd /home/labex/project/rhce-ansible
cat > inventory/host_vars/web2.yml <<'EOF'
app_port: 9090
app_source: host
EOF

此文件仅适用于 web2,因此它应该覆盖该主机的 Web 组值。web1 仍应使用组变量的值。

ansible-inventory --host web2

在运行 Playbook 之前,使用清单输出确认解析后的值。对于 web2,app_port 应显示为 9090。

渲染解析后的变量值

在此步骤中,你将编写并运行一个 Playbook,记录 Ansible 为每台主机选择的最终值。 在执行此步骤中的命令之前,请返回 Ansible 项目目录。

cd /home/labex/project/rhce-ansible
cat > playbooks/show-precedence.yml <<'EOF'
---
- name: Show resolved variable precedence
  hosts: web
  gather_facts: false
  tasks:
    - name: Write resolved variable report
      ansible.builtin.copy:
        dest: "/home/labex/project/rhce-ansible/reports/{{ inventory_hostname }}.txt"
        content: |
          host={{ inventory_hostname }}
          app_port={{ app_port }}
          app_source={{ app_source }}
        mode: '0644'
EOF

该 Playbook 将最终解析的值写入文件。这使得优先级变得直观:每份报告都记录了所选的端口以及一个来源标签,告诉你哪个层级胜出。

ansible-playbook playbooks/show-precedence.yml | tee reports/normal-run.txt
cat reports/web1.txt reports/web2.txt

web1 应显示 app_source=group,而 web2 应显示 app_source=host。这证明了主机变量的优先级高于组变量。

使用额外变量进行覆盖

在此步骤中,你将使用 -e 传递额外变量。额外变量具有极高的优先级,在此次运行中会覆盖组变量和主机变量。 在执行此步骤中的命令之前,请返回 Ansible 项目目录。

cd /home/labex/project/rhce-ansible
ansible-playbook playbooks/show-precedence.yml -e app_port=10080 -e app_source=extra | tee reports/extra-run.txt

额外变量的功能非常强大。它们在本次运行中会覆盖组变量和主机变量,但不会修改磁盘上的变量文件。

cat reports/web1.txt reports/web2.txt

现在两份报告都应显示额外变量的值。如果只有一台主机发生了变化,请重新检查 -e 选项的输入是否正确。

总结

你比较了 all、group、host 和 extra 变量,并通过生成的报告验证了 Ansible 在每个优先级级别应用了哪些值。