1.Ansible 中变量可以在哪些位置定义?请按优先级从低到高排序说明。
(1)清单中的组变量 :直接在 Inventory(如 /etc/ansible/hosts
)中为组定义的变量;
(2)group_vars 子目录的组变量 :在清单或 Playbook 同级的 group_vars/
目录下,按++组名命名++ 的文件中定义的变量(如 group_vars/web_servers.yml
);
(3)清单中的主机变量 :直接在 Inventory 中为单个主机定义的变量(如 192.168.1.10 ansible_user=admin
);
(4)host_vars 子目录的主机变量 :在清单或 Playbook 同级的 host_vars/
目录下,按++主机名命名++ 的文件中定义的变量(如 host_vars/web01.yml
);
(5)主机事实(Facts) :Ansible 自动采集的主机信息(如 ansible_hostname
),运行时动态发现;
(6)Playbook 中的 Play 变量 :在 Playbook 的 vars
或 vars_files
中定义的变量,作用于当前 Play;
(7)任务变量 :在 Playbook 的任务tasks中通过**vars
** 定义的变量,仅作用于当前任务;
(8)命令行额外变量 :通过 --extra-vars(或 -e)传入的变量(如 ansible-playbook -e "env=prod"
),优先级最高。
2.为什么需要 Ansible Vault?它解决了什么核心问题?
Ansible 自动化中常涉及敏感数据(如密码、API 密钥、数据库凭证),若直接明文存储在 Playbook、变量文件或 Inventory 中,存在以下风险:有权限访问 Ansible 文件的用户可直接获取敏感数据;版本控制系统(如 Git)中存储明文,导致数据泄露。
Ansible Vault 通过加密敏感文件 / 变量 ,让敏感数据以密文形式存储和传输,解决了敏感数据的明文暴露问题,确保只有授权用户(掌握解密密码)能访问真实值。
3.Ansible Vault 的加密算法是什么?有什么注意事项?
Ansible Vault 使用 AES256 对称加密算法(将密码作为加密密钥)保护文件。
注意事项:加密强度依赖于密码复杂度 (弱密码易被暴力破解);加密功能依赖外部 Python 工具集,需确保环境已正确安装依赖;官方提示:AES256 加密方式未经过第三方正式审核,对超高安全要求场景需额外评估。
4.如何创建一个加密的变量文件?给出完整命令和流程。
(1)使用 ansible-vault create filename 命令创建加密文件。
(2)命令执行后会提示输入Vault密码,并二次确认。
(3)自动打开默认编辑器,编写敏感变量。
(4)保存退出,文件会被加密存储。
5.如何编辑一个已加密的文件?
使用命令 ansible-vault edit filename 编辑。
6.如何加密、解密现有的文件?如何更改加密文件的密码?
使用命令 ansible-vault encrypt filename 编辑。
使用命令 ansible-vault decrypt filename 解密。
使用命令 ansible-vault rekey filename 更改文件密码。
7.运行含 Ansible Vault 加密文件的 Playbook 时,ansible-navigator 如何处理密码?
ansible-navigator 需显式获取 Vault 密码才能解密文件,否则会报错(如 ERROR! Attempting to decrypt but no vault secrets found
)。提供密码的方式有 3 种:
- 交互式提示 :通过
--vault-id @prompt
让终端弹出密码输入框; - 指定密码文件 :用
--vault-password-file
指向存储密码的纯文本文件; - 环境变量 :设置
ANSIBLE_VAULT_PASSWORD_FILE
环境变量,指定密码文件路径。
8.为什么必须禁用 Playbook 工件才能交互式输入 Vault 密码?
Playbook 工件是 ansible-navigator 生成的临时中间文件 ,用于环境隔离和调试。若启用工件(默认启用),其生成流程会阻断交互式密码的传递(临时文件机制无法捕获终端输入的密码),导致命令挂起。
因此,交互式输入密码时必须通过 --playbook-artifact-enable false
或 配置文件禁用工件,确保密码交互流程正常。
9.如何通过配置文件永久禁用 Playbook 工件?写出 ansible-navigator.yml
示例。
ansible-navigator:
playbook-artifact:
enable: false
10.写出通过 ansible-navigator 交互式运行加密 Playbook 的完整命令。
ansible-navigator run -m stdout --playbook-artifact-enable false --vault-id @prompt playbook.yml
11.使用 --vault-password-file
传递密码时,如何保证密码安全?
需通过文件权限 + 路径限制 保障安全,设置密码文件权限为 600
(仅当前用户可读写)。
12.什么是 Ansible Facts?它包含哪些类型的信息?
Ansible Facts 是 Ansible 自动从++受管主机++ 采集的系统 / 环境元数据,无需手动配置即可获取。包含信息类型:
- 硬件信息:主机名、CPU 核心数、内存大小、磁盘容量;
- 网络信息:IP 地址、网卡名称、路由表;
- 系统信息:操作系统版本、内核版本、SELinux 状态;
- 软件状态:已安装包、服务运行状态(需额外模块支持时可能需手动触发)。
13.Ansible 如何采集 Facts?默认会自动采集吗?
Ansible 通过 ansible.builtin.setup
模块采集 Facts,默认自动触发 (每个 Play 执行第一个任务前,会隐式运行 setup
模块)。
可通过以下方式控制:
- 禁用自动采集 :在 Play 中设置
gather_facts: no
(适合已知环境,加速执行); - 手动触发采集 :显式调用
setup
模块(如ansible all -m setup
)。
14.如何在 Playbook 中引用 Facts?
通过 {{ ansible_fact_name }} 语法引用。
15.如何让 Ansible 仅采集特定类型的 Facts?
通过 ansible.builtin.setup
模块的 gather_subset
参数,指定采集子集(如 hardware
仅采集硬件 Facts)。
bash
- name: 仅采集硬件 Facts
hosts: all
tasks:
- name: 采集硬件相关 Facts
ansible.builtin.setup:
gather_subset:
- hardware # 仅采集硬件子集
gather_subset
支持的预定义子集包括(但不限于):
all
:采集所有 Facts(默认);hardware
:硬件信息(CPU、内存、磁盘等);network
:网络信息(IP、网卡、路由等);os
:操作系统信息(版本、内核等);
16.如何静态创建自定义 Facts?写出 INI 格式文件示例及引用方式。
静态自定义 Facts 需在受管主机的 /etc/ansible/facts.d/
目录下,创建以 .fact
结尾的 INI / JSON 文件(不能用yaml格式)。ansible.builtin.setup 模块会在 ansible_fact['ansible_local'] 变量中存储自定义事实,事实按照器定义文件名排列。
例:
(1)在/etc/ansible/facts.d/下创建文件myapp.fact,内容如下:
bash[myapp] packages = { "db_package": "mariadb-server", "web_package": "httpd" } [users] user1 = "alice" user2 = "bob"
- 文件名
myapp.fact
会成为ansible_local
中的命名空间(ansible_local.myapp
)。(2)创建Playbook(如
facts.yml
),用于采集 Facts 并打印ansible_local
变量:
bash- name: Custom Fact Testing hosts: demo1.example.com # 替换为你的受管主机 gather_facts: yes # 启用 Facts 采集 tasks: - name: Display all facts in ansible_local ansible.builtin.debug: var: ansible_local
(3)在控制节点运行命令:
bashansible-playbook facts.yml
17.什么是 Ansible 的 "魔法变量"?为什么不能用这些名称自定义变量?给出几个常用魔法变量?
Ansible 的 "魔法变量" 是自动生成的特殊变量,用于获取受管主机的元数据(如主机组、清单信息、其他主机的 Facts)。用户自定义变量不能使用这些名称,否则会冲突覆盖。
四个最有用的魔法变量:
hostvars:获取其他受管主机 的变量或 Facts(需提前采集过 Facts)。示例:hostvars['web01']['ansible_facts']['interfaces']
可获取 web01
主机的网络接口信息。
group_names:获取当前主机所属的所有组 (清单中定义的组)。示例:判断主机是否属于 db_servers
组:when: "'db_servers' in group_names" 。
groups:获取清单中所有组和组内主机 的映射关系。示例:遍历 web_servers
组的所有主机:loop: "{{ groups['web_servers'] }}"
inventory_hostname:获取清单中配置的主机名称(可能与实际主机名不同)。
18.hostvars
引用其他主机时,提示 "变量未定义",可能是什么原因?
- Facts 未采集 :目标主机(如
web01
)的 Facts 未采集(需gather_facts: yes
或手动运行setup
模块); - 主机名不匹配 :清单中主机名(如
web01
)与实际引用的名称不一致; - 清单未加载 :
groups
或hostvars
依赖清单信息,需确保-i
参数指定了正确的清单文件; - 作用域问题 :
hostvars
仅在 Playbook 执行时动态生成,需确保目标主机在当前清单中。