1285 字
6 分钟
Ansible 其他

简单记录 Ansible 中变量、角色、多环境配置

Ansible 变量#

变量管理方式:

  1. 变量文件:group_vars/all.yml(所有主机)、group_vars/web.yml(web 组)、host_vars/web1.yml(单台主机),Ansible 会按 inventory 的位置自动加载;
  2. Playbook 内部:vars: 声明 play 级变量,vars_files: 引入外部变量文件;
  3. 命令行传入:-e / --extra-vars,如 ansible-playbook site.yml -e "app_env=prod",优先级最高,适合临时覆盖;
  4. 角色变量:roles/<role>/defaults/main.yml(默认值,任何来源都能覆盖)与 roles/<role>/vars/main.yml(角色内部固定值,优先级高)。
group_vars/all.yml
app_port: 8080
# site.yml
- hosts: web
vars:
app_env: prod # play 级变量
vars_files:
- vars/common.yml # 外部变量文件

加密数据(Vault):

  • 存储密文,可通过 Git 管理
  • 常用命令:
Terminal window
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_filesplaybook 内声明
↑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。这个场景覆盖角色最典型的三件事——装包、发配置、管服务。

使用步骤:

  1. 创建角色:ansible-galaxy init roles/nginx 生成标准骨架(也可以手写目录,结构一致即可)

  2. 角色目录:

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
  1. 在 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:

Terminal window
ansible-playbook -i inventories/dev/hosts.ini site.yml
ansible-playbook -i inventories/prod/hosts.ini site.yml --check --diff
Ansible 其他
https://blog-l7wd3.pages.dev/posts/iac/ansible-others/
作者
L7WD3-Xiao
发布于
2026-09-23
许可协议
CC BY-NC-SA 4.0

分享文章

生成精美分享图或复制链接,与更多人分享本文。

继续阅读

沿着主题读

基于共同的标签与分类

换条路线

从其他文章中稳定抽取