Ansible Vault #
什么是 Ansible Vault? #
Ansible Vault 是 Ansible 内置的加密工具,用于加密敏感数据,如密码、密钥、证书等,确保机密信息不会以明文形式存储。
text
┌─────────────────────────────────────────────────────────────┐
│ Vault 工作流程 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 明文文件 加密 解密 │
│ ────────── ────────── ────────── │
│ password: secret $ANSIBLE_VAULT password: secret │
│ api_key: key123 1.1... api_key: key123 │
│ AES256... │
│ │
│ 加密密码保护 │
│ │
└─────────────────────────────────────────────────────────────┘
创建加密文件 #
创建新的加密文件 #
bash
# 创建加密的 YAML 文件
ansible-vault create secrets.yml
# 会提示输入密码,然后打开编辑器
# 输入内容后保存退出,文件自动加密
加密现有文件 #
bash
# 加密现有文件
ansible-vault encrypt secrets.yml
# 加密多个文件
ansible-vault encrypt file1.yml file2.yml file3.yml
使用密码文件 #
bash
# 使用密码文件创建
ansible-vault create --vault-password-file ~/.vault_pass secrets.yml
# 使用密码文件加密
ansible-vault encrypt --vault-password-file ~/.vault_pass secrets.yml
编辑加密文件 #
编辑加密文件 #
bash
# 编辑加密文件
ansible-vault edit secrets.yml
# 使用密码文件
ansible-vault edit --vault-password-file ~/.vault_pass secrets.yml
查看加密文件 #
bash
# 查看加密文件内容
ansible-vault view secrets.yml
# 使用密码文件
ansible-vault view --vault-password-file ~/.vault_pass secrets.yml
解密文件 #
解密文件 #
bash
# 解密文件(永久解密)
ansible-vault decrypt secrets.yml
# 解密到标准输出
ansible-vault decrypt --output=- secrets.yml
# 解密到新文件
ansible-vault decrypt secrets.yml --output=secrets_decrypted.yml
临时解密使用 #
bash
# 执行 Playbook 时提供密码
ansible-playbook site.yml --ask-vault-pass
# 使用密码文件
ansible-playbook site.yml --vault-password-file ~/.vault_pass
# 使用多个密码文件
ansible-playbook site.yml --vault-password-file pass1.txt --vault-password-file pass2.txt
修改密码 #
修改加密密码 #
bash
# 修改密码
ansible-vault rekey secrets.yml
# 使用密码文件修改
ansible-vault rekey --vault-password-file ~/.vault_pass secrets.yml
# 使用新密码文件
ansible-vault rekey --new-vault-password-file ~/.new_vault_pass secrets.yml
加密字符串 #
加密单个字符串 #
bash
# 加密字符串
ansible-vault encrypt_string 'my_secret_password' --name 'db_password'
# 输出
db_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
663864396539666364663166363964...
加密并保存到文件 #
bash
# 加密字符串并保存
ansible-vault encrypt_string 'my_secret_password' --name 'db_password' >> vars.yml
# 从 stdin 读取
echo 'my_secret_password' | ansible-vault encrypt_string --stdin-name 'db_password'
在 Playbook 中使用加密字符串 #
yaml
---
- name: Use encrypted string
hosts: databases
vars:
db_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
663864396539666364663166363964...
tasks:
- name: Configure database
mysql_user:
name: appuser
password: "{{ db_password }}"
使用加密文件 #
加密变量文件 #
yaml
# secrets.yml (加密文件)
---
db_root_password: SuperSecretPassword123!
db_app_password: AppPassword456!
api_key: sk-1234567890abcdef
ssl_certificate: |
-----BEGIN CERTIFICATE-----
MIIDXTCCAkWgAwIBAgIJAJC1HiIAZAiUMA0G...
-----END CERTIFICATE-----
yaml
# site.yml
---
- name: Deploy application
hosts: app_servers
vars_files:
- secrets.yml
tasks:
- name: Configure database
mysql_user:
name: appuser
password: "{{ db_app_password }}"
加密 Inventory 变量 #
yaml
# inventory/group_vars/databases.yml (加密文件)
---
mysql_root_password: "{{ vault_mysql_root_password }}"
mysql_replication_password: "{{ vault_mysql_replication_password }}"
密码管理 #
密码文件 #
bash
# 创建密码文件
echo "my_vault_password" > ~/.vault_pass
# 设置权限
chmod 600 ~/.vault_pass
配置文件指定密码文件 #
ini
# ansible.cfg
[defaults]
vault_password_file = ~/.vault_pass
使用脚本获取密码 #
bash
#!/bin/bash
# ~/.vault_pass.sh
# 从环境变量获取
echo $VAULT_PASSWORD
# 或从密钥管理服务获取
# aws ssm get-parameter --name "/ansible/vault_password" --with-decryption --query "Parameter.Value" --output text
ini
# ansible.cfg
[defaults]
vault_password_file = ~/.vault_pass.sh
多密码管理 #
使用 Vault ID #
bash
# 使用 Vault ID 创建文件
ansible-vault create --vault-id prod@~/.vault_prod secrets_prod.yml
ansible-vault create --vault-id dev@~/.vault_dev secrets_dev.yml
# 使用 Vault ID 加密
ansible-vault encrypt --vault-id prod@~/.vault_prod secrets_prod.yml
# 执行时指定 Vault ID
ansible-playbook site.yml --vault-id prod@~/.vault_prod --vault-id dev@~/.vault_dev
多密码文件结构 #
text
project/
├── .vault/
│ ├── prod_pass # 生产环境密码
│ ├── staging_pass # 预发环境密码
│ └── dev_pass # 开发环境密码
├── inventory/
│ ├── production/
│ │ └── group_vars/
│ │ └── secrets.yml # 使用 prod_pass 加密
│ ├── staging/
│ │ └── group_vars/
│ │ └── secrets.yml # 使用 staging_pass 加密
│ └── development/
│ └── group_vars/
│ └── secrets.yml # 使用 dev_pass 加密
└── ansible.cfg
ini
# ansible.cfg
[defaults]
vault_identity_list = prod@.vault/prod_pass, staging@.vault/staging_pass, dev@.vault/dev_pass
最佳实践 #
1. 分离敏感数据 #
text
inventory/
├── group_vars/
│ ├── all.yml # 非敏感变量
│ ├── webservers.yml # 非敏感变量
│ └── vault/
│ └── all.yml # 加密的敏感变量
2. 使用变量引用 #
yaml
# inventory/group_vars/all.yml (明文)
---
db_host: localhost
db_port: 3306
db_user: appuser
db_password: "{{ vault_db_password }}"
# inventory/group_vars/vault/all.yml (加密)
---
vault_db_password: SuperSecretPassword123!
3. 版本控制 #
gitignore
# .gitignore
.vault_pass
.vault/
*.pass
# 加密文件应该提交到版本控制
# !secrets.yml
4. 密码管理策略 #
bash
# 开发环境:使用密码文件
echo "dev_password" > .vault_dev_pass
# 生产环境:使用密钥管理服务
# AWS Secrets Manager
aws secretsmanager get-secret-value --secret-id ansible/vault_password --query SecretString --output text > .vault_prod_pass
# HashiCorp Vault
vault kv get -field=password secret/ansible/vault > .vault_prod_pass
5. CI/CD 集成 #
yaml
# .gitlab-ci.yml
deploy:
stage: deploy
script:
- echo "$VAULT_PASSWORD" > .vault_pass
- ansible-playbook -i inventory/production site.yml --vault-password-file .vault_pass
- rm .vault_pass
only:
- main
yaml
# GitHub Actions
- name: Deploy with Ansible
env:
VAULT_PASSWORD: ${{ secrets.VAULT_PASSWORD }}
run: |
echo "$VAULT_PASSWORD" > .vault_pass
ansible-playbook -i inventory/production site.yml --vault-password-file .vault_pass
rm .vault_pass
完整示例 #
项目结构 #
text
project/
├── ansible.cfg
├── .vault_pass
├── inventory/
│ ├── production/
│ │ ├── hosts
│ │ └── group_vars/
│ │ ├── all.yml
│ │ └── vault/
│ │ └── all.yml
│ └── staging/
│ ├── hosts
│ └── group_vars/
│ ├── all.yml
│ └── vault/
│ └── all.yml
├── playbooks/
│ └── site.yml
└── roles/
└── app/
配置文件 #
ini
# ansible.cfg
[defaults]
inventory = inventory/production
vault_password_file = .vault_pass
host_key_checking = False
retry_files_enabled = False
变量文件 #
yaml
# inventory/production/group_vars/all.yml
---
app_name: myapp
app_port: 8080
db_host: db.production.example.com
db_port: 3306
db_name: "{{ app_name }}_production"
db_user: "{{ app_name }}"
db_password: "{{ vault_db_password }}"
api_key: "{{ vault_api_key }}"
yaml
# inventory/production/group_vars/vault/all.yml (加密)
---
vault_db_password: SuperSecretProductionPassword!
vault_api_key: prod_api_key_1234567890abcdef
vault_ssl_cert: |
-----BEGIN CERTIFICATE-----
MIIDXTCCAkWgAwIBAgIJAJC1HiIAZAiUMA0G...
-----END CERTIFICATE-----
Playbook #
yaml
# playbooks/site.yml
---
- name: Deploy application
hosts: app_servers
become: yes
vars_files:
- inventory/production/group_vars/vault/all.yml
tasks:
- name: Configure database connection
template:
src: templates/db_config.yml.j2
dest: /etc/app/db_config.yml
owner: appuser
group: appuser
mode: '0600'
- name: Deploy SSL certificate
copy:
content: "{{ vault_ssl_cert }}"
dest: /etc/app/ssl/cert.pem
owner: root
group: root
mode: '0644'
常见问题 #
忘记密码 #
bash
# 如果忘记密码,无法恢复加密文件
# 建议备份密码文件或使用密钥管理服务
批量加密 #
bash
# 批量加密文件
for file in inventory/*/group_vars/vault/*.yml; do
ansible-vault encrypt "$file"
done
检查文件是否加密 #
bash
# 检查文件头
head -1 secrets.yml
# 加密文件以 $ANSIBLE_VAULT 开头
下一步 #
现在你已经掌握了 Ansible Vault,接下来学习 最佳实践 了解如何编写高质量的 Ansible 代码!
最后更新:2026-03-29