Ansible教程:Playbook使用变量

介绍

Ansible 变量用于存放可复用的值(IP、账号、路径、版本、开关等),避免硬编码,支持在不同位置定义,优先级从低到高(越靠后优先级越高,会覆盖前面同名变量):

内置默认变量 < inventory 组变量 < inventory 主机变量 < playbook vars < playbook vars_files < role vars < role defaults < task vars < 命令行 `-e` 额外变量

提示: role defaults 是例外:defaults 优先级最低,role vars 高于 defaults

变量命名规范

  • 只能由字母、数字、下划线组成
  • 不能以数字开头
  • 区分大小写,推荐小写+下划线 app_port
  • 禁止使用 ansible 内置关键字(hosts, become, vars)作为变量名

变量类型

1. 字符串 string

name: "nginx" 引号可省略,有空格必须加引号

2. 数字 number

port: 80,不要加引号,否则变成字符串

3. 布尔 bool

enable: true / false(小写,yaml语法,yes/no也兼容)

4. 列表 list:

packages:
  - nginx
  - redis

取值:packages[0];循环:with_items: "{{ packages }}"

5. 字典 dict

db:
  host: 127.0.0.1
  port: 3306

两种取值:db.host 或 db['host'](key包含横杠时推荐中括号写法 db['db-port'])

下面例子的解释

  • debug 是 Ansible 内置模块,作用:打印信息,用来调试、看变量值。
  • msg 是 debug 模块的参数,用来指定要输出的文本内容。

变量定义1:定义全局变量(最常用)

创建文件:

vim playbook_变量.yml

内容如下:

---
- name: 变量演示playbook
  hosts: web
  vars:                  # 定义变量
    app_name: nginx
    dir_list:
      - /etc/nginx
      - /var/log/nginx
    user_info:
      name: www
      uid: 1000
  tasks:
    - name: 输出普通变量
      debug:
        msg: "应用名 {{ app_name }}"
    - name: 访问列表变量
      debug:
        msg: "日志目录 {{ dir_list[1] }}"
    - name: 访问字典变量
      debug:
        msg: "用户UID {{ user_info.uid }}"

取值语法

