Clean repository: organized structure and GitOps setup
- Organized root directory structure - Moved orphan files to proper locations - Updated .gitignore to ignore temporary files - Set up Gitea Runner for GitOps automation - Fixed Tailscale access issues - Added workflow for automated Nomad deployment
This commit is contained in:
268
docs/vault/ansible_vault_integration.md
Normal file
268
docs/vault/ansible_vault_integration.md
Normal file
@@ -0,0 +1,268 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user