#!/bin/bash # Deploy Identity Service with Entra VerifiedID to Production # Uses blue-green deployment strategy for zero downtime set -euo pipefail GREEN='\033[0;32m' BLUE='\033[0;34m' YELLOW='\033[1;33m' RED='\033[0;31m' NC='\033[0m' log_info() { echo -e "${BLUE}[INFO]${NC} $1"; } log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; } log_warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; } log_error() { echo -e "${RED}[ERROR]${NC} $1"; } cd "$(dirname "$0")/../.." # Safety check log_warning "This will deploy to PRODUCTION. Are you sure?" read -p "Type 'deploy-production' to confirm: " CONFIRM if [ "${CONFIRM}" != "deploy-production" ]; then log_error "Deployment cancelled" exit 1 fi # Check prerequisites log_info "Checking prerequisites..." if ! command -v kubectl &> /dev/null; then log_error "kubectl not found" exit 1 fi if ! kubectl cluster-info &> /dev/null; then log_error "Not connected to Kubernetes cluster" exit 1 fi NAMESPACE="the-order-prod" # Verify production namespace if ! kubectl get namespace "${NAMESPACE}" &> /dev/null; then log_error "Production namespace not found: ${NAMESPACE}" exit 1 fi # Verify secrets exist log_info "Verifying Entra secrets..." if ! kubectl get secret entra-verifiedid-secrets -n "${NAMESPACE}" &> /dev/null; then log_error "Entra secrets not found in production!" log_info "Create secrets first: kubectl apply -f infra/k8s/identity-service-entra-secrets.yaml -n ${NAMESPACE}" exit 1 fi # Build and push image IMAGE_TAG="prod-$(date +%Y%m%d-%H%M%S)" IMAGE_NAME="ghcr.io/the-order/identity-service:${IMAGE_TAG}" log_info "Building production image: ${IMAGE_NAME}" docker build -t "${IMAGE_NAME}" -f services/identity/Dockerfile . docker push "${IMAGE_NAME}" log_success "Image built and pushed" # Blue-Green Deployment Strategy log_info "Starting blue-green deployment..." # Create green deployment log_info "Creating green deployment..." sed "s|ghcr.io/the-order/identity-service:latest|${IMAGE_NAME}|g" \ infra/k8s/identity-service-deployment-entra.yaml | \ sed 's/name: identity-service/name: identity-service-green/' | \ sed 's/app: identity-service/app: identity-service-green/' > /tmp/identity-green.yaml kubectl apply -f /tmp/identity-green.yaml -n "${NAMESPACE}" # Wait for green to be ready log_info "Waiting for green deployment to be ready..." kubectl rollout status deployment/identity-service-green -n "${NAMESPACE}" --timeout=10m # Health check on green log_info "Running health checks on green deployment..." GREEN_POD=$(kubectl get pod -n "${NAMESPACE}" -l app=identity-service-green -o jsonpath='{.items[0].metadata.name}') if kubectl exec -n "${NAMESPACE}" "${GREEN_POD}" -- curl -sf http://localhost:4002/health > /dev/null; then log_success "Green deployment is healthy" else log_error "Green deployment health check failed!" log_info "Rolling back..." kubectl delete deployment identity-service-green -n "${NAMESPACE}" exit 1 fi # Switch traffic to green log_info "Switching traffic to green deployment..." kubectl patch service identity-service -n "${NAMESPACE}" -p '{"spec":{"selector":{"app":"identity-service-green"}}}' # Wait and verify sleep 10 log_info "Verifying service after switch..." if curl -sf https://api.theorder.org/health > /dev/null; then log_success "Service is responding" else log_warning "Service health check failed (may need more time)" fi # Scale down blue (old) deployment log_info "Scaling down blue deployment..." if kubectl get deployment identity-service -n "${NAMESPACE}" &> /dev/null; then kubectl scale deployment identity-service -n "${NAMESPACE}" --replicas=0 log_success "Blue deployment scaled down" fi # Rename green to main log_info "Promoting green to main deployment..." kubectl delete deployment identity-service -n "${NAMESPACE}" 2>/dev/null || true kubectl patch deployment identity-service-green -n "${NAMESPACE}" -p '{"metadata":{"name":"identity-service"},"spec":{"selector":{"matchLabels":{"app":"identity-service"}}},"template":{"metadata":{"labels":{"app":"identity-service"}}}}' kubectl patch service identity-service -n "${NAMESPACE}" -p '{"spec":{"selector":{"app":"identity-service"}}}' log_success "Production deployment complete!" log_info "Deployment details:" kubectl get deployment identity-service -n "${NAMESPACE}" kubectl get pods -n "${NAMESPACE}" -l app=identity-service log_info "Next steps:" echo "1. Monitor metrics: kubectl logs -n ${NAMESPACE} deployment/identity-service -f | grep entra" echo "2. Verify webhook URL: https://api.theorder.org/vc/entra/webhook" echo "3. Test credential issuance" echo "4. Monitor for 24 hours"