Files
proyectosacc-mirror/scripts/health-check.sh
T
Evert Daniel Romero Garrido defce6933d 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.
2026-04-20 17:47:15 -06:00

141 lines
4.9 KiB
Bash
Executable File

#!/usr/bin/env bash
# ===============================================================================================================
# health-check.sh - Verifica que la API backend, CloudFront y RDS estén saludables
# Descripción:
# 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
# ===============================================================================================================
set -euo pipefail
# -------------------------------------------------------------------------------
# Configuración
# -------------------------------------------------------------------------------
HEALTH_URL="${HEALTH_URL:-http://localhost:8080/actuator/health}"
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'
readonly CLR_YELLOW='\033[1;33m'
readonly CLR_BLUE='\033[0;34m'
readonly CLR_NC='\033[0m'
_log_info() { echo -e "${CLR_GREEN}[INFO]${CLR_NC} $*"; }
_log_warn() { echo -e "${CLR_YELLOW}[WARN]${CLR_NC} $*" >&2; }
_log_error() { echo -e "${CLR_RED}[ERROR]${CLR_NC} $*" >&2; }
_log_step() { echo ""; echo -e "${CLR_BLUE}==== $* ====${CLR_NC}"; }
# -------------------------------------------------------------------------------
# Health Check con reintentos
# -------------------------------------------------------------------------------
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 eval "${check_cmd}"; then
_log_info "${name} - SALUDABLE"
return 0
fi
if [[ $attempt -lt $MAX_RETRIES ]]; then
_log_warn "${name} no responde, reintentando en ${RETRY_INTERVAL}s..."
sleep "${RETRY_INTERVAL}"
fi
((attempt++))
done
_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 "$@"