Ansible教程:Playbook使用变量 作者:马育民 • 2026-09-26 17:08 • 阅读:10001 # 介绍 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**: ```yaml packages: - nginx - redis ``` 取值:`packages[0]`;循环:`with_items: "{{ packages }}"` ### 5. **字典 dict** ```yaml db: host: 127.0.0.1 port: 3306 ``` 两种取值:`db.host` 或 `db['host']`(key包含横杠时推荐中括号写法 `db['db-port']`) # 下面例子的解释 - `debug` 是 Ansible **内置模块**,作用:**打印信息,用来调试、看变量值**。 - `msg` 是 debug 模块的**参数**,用来指定要输出的文本内容。 # 变量定义1:定义全局变量(最常用) 创建文件: ``` vim playbook_变量.yml ``` 内容如下: ```yaml --- - name: 变量演示playbook hosts: web vars: # 定义变量 app_name: nginx app_port: 80 enable_ssl: true 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 解析报错。 ##### 正确: ```yaml msg: "{{ app_name }}" ``` ##### 报错!yaml认为是特殊语法: ``` msg: {{ app_name }} ``` ### 模拟执行 ``` ansible-playbook playbook_变量.yml -C -i ansible_client.ini ``` # 变量定义2:任务级变量 仅当前task生效 ``` nano playbook_变量_任务级变量.yml ``` ```yaml --- - 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 ``` 变量文件内容: ```yaml env: dev db_host: 127.0.0.1 ``` 创建playbook文件: ``` vim playbook_变量文件.yml ``` 内容: ```yaml --- - 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 ``` 内容如下: ```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 ``` 变量文件内容: ```yaml 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` ```yaml when: db_host is defined ``` 5. **facts变量只有 gather_facts: true 才存在**,关闭facts后 ansible_os_family 等变量无法使用 6. 变量名不能包含 `-` 横杠,`app-port` 字典key可以,变量名推荐下划线 原文出处:/show_1GW47UESRrwV.html