1285 字
6 分钟
Ansible 其他
简单记录 Ansible 中变量、角色、多环境配置
Ansible 变量
变量管理方式:
- 变量文件:
group_vars/all.yml(所有主机)、group_vars/web.yml(web组)、host_vars/web1.yml(单台主机),Ansible 会按 inventory 的位置自动加载; - Playbook 内部:
vars:声明 play 级变量,vars_files:引入外部变量文件; - 命令行传入:
-e/--extra-vars,如ansible-playbook site.yml -e "app_env=prod",优先级最高,适合临时覆盖; - 角色变量:
roles/<role>/defaults/main.yml(默认值,任何来源都能覆盖)与roles/<role>/vars/main.yml(角色内部固定值,优先级高)。
app_port: 8080
# site.yml- hosts: web vars: app_env: prod # play 级变量 vars_files: - vars/common.yml # 外部变量文件加密数据(Vault):
- 存储密文,可通过 Git 管理
- 常用命令:
ansible-vault create group_vars/all/vault.yml # 新建并加密ansible-vault edit group_vars/all/vault.yml # 解密后编辑,保存时重新加密ansible-vault encrypt group_vars/all/vault.yml # 加密已有文件ansible-vault decrypt group_vars/all/vault.yml # 解密已有文件ansible-vault rekey group_vars/all/vault.yml # 更换密码ansible-vault view group_vars/all/vault.yml # 只读查看- 执行时提供密码:
--ask-vault-pass(交互输入)或--vault-password-file ~/.vault_pass(适合 CI); - 常见约定是变量名明文、值加密:密文放
vault.yml,明文文件里引用它(db_password: "{{ vault_db_password }}"),这样 grep 变量名不必解密,--check也能正常渲染模板。
变量优先级:
Ansible 官方有二十余级变量来源,日常只需记住这条由低到高的主干:
| 优先级 | 来源 | 说明 |
|---|---|---|
| 低 | role defaults | 角色默认值,最容易被覆盖 |
| ↑ | inventory group_vars / host_vars | 按组、按主机分层的变量文件 |
| ↑ | play vars / vars_files | playbook 内声明 |
| ↑ | role vars(vars/main.yml) | 角色内部固定值,覆盖 defaults |
| ↑ | task vars | 单个任务上的 vars: |
| ↑ | set_fact / register | 运行时产生的变量,覆盖以上层级 |
| 高 | -e / --extra-vars | 命令行传入,永远最高 |
目录结构示例:
变量与 Inventory 目录约定
inventory
- hosts.ini
group_vars
- all.yml所有主机共用
- web.ymlweb 组
all
- vault.yml加密的敏感变量
host_vars
- web1.yml单台主机覆盖
- site.yml
Ansible 角色
角色是组织和重用 Playbook 的标准化结构,将任务、变量、文件模板、handler 等按约定目录组织。
核心价值:
- 复用:一个角色可以同时被多个 playbook、多个项目引用,也可以发布到 Galaxy 或打包进 collection;
- 解耦:playbook 只回答”哪些主机装什么”,实现细节沉到角色里,剧本因此短且稳定;
- 约定优于配置:目录名即语义(
tasks/、handlers/、templates/、defaults/),接手的人不用读完全部代码就知道东西在哪; - 可测试:结构固定,才便于用 Molecule 之类工具做收敛与幂等验证。
下面以”给 web 组部署 Nginx 与静态站点”作为示例场景:安装 nginx、下发站点配置、确保服务运行,且配置变更时自动 reload。这个场景覆盖角色最典型的三件事——装包、发配置、管服务。
使用步骤:
-
创建角色:
ansible-galaxy init roles/nginx生成标准骨架(也可以手写目录,结构一致即可) -
角色目录:
roles/nginx
roles
nginx
tasks
- main.yml任务入口
handlers
- main.yml配置变更后 reload
templates
- site.conf.j2Jinja2 模板
defaults
- main.yml可被覆盖的默认变量
vars
- main.yml角色内部变量
- files
meta
- main.yml依赖与元信息
- README.md
- 在 Playbook 中使用
- hosts: web become: true roles: - role: nginx vars: server_name: example.com # 覆盖 defaults/main.yml 中的默认值需要配合条件、标签或循环时,改用 include_role 把角色当普通任务引入:
- hosts: web become: true tasks: - name: 部署站点 ansible.builtin.include_role: name: nginx vars: server_name: example.com when: inventory_hostname in groups['web'] tags: [nginx]Ansible 多环境配置
Inventory 分离 + 变量分层
多环境(dev / staging / prod)的核心诉求是:同一套 playbook 与角色,靠 inventory 和变量区分环境,而不是复制三份剧本。
核心方法:
- Inventory 分离:每个环境一份 inventory(如
inventories/prod/hosts.ini),里面只写”有哪些主机、属于哪些组”; - 变量分层:环境相关变量放在 inventory 同级的
group_vars/中,Ansible 会按 inventory 位置自动加载;跨环境通用的放all.yml,环境特有的放web.yml; - 角色与剧本保持环境无关:playbook 和 role 里不出现环境名,只引用变量;
- 敏感变量逐环境加密:每个环境自己的
vault.yml单独加密,密码文件不入库; - 差异用变量表达,而不是用条件分支:能写成
{{ app_port }}的,就不要写when: env == 'prod',否则剧本会被环境判断塞满。
示例结构:
多环境目录布局
inventories
dev
- hosts.ini
group_vars
- all.yml
- web.yml
prod
- hosts.ini
group_vars
- all.yml
- web.yml
- vault.yml加密
roles
- nginx
- site.yml
用法上只是换一个 inventory:
ansible-playbook -i inventories/dev/hosts.ini site.ymlansible-playbook -i inventories/prod/hosts.ini site.yml --check --diff分享文章
生成精美分享图或复制链接,与更多人分享本文。
继续阅读
换条路线
从其他文章中稳定抽取
最后更新于 ,距今已过 33 天
部分内容可能已过时