Ansible 密钥管理:安全自动化实用指南

  • infisical
  • 发布于 2026-02-06 18:41
  • 阅读 5

文章围绕 Ansible 中的密钥管理展开,先介绍 Ansible Vault 的用途、AES256 加密机制、文件级与变量级加密、vault password 的使用方式,以及在 playbook、环境隔离和执行命令中的典型实践。

博客图片

Ansible 是一个开源自动化工具,Red Hat 将其作为 Red Hat Ansible Automation Platform 的一部分提供。它已经成为全球无数服务器上配置管理和应用部署的首选方案之一。其无 Agent 架构和易于阅读的 YAML playbook 让各种规模的团队都能轻松上手。但和你技术栈中的任何其他工具一样,它也需要访问敏感凭证,也就是你的 secrets。

secrets 就像能打开技术栈不同部分的钥匙。这些凭证包括 API keysSSH certificates 以及云服务提供商的 token。妥善管理它们,对于在不引入不必要障碍的前提下维护安全性至关重要。

挑战在于:如何在保持 Ansible 简洁高效的同时,安全地保管这些 secrets。这就是为什么正确的 secrets 管理变得至关重要,尤其是像 SOC 2GDPRHIPAA 这样的框架和法规,往往要求加密、访问控制和可审计性等强有力的控制措施。

Ansible 提供了名为 Ansible Vault 的原生解决方案,用于加密敏感数据。然而,像 Infisical 这样的现代 secret 管理平台则提供了更高级的能力,包括自动轮换、集中管理和详细的审计日志。

在本指南中,我们将探讨这两种方法及其权衡,并帮助你为自动化需求选择合适的方案。

理解 Ansible Vault

Ansible Vault 是 Ansible 内置的加密功能,可用于保护项目中的敏感数据。它不会以明文形式存储密码、密钥和其他 secrets,而是使用 AES256 密码(AES-256)对这些信息进行加密。只要妥善保护并及时轮换 vault 密码,将加密后的 secret 文件存入版本控制系统就是合理的。

Ansible Vault 在两个层面上工作:

你也可以使用多个 vault ID 来管理不同环境或团队对应的不同密码,从而在组织和保护 secrets 时获得更大的灵活性。

创建和管理加密 secrets

设置你的第一个加密文件

首先,为敏感数据创建一个加密变量文件:

## 使用交互式密码提示创建一个新的加密文件
ansible-vault create group_vars/production/secrets.yml

## 或者加密一个已有文件
ansible-vault encrypt group_vars/production/database.yml

运行这些命令时,Ansible 会提示你输入 vault 密码。这个密码就是解密 secrets 的密钥,因此请妥善保管。

加密单个变量

有时你只需要保护特定值,而不是整个文件。使用 Ansible Vault,你可以加密单个字符串:

## 加密单个值
ansible-vault encrypt_string 'P@ssw0rd123!' --name 'database_password'

## 这会输出可直接粘贴到 playbook 中的 YAML:
database_password: !vault |
          $ANSIBLE_VAULT;1.1;AES256
          66386439653236336...

处理加密内容

一旦文件被加密,你就需要 vault 密码来查看或修改它们。可以使用 Ansible CLI 的 rekeydecryptedit 功能来完成这些操作。

## 编辑一个加密文件(会在你的默认编辑器中打开)
ansible-vault edit secrets.yml

## 查看内容而不编辑
ansible-vault view secrets.yml

## 永久解密一个文件(谨慎使用!)
ansible-vault decrypt secrets.yml

## 更改加密密码
ansible-vault rekey secrets.yml

将 secrets 集成到 Ansible playbook 中

基本用法

接下来,我们来看看如何在典型的 playbook 中使用 vault 加密变量。首先,需要配置 vars_files

---
- name: 配置 Web 应用
  hosts: webservers
  vars_files:
    - vars/common.yml
    - vars/secrets.yml  # 此文件已加密

  tasks:
    - name: 部署数据库配置
      template:
        src: database.conf.j2
        dest: /etc/app/database.conf
        mode: '0600'
      no_log: true  # 防止 secrets 出现在日志中

按环境划分的 secrets

然后,我们需要使用 Ansible 的目录结构按环境组织 secrets。结构如下:

ansible-project/
├── group_vars/
│   ├── all/
│   │   └── common.yml
│   ├── production/
│   │   ├── vars.yml
│   │   └── secrets.yml  # 已加密
│   └── staging/
│       ├── vars.yml
│       └── secrets.yml  # 使用不同密码加密

使用加密数据执行 playbook

接下来,在执行时可以通过几种方式提供 vault 密码。主要有三种策略:

  • 使用 --ask-vault-pass 提示输入密码
  • 使用 --vault-password-file 提供密码文件
  • 使用 --vault-id 为不同环境提供不同 ID,并配合密码文件使用
## 交互式密码提示
ansible-playbook deploy.yml --ask-vault-pass

## 密码文件(请妥善保管,不要放入版本控制!)
echo 'your_vault_password' > .vault_pass
chmod 600 .vault_pass
ansible-playbook deploy.yml --vault-password-file .vault_pass

## 为不同环境使用多个 vault ID
ansible-playbook deploy.yml \
  --vault-id production@.vault_pass_prod \
  --vault-id staging@.vault_pass_stage

