mgmt/docs/vault/ansible_vault_integration.md

268 lines
6.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Ansible与HashiCorp Vault集成指南
本文档介绍如何将Ansible与HashiCorp Vault集成以安全地管理和使用敏感信息。
## 1. 安装必要的Python包
首先需要安装Ansible的Vault集成包
```bash
pip install hvac
```
## 2. 配置Ansible使用Vault
### 2.1 创建Vault连接配置
创建一个Vault连接配置文件 `vault_config.yml`
```yaml
vault_addr: http://localhost:8200
vault_role_id: "your-approle-role-id"
vault_secret_id: "your-approle-secret-id"
```
### 2.2 创建Vault查询角色
在Vault中创建一个专用于Ansible的AppRole
```bash
# 启用AppRole认证
vault auth enable approle
# 创建策略
cat > ansible-policy.hcl <<EOF
path "kv/data/ansible/*" {
capabilities = ["read"]
}
EOF
vault policy write ansible ansible-policy.hcl
# 创建AppRole
vault write auth/approle/role/ansible \
token_policies="ansible" \
token_ttl=1h \
token_max_ttl=4h
# 获取Role ID
vault read auth/approle/role/ansible/role-id
# 生成Secret ID
vault write -f auth/approle/role/ansible/secret-id
```
## 3. 在Ansible中使用Vault
### 3.1 使用lookup插件
在Ansible playbook中使用`hashi_vault`查找插件:
```yaml
---
- name: 使用HashiCorp Vault的示例
hosts: all
vars:
vault_addr: "http://localhost:8200"
role_id: "{{ lookup('file', '/path/to/role_id') }}"
secret_id: "{{ lookup('file', '/path/to/secret_id') }}"
# 从Vault获取数据库密码
db_password: "{{ lookup('hashi_vault', 'secret=kv/data/ansible/db:password auth_method=approle role_id=' + role_id + ' secret_id=' + secret_id + ' url=' + vault_addr) }}"
tasks:
- name: 配置数据库连接
template:
src: db_config.j2
dest: /etc/app/db_config.ini
```
### 3.2 使用环境变量
也可以通过环境变量设置Vault认证信息
```yaml
---
- name: 使用环境变量的Vault示例
hosts: all
environment:
VAULT_ADDR: "http://localhost:8200"
VAULT_ROLE_ID: "{{ lookup('file', '/path/to/role_id') }}"
VAULT_SECRET_ID: "{{ lookup('file', '/path/to/secret_id') }}"
tasks:
- name: 从Vault获取密钥
set_fact:
api_key: "{{ lookup('hashi_vault', 'secret=kv/data/ansible/api:key') }}"
```
## 4. 创建Vault密钥模块
创建一个自定义的Ansible角色用于管理Vault中的密钥
### 4.1 角色结构
```
roles/
└── vault_secrets/
├── defaults/
│ └── main.yml
├── tasks/
│ └── main.yml
└── vars/
└── main.yml
```
### 4.2 主任务文件
`roles/vault_secrets/tasks/main.yml`:
```yaml
---
- name: 确保Vault令牌有效
block:
- name: 获取Vault令牌
set_fact:
vault_token: "{{ lookup('hashi_vault', 'auth_method=approle role_id=' + vault_role_id + ' secret_id=' + vault_secret_id + ' url=' + vault_addr) }}"
no_log: true
rescue:
- name: Vault认证失败
fail:
msg: "无法从Vault获取有效令牌"
- name: 从Vault读取密钥
set_fact:
secrets: "{{ lookup('hashi_vault', 'secret=' + vault_path + ' token=' + vault_token + ' url=' + vault_addr) }}"
no_log: true
- name: 设置各个密钥变量
set_fact:
"{{ item.key }}": "{{ item.value }}"
with_dict: "{{ secrets.data.data }}"
no_log: true
```
## 5. 将现有Ansible Vault迁移到HashiCorp Vault
### 5.1 创建迁移脚本
创建一个脚本来自动迁移Ansible Vault内容到HashiCorp Vault
```bash
#!/bin/bash
# migrate_to_hashicorp_vault.sh
# 设置变量
ANSIBLE_VAULT_FILE=$1
VAULT_PATH=$2
VAULT_ADDR=${VAULT_ADDR:-"http://localhost:8200"}
# 检查参数
if [ -z "$ANSIBLE_VAULT_FILE" ] || [ -z "$VAULT_PATH" ]; then
echo "用法: $0 <ansible_vault_file> <vault_path>"
echo "示例: $0 group_vars/all/vault.yml kv/ansible/group_vars/all"
exit 1
fi
# 检查Vault登录状态
if ! vault token lookup >/dev/null 2>&1; then
echo "请先登录Vault: vault login <token>"
exit 1
fi
# 解密Ansible Vault文件
echo "解密Ansible Vault文件..."
TEMP_FILE=$(mktemp)
ansible-vault decrypt --output="$TEMP_FILE" "$ANSIBLE_VAULT_FILE"
# 将YAML转换为JSON并存储到HashiCorp Vault
echo "迁移密钥到HashiCorp Vault..."
python3 -c "
import yaml, json, sys, subprocess
with open('$TEMP_FILE', 'r') as f:
data = yaml.safe_load(f)
for key, value in data.items():
cmd = ['vault', 'kv', 'put', '$VAULT_PATH/' + key, 'value=' + json.dumps(value)]
subprocess.run(cmd)
"
# 清理临时文件
rm "$TEMP_FILE"
echo "迁移完成! 数据已存储在Vault路径: $VAULT_PATH/"
```
### 5.2 执行迁移
```bash
# 赋予脚本执行权限
chmod +x migrate_to_hashicorp_vault.sh
# 执行迁移
./migrate_to_hashicorp_vault.sh group_vars/all/vault.yml kv/ansible/group_vars/all
```
## 6. 更新Ansible配置
### 6.1 修改ansible.cfg
更新`ansible.cfg`文件添加Vault相关配置
```ini
[defaults]
vault_identity_list = dev@~/.ansible/vault_dev.txt, prod@~/.ansible/vault_prod.txt
[hashi_vault_collection]
url = http://localhost:8200
auth_method = approle
role_id = /path/to/role_id
secret_id = /path/to/secret_id
```
### 6.2 更新现有Playbook
将现有playbook中的Ansible Vault引用替换为HashiCorp Vault引用
```yaml
# 旧方式
- name: 使用Ansible Vault变量
debug:
msg: "数据库密码: {{ vault_db_password }}"
# 新方式
- name: 使用HashiCorp Vault变量
debug:
msg: "数据库密码: {{ lookup('hashi_vault', 'secret=kv/data/ansible/db:password') }}"
```
## 7. 最佳实践
1. **避免硬编码认证信息**使用环境变量或外部文件存储Vault认证信息
2. **限制令牌权限**为Ansible创建的Vault令牌仅授予必要的最小权限
3. **设置合理的TTL**为Vault令牌设置合理的生命周期避免长期有效的令牌
4. **使用no_log**:对包含敏感信息的任务使用`no_log: true`防止日志泄露
5. **定期轮换认证凭据**定期轮换AppRole的Secret ID
6. **使用CI/CD集成**在CI/CD流程中集成Vault认证避免手动管理令牌
## 8. 故障排除
### 8.1 常见问题
1. **认证失败**
- 检查Role ID和Secret ID是否正确
- 验证AppRole是否有正确的策略附加
2. **路径错误**
- KV v2引擎需要在路径中包含`data`,例如`kv/data/path`而不是`kv/path`
3. **权限问题**
- 确保AppRole有足够的权限访问请求的密钥
### 8.2 调试技巧
```yaml
- name: 调试Vault查询
debug:
msg: "{{ lookup('hashi_vault', 'secret=kv/data/ansible/db:password auth_method=approle role_id=' + role_id + ' secret_id=' + secret_id + ' url=' + vault_addr) }}"
vars:
ansible_hashi_vault_debug: true