91 lines
3.2 KiB
Markdown
91 lines
3.2 KiB
Markdown
# Vault + Woodpecker CI Integration
|
||
|
||
Тестовый репозиторий для проверки интеграции HashiCorp Vault с Woodpecker CI.
|
||
|
||
## Как это работает
|
||
|
||
Vault хранит секреты проектов по пути `projects/<project>/<env>`. Woodpecker CI получает их через AppRole аутентификацию.
|
||
|
||
### Архитектура
|
||
|
||
```
|
||
Woodpecker Agent (сеть: internal)
|
||
└── Pipeline контейнер (подключён к сети internal через WOODPECKER_BACKEND_DOCKER_NETWORK)
|
||
└── vault write auth/approle/login → Vault (сеть: internal)
|
||
└── vault kv get projects/... → секреты
|
||
```
|
||
|
||
### Глобальные секреты Woodpecker
|
||
|
||
В Woodpecker настроены 3 глобальных секрета:
|
||
|
||
| Секрет | Описание |
|
||
|--------|----------|
|
||
| `vault_addr` | Адрес Vault (`http://vault:8200`) |
|
||
| `vault_role_id` | AppRole Role ID для аутентификации |
|
||
| `vault_secret_id` | AppRole Secret ID для аутентификации |
|
||
|
||
### Паттерн использования в пайплайнах
|
||
|
||
**Step 1** — `fetch-secrets`: аутентифицируется в Vault и записывает секреты в `.env.vault`
|
||
|
||
**Step 2+** — любые шаги: делают `source .env.vault` и используют переменные
|
||
|
||
```yaml
|
||
steps:
|
||
- name: fetch-secrets
|
||
image: hashicorp/vault:latest
|
||
environment:
|
||
VAULT_ADDR:
|
||
from_secret: vault_addr
|
||
VAULT_ROLE_ID:
|
||
from_secret: vault_role_id
|
||
VAULT_SECRET_ID:
|
||
from_secret: vault_secret_id
|
||
commands:
|
||
- export VAULT_TOKEN=$(vault write -field=token auth/approle/login role_id=$VAULT_ROLE_ID secret_id=$VAULT_SECRET_ID)
|
||
- vault kv get -format=table projects/<project>/<env> | awk '/^====== Data/,0 { if ($1 != "======" && $1 != "Key" && $1 != "---") print "export "$1"="$2 }' > .env.vault
|
||
|
||
- name: build
|
||
image: node:20
|
||
commands:
|
||
- source .env.vault
|
||
- npm run build
|
||
|
||
- name: deploy
|
||
image: alpine
|
||
commands:
|
||
- source .env.vault
|
||
- ./deploy.sh
|
||
```
|
||
|
||
### Структура секретов в Vault
|
||
|
||
```
|
||
projects/
|
||
├── <project-a>/
|
||
│ ├── prod → {DB_HOST, DB_PASS, API_KEY, ...}
|
||
│ └── staging → {DB_HOST, DB_PASS, API_KEY, ...}
|
||
├── <project-b>/
|
||
│ └── prod → {DB_HOST, DB_PASS, ...}
|
||
```
|
||
|
||
### Управление секретами
|
||
|
||
```bash
|
||
# Добавить секрет
|
||
vault kv put projects/my-app/prod DB_HOST=db.example.com DB_PASS=secret API_KEY=xxx
|
||
|
||
# Прочитать секрет
|
||
vault kv get projects/my-app/prod
|
||
|
||
# Обновить одно поле (patch)
|
||
vault kv patch projects/my-app/prod API_KEY=new-key
|
||
```
|
||
|
||
### Безопасность
|
||
|
||
- AppRole `woodpecker` имеет **read-only** доступ к `projects/*`
|
||
- Токен живёт 1 час (TTL), максимум 4 часа
|
||
- `.env.vault` существует только во время пайплайна — volume удаляется после завершения
|
||
- Секреты, полученные из Vault в runtime, **не маскируются** в логах Woodpecker — не выводите их через `echo`
|