安全最佳实践

处理 Ansible secrets 时,有两个关键实践。

在涉及 secrets 的任务上设置 no_log: true,以减少敏感值在输出和日志中泄露的可能性(但需要注意,某些调试模式和边界情况下仍可能暴露数据)。

- name: 处理敏感数据的任务
  mysql_user:
    name: appuser
    password: "{{ mysql_password }}"
    priv: '*.*:ALL'
  no_log: true  # 关键:防止密码出现在输出中

其次,在使用 shell 命令时,你可以向外部工具传递环境变量:

- name: 为外部工具使用环境变量
  shell: |
    export API_KEY="{{ api_secret }}"
    ./deploy-script.sh
  environment:
    API_KEY: "{{ api_secret }}"
  no_log: true

局限性和挑战

虽然 Ansible Vault 解决了加密 secrets 这一直接问题,但它也带来了显著的运维挑战:

  • 手动轮换负担:Vault 不提供自动轮换凭证的方法。当你需要更新密码时,必须手动编辑每个加密文件、更新值,并确保所有系统都收到新的凭证。
  • 团队协作阻力:在团队成员之间安全共享 vault 密码出乎意料地困难。团队常常会诉诸不安全的做法,比如通过聊天工具或电子邮件共享密码,这削弱了 Vault 提供的安全性。
  • 没有审计轨迹:Vault 不跟踪谁访问或修改了 secrets。对于合规要求或安全调查来说,你会缺少关于 secret 使用情况的关键可见性。
  • 仅支持静态 secrets:与现代 secrets 管理系统不同,Vault 不能生成临时且自动过期的凭证。每个 secret 在手动更改之前都会长期存在。
  • 规模复杂性:在不同环境、项目和团队之间管理多个 vault 密码,很快就会变成一场后勤噩梦。

不过,这些问题都可以通过将 Ansible 与更强大的方案(如 Infisical)集成来轻松解决。

现代替代方案:Infisical 集成

对于需要更强大 secrets 管理能力的团队,Infisical 提供了原生的 Ansible 集成,在保持易用性的同时解决了 Vault 的局限性。

主要优势

将专用 secrets 管理器(如 Infisical)与 Ansible 结合使用,可以解决核心挑战。具体来说,它提供:

要设置 Infisical 和 Ansible,只需要两个简单步骤。

第一步:安装 Infisical Collection

Ansible Galaxy(Ansible 的包管理器)安装 Infisical collection。

## 安装 collection
$ ansible-galaxy collection install infisical.vault

## 安装所需的 Python 包
$ pip install infisicalsdk

第二步:动态 secret 获取

然后,用从 Infisical 获取的 dynamic secret 替换静态加密文件。这样一来,secrets 就可以由 Infisical 来管理了。

- name: 使用 Infisical secrets 部署
  hosts: webservers
  gather_facts: false

  tasks:
    - name: 登录 Infisical(缓存认证一次)
      infisical.vault.login:
        url: "https://app.infisical.com"
        auth_method: universal_auth
        universal_auth_client_id: "{{ vault_client_id }}"
        universal_auth_client_secret: "{{ vault_client_secret }}"
      register: infisical_login
      no_log: true

    - name: 以字典形式读取 secrets
      infisical.vault.read_secrets:
        login_data: "{{ infisical_login.login_data }}"
        project_id: "proj_abc123"
        env_slug: "production"
        path: "/database"
        as_dict: true
      register: db_secrets
      no_log: true

    - name: 使用 secret
      debug:
        msg: "DB 密码已设置(已脱敏)"
      vars:
        db_password: "{{ db_secrets.secrets.PRIMARY_PASSWORD }}"

做出正确选择

对于非常小的团队或简单项目,Ansible Vault 可能已经足够。它内置、直接,而且不需要额外基础设施。如果你刚开始保护 playbook,可以从这里起步。

然而,对于生产环境,建议考虑像 Infisical 这样的专用 secrets 管理方案。专用方案提供:

  • 自动凭证轮换
  • 用于合规的审计轨迹
  • 跨多个工具的集中 secrets 管理
  • 动态、临时凭证
  • 基于团队的访问控制

从 Vault 迁移到专用 secrets 管理器并不一定要一刀切。许多团队会先在开发环境中使用 Vault,同时在生产环境中使用企业级解决方案,并随着需求增长逐步迁移。

你的下一步:标准化 secrets 管理

在使用 Ansible 时保护 secrets 并非可选项。这是负责任的基础设施自动化的基本要求。现在就从一些容易实现的改进入手,比如消除应用中的硬编码凭证。将 Ansible Vault 作为基础防护,确保所有敏感数据在进入版本控制之前都已加密。

随着自动化实践的成熟,评估 Vault 的局限性是否正在阻碍你。像 Infisical 这样的现代 secrets management 平台,可以消除手动轮换 secret 的负担,同时提供企业环境所需的审计轨迹和访问控制。

记住:最好的 secrets 管理策略,是你的团队真正会使用的策略。选择能够增强而非阻碍你自动化工作流的工具,并让安全成为开发流程中无缝的一部分。

  • 原文链接: infisical.com/blog/ansib...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
infisical
infisical
江湖只有他的大名,没有他的介绍。