目录
-
一、变量(Variables)
-
1.1 命名规则
-
1.2 定义位置与优先级
-
1.3 清单变量
-
1.4 字典变量
-
1.5 变量使用与捕获输出
-
-
二、Vault:敏感数据加密
-
2.1 基本操作
-
2.2 运行加密 Playbook
-
-
三、Facts(事实)
-
3.1 查看事实
-
3.2 关闭与手动收集
-
3.3 事实子集
-
3.4 自定义事实
-
-
四、魔法变量(Magic Variables)
-
五、总结
一、变量(Variables)
变量是 Ansible 自动化的基础------它让 playbook 变得灵活、可复用,而不是一堆写死的配置。
1.1 命名规则
和大多数编程语言一样:
-
必须以字母开头
-
只能包含字母、数字、下划线
-
区分大小写
合法
nginx_port
app_version_2不合法
2app # 数字开头
my-var # 含连字符
1.2 定义位置与优先级
这是初学者最容易踩坑的点。
核心规则:越具体越优先,离 task 越近优先级越高
常见优先级(从低到高):
| 位置 | 优先级 |
|---|---|
| 清单组变量(inventory group vars) | 低 |
| group_vars 目录文件 | 向上递增 |
| 清单主机变量(host vars) | 向上递增 |
| host_vars 目录文件 | 向上递增 |
| Ansible 自动采集的 Facts | 向上递增 |
play 的 vars / vars_files |
向上递增 |
| 任务变量(register、set_fact) | 向上递增 |
命令行 -e / --extra-vars |
最高 |
常见定义方式示例:
# play 内联定义(vars 关键字)
- hosts: webservers
vars:
app_port: 8080
app_name: "my_app"
tasks:
- debug:
msg: "{{ app_name }} is running on port {{ app_port }}"
# 从外部文件加载(vars_files)
- hosts: webservers
vars_files:
- vars/settings.yml
tasks:
- debug:
msg: "{{ app_name }}"
# vars/settings.yml
---
app_name: "my_application"
app_port: 8080
命令行传入(优先级最高,适合临时覆盖):
ansible-playbook deploy.yml -e "app_port=9090"
# 传入列表
ansible-playbook deploy.yml -e '{"packages": ["nginx", "vim"]}'
# 从文件传入
ansible-playbook deploy.yml -e "@vars_file.yml"
1.3 清单变量
变量按作用范围分两类:
| 类型 | 说明 |
|---|---|
| 主机变量 | 只对特定主机生效 |
| 组变量 | 对组内所有主机生效 |
主机变量优先于组变量。
推荐用目录结构管理(比写在清单文件里清晰很多):
my_project/
├── inventory.ini
├── group_vars/
│ └── webservers.yml
├── host_vars/
│ └── web1.example.com.yml
└── site.yml
# group_vars/webservers.yml
---
firewall_package: ufw
common_packages:
- vim
- git
- htop
# host_vars/web1.example.com.yml
---
nginx_sites_enabled:
- host1.example.com
- admin.example.com
1.4 字典变量
当管理多个对象(如用户、服务)时,扁平变量很快就会失控:
# 扁平化(难维护,容易命名冲突)
user_alice_uid: 1234
user_alice_home: /home/alice
user_bob_uid: 1235
user_bob_home: /home/bob
用字典会清晰很多:
# 推荐
users:
alice:
uid: 1234
home: /home/alice
groups: developers
bob:
uid: 1235
home: /home/bob
groups: ops
访问方式:
# 两种写法等价,选一种统一用
users.alice.uid
users['alice']['uid']
1.5 变量使用与捕获输出
使用变量时,双花括号包裹,记得加引号:
- name: Install package
ansible.builtin.yum:
name: "{{ package_name }}"
state: present
捕获命令输出:
- name: Check hostname file
ansible.builtin.command: ls /etc/hostname
register: file_check
- name: Print result
debug:
var: file_check.stdout
register 返回的是一个字典,包含 stdout、stderr、rc(返回码)等字段,调试时用 debug: var: xxx 打印全部内容。
二、Vault:敏感数据加密
密码、API Key、数据库凭证------这些东西绝对不能以明文存在 Git 仓库里。
Ansible Vault 就是干这个的:用 AES256 对称加密保护敏感文件,整个工作流不变,只是文件变成了加密格式。
可以类比理解:普通变量文件 = ConfigMap,Vault 文件 = Secret。
2.1 基本操作
创建加密文件(默认用 vi 打开):
ansible-vault create secrets.yml
查看加密文件:
ansible-vault view secrets.yml
编辑加密文件:
ansible-vault edit secrets.yml
加密已有文件:
ansible-vault encrypt plaintext.yml
# 加密后保存为新文件
ansible-vault encrypt plaintext.yml --output=secrets.yml
解密文件:
ansible-vault decrypt secrets.yml
# 解密后保存为新文件
ansible-vault decrypt secrets.yml --output=plaintext.yml
修改 Vault 密码:
ansible-vault rekey secrets.yml
# 指定新密码文件
ansible-vault rekey secrets.yml --new-vault-password-file=new_pw.txt
2.2 运行加密 Playbook
运行包含加密变量的 playbook,必须提供 Vault 密码,有三种方式:
方式一:交互输入(临时用)
ansible-navigator run -m stdout \
--playbook-artifact-enable false site.yml \
--vault-id @prompt
方式二:密码文件(推荐,适合 CI/CD)
ansible-navigator run -m stdout site.yml \
--vault-password-file=.vault_pass
密码文件建议设置权限
chmod 600,且不要提交到版本控制。
方式三:环境变量
export ANSIBLE_VAULT_PASSWORD_FILE=~/.vault_pass
ansible-navigator run -m stdout site.yml
多环境场景下,可以同时指定多个密码文件:
ansible-navigator run site.yml \
--vault-password-file=prod.pass \
--vault-password-file=dev.pass
三、Facts(事实)
Facts 是 Ansible 在执行 play 前,从受管节点自动采集的系统信息,由 ansible.builtin.setup 模块完成。
常用 Facts 速查:
| 描述 | 变量名 |
|---|---|
| 短主机名 | ansible_facts['hostname'] |
| 完整域名 | ansible_facts['fqdn'] |
| 主要 IPv4 地址 | ansible_facts['default_ipv4']['address'] |
| 所有网络接口列表 | ansible_facts['interfaces'] |
| 内核版本 | ansible_facts['kernel'] |
| OS 版本 | ansible_facts['distribution_version'] |
| 总内存(MB) | ansible_facts['memtotal_mb'] |
| 可用内存(MB) | ansible_facts['memfree_mb'] |
3.1 查看事实
# fact_dump.yml
---
- name: Dump all facts
hosts: all
tasks:
- name: Print all facts
ansible.builtin.debug:
var: ansible_facts
ansible-navigator run -m stdout fact_dump.yml
输出内容很多,实际用的时候只取需要的字段:
- debug:
msg: "IP: {{ ansible_facts['default_ipv4']['address'] }}"
3.2 关闭与手动收集
Facts 默认自动收集,对大规模集群会增加耗时。可以关掉,在需要时手动采集:
---
- name: Manual fact gathering
hosts: all
gather_facts: no
tasks:
- name: Only collect network facts
ansible.builtin.setup:
gather_subset:
- network
3.3 事实子集
不需要全量采集时,通过 gather_subset 指定:
tasks:
# 只采集网络相关
- ansible.builtin.setup:
gather_subset:
- network
# 采集硬件 + 网络
- ansible.builtin.setup:
gather_subset:
- hardware
- network
# 排除网络(其余全采)
- ansible.builtin.setup:
gather_subset:
- "!network"
# 最小集
- ansible.builtin.setup:
gather_subset:
- min
详细子集列表可查:
ansible-doc ansible.builtin.setup
3.4 自定义事实
除了系统自动采集的信息,管理员也可以在受管节点上定义自定义事实。
规则:
-
文件存放在受管节点的
/etc/ansible/facts.d/目录 -
格式支持 INI 或 JSON,不支持 YAML
-
文件名必须以
.fact结尾/etc/ansible/facts.d/app.fact(INI 格式)
[app]
version=2.3.1
env=production
port=8080
采集后通过以下路径访问:
ansible_facts['ansible_local']['app']['app']['version']
四、魔法变量(Magic Variables)
有些信息 setup 模块不会采集,但有时候我们确实需要------比如在操作一台主机时,想知道另一台主机的 IP。这时候就用魔法变量:
| 变量名 | 描述 |
|---|---|
hostvars |
包含所有受管主机的变量(含 Facts) |
hostvars[inventory_hostname] |
当前主机的全部变量 |
group_names |
当前主机所属的组列表 |
groups |
清单中所有组及其主机 |
inventory_hostname |
清单中定义的主机名 |
使用示例:
- name: Get another host's IP
debug:
msg: "db server IP: {{ hostvars['db01']['ansible_facts']['default_ipv4']['address'] }}"
注意:
inventory_hostname和ansible_facts['hostname']不一定相同。清单里写的是 IP 或别名,facts 采集的是系统真实主机名,别混淆。
五、总结
这篇覆盖了 Ansible 里最高频用到的几个核心概念:
| 功能 | 关键点 |
|---|---|
| 变量 | 优先级规则、字典变量、register 捕获输出 |
| Vault | AES256 加密、三种运行方式 |
| Facts | 自动采集系统信息、支持自定义 |
| 魔法变量 | 跨主机访问变量的入口 |
一个比较实用的设计思路:非敏感配置放 group_vars/ 和 host_vars/,敏感数据走 Vault 加密,运行时信息用 Facts,跨节点引用靠魔法变量。四块配合用好,基本覆盖 Ansible 项目里 90% 的变量管理场景。