变量在 Ansible 里可以定义在很多地方,但它们有优先级,也就是说:变量覆盖的顺序是有规则的。

1. Ansible 变量优先级从高到低如下(由高到低)

优先级        位置                                            示例
--------------------------------------------------------------------------------------------------------------
1(最高)       命令行参数	                                    -e "var=value"
2            task 层级中设置的变量                             vars: 中或 set_fact
3            block 中定义的变量
4            play 中定义的变量                                vars: 或 vars_files:
5            主机变量(inventory)                            host_vars/hostname.yml 或 inventory 文件中的变量
6            组变量(inventory)                              group_vars/web.yml 等
7            角色变量(roles/xxx/vars/main.yml)
8            角色默认变量(roles/xxx/defaults/main.yml)
9(最低)       Ansible 内置默认值                               module 默认值、系统默认变量等

简单记忆口诀:

命令行最大,角色默认最小。近的覆盖远的

2. 举例

你定义了一个变量 app_port:

  • roles/myapp/defaults/main.yml → app_port: 8080

  • group_vars/web.yml → app_port: 8081

  • host_vars/web1.yml → app_port: 8082

  • playbook 里写了 vars: app_port: 8083

  • 命令行执行加了 -e app_port=8084

那么最终生效的是:👉 8084

3. 💡 常见冲突说明:

  • 如果你在多个地方定义了同一个变量名,Ansible 会取 优先级高的那个。

  • -e 的命令行参数是最高的,可以强制覆盖一切,常用于调试或临时调整配置。

4. 关于block中定义的变量

关于block中定义的变量,举例如下:

- hosts: all
  vars:
    my_var: "Play level"
  tasks:
    - name: Outside block
      debug:
        msg: "Outside block: "

    - block:
        - name: Inside block
          debug:
            msg: "Inside block: "
      vars:
        my_var: "Block level"

输出结果为:

Outside block: Play level
Inside block: Block level