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