一、为什么需要关注Ansible中的敏感信息?

在日常运维工作中,我们经常使用Ansible来自动化部署和管理服务器。但你是否想过,那些写在playbook里的数据库密码、API密钥等敏感信息,可能会因为一个小疏忽就暴露在外?这就像把家门钥匙随手放在门口地毯下,虽然方便,但风险很大。

举个例子,很多团队会把这样的内容直接写在playbook中:

# 技术栈:Ansible YAML
- name: 配置数据库连接
  hosts: db_servers
  tasks:
    - name: 部署MySQL配置文件
      template:
        src: my.cnf.j2
        dest: /etc/mysql/my.cnf
      vars:
        db_password: "SuperSecret123!"  # 明文密码直接暴露在playbook中

这种做法的问题显而易见:任何能访问这个playbook的人都能看到密码,如果代码仓库被入侵,后果不堪设想。

二、Ansible保护敏感信息的三种实用方法

1. 使用Ansible Vault加密敏感变量

Ansible Vault就像给你的敏感数据加了一个保险箱。它可以加密变量文件、整个playbook甚至单个变量。

# 技术栈:Ansible VAML
# 首先创建一个加密的变量文件
$ ansible-vault create secrets.yml
# 输入加密密码后,会打开编辑器,可以添加如下内容:
db_password: "SuperSecret123!"
api_key: "ABCDEFG123456"

# 然后在playbook中这样使用:
- name: 安全配置应用
  hosts: app_servers
  vars_files:
    - secrets.yml  # 引用加密文件
  tasks:
    - name: 注入API密钥
      template:
        src: config.json.j2
        dest: /etc/app/config.json

执行时需要提供加密密码:

$ ansible-playbook site.yml --ask-vault-pass

2. 环境变量与第三方密钥管理服务集成

对于云环境,我们可以结合AWS Secrets Manager或HashiCorp Vault:

# 技术栈:Ansible + HashiCorp Vault
- name: 从Vault获取数据库凭据
  hosts: localhost
  tasks:
    - name: 获取数据库密码
      community.hashi_vault.hashi_vault:
        url: "https://vault.example.com"
        auth_method: token
        token: "{{ lookup('env', 'VAULT_TOKEN') }}"  # 从环境变量获取token
        secret: "secret/data/db/prod"
      register: db_secret

    - name: 使用获取的密码配置应用
      template:
        src: db_config.j2
        dest: /etc/app/db.conf
      vars:
        db_pass: "{{ db_secret.secret.data.password }}"

3. 动态库存与临时凭据

对于临时访问,可以使用动态生成的凭据:

# 技术栈:Ansible + AWS
- name: 使用临时AWS凭据
  hosts: aws_servers
  vars:
    aws_access_key: "{{ lookup('env', 'AWS_ACCESS_KEY_ID') }}"
    aws_secret_key: "{{ lookup('env', 'AWS_SECRET_ACCESS_KEY') }}"
  tasks:
    - name: 创建临时IAM用户
      community.aws.iam_user:
        name: temp_deploy_user
        state: present
        access_key: "{{ aws_access_key }}"
        secret_key: "{{ aws_secret_key }}"

三、实际应用中的安全加固策略

1. 最小权限原则的实施

不要给Ansible执行账户过多权限。比如MySQL配置:

# 技术栈:Ansible + MySQL
- name: 创建受限数据库用户
  community.mysql.mysql_user:
    name: "ansible_user"
    password: "{{ vault_db_password }}"  # 从加密库获取密码
    priv: "app_db.*:SELECT,INSERT,UPDATE,DELETE"  # 只给必要权限
    state: present

2. Playbook的版本控制安全

在Git仓库中正确处理敏感文件:

# 技术栈:Git + Ansible
# .gitignore文件内容
secrets/*.vault
*.secret
.env

3. 审计与日志记录

记录敏感操作:

# 技术栈:Ansible
- name: 关键配置变更审计
  hosts: all
  tasks:
    - name: 记录配置变更
      lineinfile:
        path: /var/log/ansible_audit.log
        line: "{{ ansible_date_time.iso8601 }} - 用户 {{ ansible_user_id }} 修改了 {{ item }}"
      with_items: "{{ sensitive_files }}"
      no_log: true  # 不在日志中显示实际内容

四、不同场景下的最佳实践选择

1. 小型团队快速起步

对于3-5人的小团队,建议:

# 技术栈:Ansible
# 项目结构建议
inventory/
  production/
    hosts
    group_vars/
      all/
        vars.yml      # 非敏感变量
        vault.yml     # 加密的敏感变量

2. 企业级多环境管理

复杂环境需要更细致的划分:

# 技术栈:Ansible
# 企业级项目结构
environments/
  prod/
    inventory/
    group_vars/
    host_vars/
  staging/
    inventory/
    group_vars/
  secrets/
    prod/
      credentials.vault
    staging/
      credentials.vault

3. 云原生环境

结合Kubernetes的场景:

# 技术栈:Ansible + Kubernetes
- name: 部署应用到K8s
  hosts: localhost
  vars_files:
    - k8s_secrets.vault
  tasks:
    - name: 创建Secret资源
      k8s:
        state: present
        definition:
          apiVersion: v1
          kind: Secret
          metadata:
            name: app-secrets
          type: Opaque
          data:
            db_password: "{{ k8s_db_password | b64encode }}"

五、常见陷阱与避坑指南

  1. 加密文件忘记密码:建议使用密码管理器存储vault密码
  2. 部分加密导致泄露:要么整个文件加密,要么完全不加密
  3. 日志泄露敏感信息:总是为敏感任务设置no_log: true
  4. 临时文件残留:使用cleanup模块确保不留下临时文件
  5. 过度共享权限:定期审查Ansible执行账户的权限
# 技术栈:Ansible
- name: 安全清理任务示例
  hosts: all
  tasks:
    - name: 传输敏感文件
      copy:
        src: /tmp/sensitive.data
        dest: /etc/app/config
      no_log: true  # 不在日志中记录此任务

    - name: 清理临时文件
      file:
        path: /tmp/sensitive.data
        state: absent

六、总结与行动建议

安全加固不是一蹴而就的,而是一个持续的过程。建议从今天开始:

  1. 审计现有playbook中的明文密码
  2. 为不同环境创建独立的加密变量文件
  3. 建立团队内部的敏感信息处理规范
  4. 定期轮换加密密码和API密钥
  5. 考虑引入专业的密钥管理服务

记住,自动化带来的便利不应该以牺牲安全为代价。花点时间加固你的Ansible配置,未来可能会避免一场灾难。