{{ 变量名 }},jinja2 语法,yaml 中如果 {{ 开头,必须加引号,否则 yaml 解析报错。

正确:
msg: "{{ app_name }}"
报错!yaml认为是特殊语法:
msg: {{ app_name }}

模拟执行

ansible-playbook playbook_变量.yml  -C -i ansible_client.ini

变量定义2:任务级变量

仅当前task生效

nano playbook_变量_任务级变量.yml
---
- name: 任务级变量演示
  hosts: all
  gather_facts: false
  vars:
    msg_content: "这是play全局变量"                  # play全局变量

  tasks:
    - name: 任务1:使用任务级变量,临时覆盖同名变量
      debug:
        msg: "{{ msg_content }}"                     # 该任务定义同名变量,使用任务级变量
      vars:
        msg_content: "👉 这是【任务1】的局部变量"      # 仅本任务生效

    - name: 任务2:再次打印msg_content,观察变化
      debug:
        msg: "{{ msg_content }}"                     # 该任务没有变量,使用全局变量

模拟执行

ansible-playbook playbook_变量_任务级变量.yml  -C -i ansible_client.ini

变量定义3:外部变量文件(推荐)

把变量单独放到 yaml 文件,playbook 引入,适合区分 开发/测试/生产环境。

创建文件夹,用于存放变量文件:

mkdir ansible_vars

创建变量文件:

vim ansible_vars/dev.yml

变量文件内容:

env: dev
db_host: 127.0.0.1

创建playbook文件:

vim playbook_变量文件.yml

内容:

---
- name: 加载外部变量文件
  hosts: web
  vars_files:            # 指定变量文件
    - ansible_vars/dev.yml
  tasks:
    - debug: 
        msg: "数据库地址 {{ db_host }}"

支持多个文件,后面文件同名变量覆盖前面。

模拟执行

ansible-playbook playbook_变量文件.yml  -C -i ansible_client.ini

变量定义4:Inventory 清单变量

在 Inventory 清单中定义变量,在 playbook 中使用变量

按主机 / 分组区分,不同主机可以有不同变量

inventory 清单文件

创建 inventory 文件:

vim ansible_client_变量.ini

内容如下:

# 定义web主机组
[web]
# 主机IP,后面 web_name=web01 就是【主机变量】,只对192.168.1.100生效
192.168.1.100 web_name=web01

# web组的组变量:[组名:vars],下面所有变量对web组里**全部主机生效**
[web:vars]
env=prod
nginx_port=80

playbook 文件

创建 playbook 文件

vim playbook_变量_清单变量.yml

内容:

---
- name: 测试inventory清单变量
  hosts: web
  gather_facts: false
  tasks:
    - name: 打印主机变量 web_name
      debug:
        msg: "主机名变量:{{ web_name }}"

    - name: 打印组变量 env 和 nginx_port
      debug:
        msg: "环境={{ env }}, nginx端口={{ nginx_port }}"

模拟执行

ansible-playbook playbook_变量_清单变量.yml  -C -i ansible_client_变量.ini

变量定义5:命令行传入变量(最高优先级)

执行命令时,定义变量,传给 playbook。

适合临时覆盖参数,例如上线时临时指定版本。

playbook 文件

创建 playbook 文件

nano playbook_变量_命令传入.yml

内容:

---
- name: 测试inventory清单变量
  hosts: web
  gather_facts: false
  tasks:
    - name: 打印主机变量 web_name
      debug:
        msg: "主机名变量:{{ web_name }}"

    - name: 打印组变量 env 和 nginx_port
      debug:
        msg: "环境={{ env }}, nginx端口={{ nginx_port }}"

模拟执行

简单变量

多个 -e 定义参数:

ansible-playbook playbook_变量_清单变量.yml  -C -i ansible_client.ini -e "web_name=web01" -e "env=prod"  -e "nginx_port=8080"
json格式多个变量
ansible-playbook playbook_变量_清单变量.yml  -C -i ansible_client.ini -e '{"web_name":"web01", "env":"prod", "nginx_port":8080}'

加载外部变量文件

把变量单独放到 yaml 文件,playbook 引入,适合区分 开发/测试/生产环境。

创建文件夹,用于存放变量文件:

mkdir ansible_vars

创建变量文件:

nano ansible_vars/变量.yml

变量文件内容:

web_name: web01
env: prod
nginx_port: 8080
ansible-playbook playbook_变量_清单变量.yml  -C -i ansible_client.ini -e @ansible_vars/变量.yml

真实案例

创建 playbook 文件

nano playbook_真实案例.yml

内容:

---
- name: 使用变量
  hosts: all
  vars:
    nginx_version: 1.24.0                   # 定义变量
  tasks:
    - name: 安装nginx
      apt:                                  # 适用ubuntu,使用centos改为yum,centos8以上改为dnf
        name: "nginx-{{ nginx_version }}"   # 使用变量
        state: present

模拟执行

ansible-playbook playbook_真实案例.yml  -C -i ansible_client.ini

常见坑点

  1. YAML 解析 {{ }} 报错:msg: "{{ var }}" 必须加双引号
  2. 变量优先级混淆:命令行 -e 优先级最高,会覆盖所有地方定义的同名变量
  3. 布尔值陷阱:True大写在yaml里会被识别成布尔,尽量小写 true;不要写字符串 "true",判断会出错
  4. 变量未定义报错:使用 | default() 兜底,或者开启 vars: ansible_check_mode,或者 when: var is defined
    when: db_host is defined
    
  5. facts变量只有 gather_facts: true 才存在,关闭facts后 ansible_os_family 等变量无法使用
  6. 变量名不能包含 - 横杠,app-port 字典key可以,变量名推荐下划线

原文出处:/show_1GW47UESRrwV.html