Что такое Secrets not found?
Ошибка Secrets not found
возникает, когда CI/CD пайплайн не может найти необходимые секреты (пароли, токены, ключи) для выполнения операций, что приводит к сбою процесса.
Причины возникновения
- Секреты не настроены в CI/CD системе
- Неправильные имена переменных окружения
- Проблемы с правами доступа к секретам
- Секреты устарели или были удалены
- Проблемы с шифрованием секретов
- Неправильная конфигурация vault или secret manager
- Проблемы с сетью при доступе к секретам
- Ошибки в скриптах загрузки секретов
Как отладить ошибку
- Проверь наличие секретов - убедись в их существовании в системе
- Проверь имена переменных - убедись в правильности названий
- Проверь права доступа - убедись в наличии необходимых прав
- Проверь конфигурацию - убедись в правильности настроек
- Проверь сетевые подключения - убедись в доступности secret manager
Как исправить ошибку
1. Настрой секреты в GitHub Actions
1# .github/workflows/secrets.yml
2name: Secrets Management
3on: [push]
4
5jobs:
6 deploy:
7 runs-on: ubuntu-latest
8 steps:
9 - uses: actions/checkout@v3
10
11 - name: Check secrets availability
12 run: |
13 # Проверка наличия секретов
14 if [ -z "${{ secrets.DATABASE_URL }}" ]; then
15 echo "DATABASE_URL secret is missing"
16 exit 1
17 fi
18
19 if [ -z "${{ secrets.API_KEY }}" ]; then
20 echo "API_KEY secret is missing"
21 exit 1
22 fi
23
24 - name: Deploy with secrets
25 run: |
26 # Использование секретов
27 echo "Deploying with database: ${{ secrets.DATABASE_URL }}"
28 echo "Using API key: ${{ secrets.API_KEY }}"
29
30 # Логика деплоя
31 kubectl set env deployment/my-app \
32 DATABASE_URL="${{ secrets.DATABASE_URL }}" \
33 API_KEY="${{ secrets.API_KEY }}"
2. Настрой секреты в GitLab CI
1# .gitlab-ci.yml
2variables:
3 DOCKER_DRIVER: overlay2
4
5stages:
6 - deploy
7
8deploy:
9 stage: deploy
10 image: alpine:latest
11 before_script:
12 - apk add --no-cache curl
13 script:
14 - |
15 # Проверка секретов
16 if [ -z "$DATABASE_URL" ]; then
17 echo "DATABASE_URL variable is not set"
18 exit 1
19 fi
20
21 if [ -z "$API_KEY" ]; then
22 echo "API_KEY variable is not set"
23 exit 1
24 fi
25
26 # Деплой с секретами
27 curl -X POST "https://api.example.com/deploy" \
28 -H "Authorization: Bearer $API_KEY" \
29 -H "Content-Type: application/json" \
30 -d "{\"database_url\":\"$DATABASE_URL\"}"
31 only:
32 - main
3. Настрой секреты в Jenkins
1// Jenkinsfile
2pipeline {
3 agent any
4
5 environment {
6 DATABASE_URL = credentials('database-url')
7 API_KEY = credentials('api-key')
8 }
9
10 stages {
11 stage('Check Secrets') {
12 steps {
13 script {
14 // Проверка наличия секретов
15 if (env.DATABASE_URL == null || env.DATABASE_URL.isEmpty()) {
16 error "DATABASE_URL secret is missing"
17 }
18
19 if (env.API_KEY == null || env.API_KEY.isEmpty()) {
20 error "API_KEY secret is missing"
21 }
22
23 echo "All secrets are available"
24 }
25 }
26 }
27
28 stage('Deploy') {
29 steps {
30 script {
31 // Использование секретов
32 sh """
33 echo "Deploying with database: \$DATABASE_URL"
34 echo "Using API key: \$API_KEY"
35
36 # Логика деплоя
37 kubectl set env deployment/my-app \\
38 DATABASE_URL="\$DATABASE_URL" \\
39 API_KEY="\$API_KEY"
40 """
41 }
42 }
43 }
44 }
45}
4. Настрой секреты в Kubernetes
1# k8s-secret.yaml
2apiVersion: v1
3kind: Secret
4metadata:
5 name: app-secrets
6 namespace: default
7type: Opaque
8data:
9 database-url: <base64-encoded-database-url>
10 api-key: <base64-encoded-api-key>
11 jwt-secret: <base64-encoded-jwt-secret>
12
13---
14apiVersion: apps/v1
15kind: Deployment
16metadata:
17 name: my-app
18spec:
19 replicas: 3
20 selector:
21 matchLabels:
22 app: my-app
23 template:
24 metadata:
25 labels:
26 app: my-app
27 spec:
28 containers:
29 - name: my-app
30 image: my-app:latest
31 env:
32 - name: DATABASE_URL
33 valueFrom:
34 secretKeyRef:
35 name: app-secrets
36 key: database-url
37 - name: API_KEY
38 valueFrom:
39 secretKeyRef:
40 name: app-secrets
41 key: api-key
42 - name: JWT_SECRET
43 valueFrom:
44 secretKeyRef:
45 name: app-secrets
46 key: jwt-secret
5. Настрой проверку секретов
1# secrets_validator.py
2import os
3import sys
4from typing import List, Dict
5
6class SecretsValidator:
7 def __init__(self, required_secrets: List[str]):
8 self.required_secrets = required_secrets
9 self.missing_secrets = []
10
11 def validate_secrets(self) -> bool:
12 """Проверка наличия всех необходимых секретов"""
13 for secret in self.required_secrets:
14 if not os.getenv(secret):
15 self.missing_secrets.append(secret)
16
17 if self.missing_secrets:
18 print(f"Missing secrets: {', '.join(self.missing_secrets)}")
19 return False
20
21 print("All required secrets are available")
22 return True
23
24 def validate_secret_format(self, secret_name: str, expected_format: str) -> bool:
25 """Проверка формата секрета"""
26 secret_value = os.getenv(secret_name)
27 if not secret_value:
28 print(f"Secret {secret_name} is not set")
29 return False
30
31 # Проверка формата (пример для URL)
32 if expected_format == "url" and not secret_value.startswith(("http://", "https://")):
33 print(f"Secret {secret_name} is not a valid URL")
34 return False
35
36 return True
37
38 def get_secrets_info(self) -> Dict[str, str]:
39 """Получение информации о секретах (без значений)"""
40 secrets_info = {}
41 for secret in self.required_secrets:
42 if os.getenv(secret):
43 secrets_info[secret] = "***SET***"
44 else:
45 secrets_info[secret] = "***MISSING***"
46
47 return secrets_info
48
49# Использование
50if __name__ == "__main__":
51 validator = SecretsValidator([
52 "DATABASE_URL",
53 "API_KEY",
54 "JWT_SECRET",
55 "REDIS_URL"
56 ])
57
58 if not validator.validate_secrets():
59 print("Secrets validation failed")
60 sys.exit(1)
61
62 print("Secrets validation passed")
63 print("Secrets status:", validator.get_secrets_info())
Как мониторить подобные ошибки
- Настрой алерты на missing secrets
- Мониторь доступность secret manager
- Отслеживай использование секретов
- Настрой мониторинг прав доступа
- Используй метрики для анализа проблем
FAQ
В: Как безопасно хранить секреты в CI/CD?
О: Используй встроенные secret managers, шифруй секреты, применяй принцип минимальных прав.
В: Что делать, если секреты устарели?
О: Настрой автоматическую ротацию секретов, используй временные токены, применяй secret rotation.
В: Как избежать утечек секретов в логах?
О: Используй маскирование в логах, настрой правильные уровни логирования, применяй secret scanning.
Лучшие практики
- Всегда проверяй наличие секретов перед использованием
- Используй встроенные secret managers CI/CD систем
- Настрой автоматическую ротацию секретов
- Мониторь доступность и использование секретов
- Применяй принцип минимальных прав
- Используй secret scanning для предотвращения утечек