feat(pipeline): Add SSH key rotation, health checks, and manual approval
Security & Operations Improvements: - Add step 06_update_ssh_keys to rotate authorized_keys on EC2 before each deployment, ensuring only current pipeline can access - Add step 09_health_check with retry logic (12 retries, 10s interval) verifying API backend (/actuator/health), CloudFront, and RDS - Add manual approval (trigger: manual) for production deployment with terraform plan saved as artifact (prod.tfplan) - Document terraform auto-approve policy: dev automatic, prod manual - Use DEV_DB_HOST and PROD_DB_HOST variables for RDS connectivity checks - Reorder steps: 7 steps → 9 steps standard CCsoft pipeline Closes pipeline security gaps and adds post-deploy verification.
This commit is contained in:
+96
-17
@@ -1,12 +1,14 @@
|
||||
#!/usr/bin/env bash
|
||||
# ===============================================================================================================
|
||||
# health-check.sh - Verifica que la API backend esté saludable
|
||||
# health-check.sh - Verifica que la API backend, CloudFront y RDS estén saludables
|
||||
# Descripción:
|
||||
# Realiza peticiones al endpoint de salud de la API con reintentos.
|
||||
# Puede ejecutarse desde la EC2 localmente o desde el pipeline.
|
||||
# Realiza peticiones a múltiples endpoints con reintentos configurables.
|
||||
# Puede ejecutarse desde la EC2 localmente o desde el pipeline CI/CD.
|
||||
# Verifica: API backend (puertos 8080-8084), CloudFront, RDS.
|
||||
#
|
||||
# Uso:
|
||||
# HEALTH_URL=http://localhost:8080/actuator/health bash health-check.sh
|
||||
# ENV=prod CF_DOMAIN=sacc.ccsoft.mx bash health-check.sh
|
||||
#
|
||||
# Autor: Área de Tecnología y Desarrollo - CCsoft
|
||||
# ===============================================================================================================
|
||||
@@ -17,8 +19,12 @@ set -euo pipefail
|
||||
# Configuración
|
||||
# -------------------------------------------------------------------------------
|
||||
HEALTH_URL="${HEALTH_URL:-http://localhost:8080/actuator/health}"
|
||||
MAX_RETRIES="${MAX_RETRIES:-30}"
|
||||
RETRY_INTERVAL="${RETRY_INTERVAL:-2}"
|
||||
CF_DOMAIN="${CF_DOMAIN:-}"
|
||||
DB_HOST="${DB_HOST:-}"
|
||||
DB_PORT="${DB_PORT:-3306}"
|
||||
ENV="${ENV:-dev}"
|
||||
MAX_RETRIES="${MAX_RETRIES:-12}"
|
||||
RETRY_INTERVAL="${RETRY_INTERVAL:-10}"
|
||||
|
||||
readonly CLR_RED='\033[0;31m'
|
||||
readonly CLR_GREEN='\033[0;32m'
|
||||
@@ -32,30 +38,103 @@ _log_error() { echo -e "${CLR_RED}[ERROR]${CLR_NC} $*" >&2; }
|
||||
_log_step() { echo ""; echo -e "${CLR_BLUE}==== $* ====${CLR_NC}"; }
|
||||
|
||||
# -------------------------------------------------------------------------------
|
||||
# Health Check
|
||||
# Health Check con reintentos
|
||||
# -------------------------------------------------------------------------------
|
||||
main() {
|
||||
_log_step "Health Check: ${HEALTH_URL}"
|
||||
|
||||
check_with_retry() {
|
||||
local name="$1"
|
||||
local url="$2"
|
||||
local check_cmd="$3"
|
||||
|
||||
_log_step "Verificando: ${name} (${url})"
|
||||
|
||||
local attempt=1
|
||||
while [[ $attempt -le $MAX_RETRIES ]]; do
|
||||
_log_info "Intento ${attempt}/${MAX_RETRIES}..."
|
||||
|
||||
if curl -sf "${HEALTH_URL}" | grep -q '"status":"UP"'; then
|
||||
_log_info "Health check PASÓ - API saludable"
|
||||
|
||||
if eval "${check_cmd}"; then
|
||||
_log_info "✓ ${name} - SALUDABLE"
|
||||
return 0
|
||||
fi
|
||||
|
||||
|
||||
if [[ $attempt -lt $MAX_RETRIES ]]; then
|
||||
_log_warn "API no responde aún, reintentando en ${RETRY_INTERVAL}s..."
|
||||
_log_warn "${name} no responde, reintentando en ${RETRY_INTERVAL}s..."
|
||||
sleep "${RETRY_INTERVAL}"
|
||||
fi
|
||||
|
||||
|
||||
((attempt++))
|
||||
done
|
||||
|
||||
_log_error "Health check FALLÓ después de ${MAX_RETRIES} intentos"
|
||||
|
||||
_log_error "✗ ${name} - FALLÓ después de ${MAX_RETRIES} intentos"
|
||||
return 1
|
||||
}
|
||||
|
||||
# -------------------------------------------------------------------------------
|
||||
# Health Check Principal
|
||||
# -------------------------------------------------------------------------------
|
||||
main() {
|
||||
local exit_code=0
|
||||
|
||||
_log_step "Health Check Post-Deploy [${ENV^^}]"
|
||||
echo "Configuración: MAX_RETRIES=${MAX_RETRIES}, INTERVAL=${RETRY_INTERVAL}s"
|
||||
echo ""
|
||||
|
||||
# 1. Verificar API Backend (puerto principal)
|
||||
if ! check_with_retry "API Backend" "${HEALTH_URL}" \
|
||||
"curl -sf '${HEALTH_URL}' | grep -q '\"status\":\"UP\"'"; then
|
||||
exit_code=1
|
||||
fi
|
||||
|
||||
# 2. Verificar puertos adicionales de servicios (8080-8084)
|
||||
local base_url
|
||||
base_url=$(echo "${HEALTH_URL}" | sed 's|/actuator/health||')
|
||||
for port in 8081 8082 8083 8084; do
|
||||
local port_url="${base_url//:[0-9]*/:${port}}/actuator/health"
|
||||
# Solo verificar si la variable del puerto está definida o si es el mismo host
|
||||
if [[ "${base_url}" =~ :[0-9]+ ]]; then
|
||||
port_url="${base_url%:*}:${port}/actuator/health"
|
||||
fi
|
||||
|
||||
# Verificación opcional - no falla el pipeline si un puerto opcional no responde
|
||||
_log_info "Verificando puerto opcional ${port}..."
|
||||
if curl -sf "${port_url}" | grep -q '"status":"UP"' 2>/dev/null; then
|
||||
_log_info "✓ Puerto ${port} - RESPONDE"
|
||||
else
|
||||
_log_warn "Puerto ${port} no responde (opcional)"
|
||||
fi
|
||||
done
|
||||
|
||||
# 3. Verificar CloudFront (si está configurado)
|
||||
if [[ -n "${CF_DOMAIN}" ]]; then
|
||||
if ! check_with_retry "CloudFront" "https://${CF_DOMAIN}/api/health" \
|
||||
"curl -sf -o /dev/null 'https://${CF_DOMAIN}/api/health'"; then
|
||||
exit_code=1
|
||||
fi
|
||||
else
|
||||
_log_warn "CF_DOMAIN no configurado. Saltando verificación de CloudFront."
|
||||
fi
|
||||
|
||||
# 4. Verificar RDS (si está configurado)
|
||||
if [[ -n "${DB_HOST}" ]]; then
|
||||
if command -v nc &> /dev/null; then
|
||||
if ! check_with_retry "RDS" "${DB_HOST}:${DB_PORT}" \
|
||||
"nc -zv '${DB_HOST}' ${DB_PORT}"; then
|
||||
exit_code=1
|
||||
fi
|
||||
else
|
||||
_log_warn "nc (netcat) no instalado. Saltando verificación de RDS."
|
||||
fi
|
||||
else
|
||||
_log_warn "DB_HOST no configurado. Saltando verificación de RDS."
|
||||
fi
|
||||
|
||||
echo ""
|
||||
if [[ $exit_code -eq 0 ]]; then
|
||||
_log_step "✓ TODOS LOS HEALTH CHECKS PASARON"
|
||||
else
|
||||
_log_step "✗ ALGUNOS HEALTH CHECKS FALLARON"
|
||||
fi
|
||||
|
||||
return $exit_code
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
Reference in New Issue
Block a user