#!/bin/bash # ============================================================================ # SigNoz Deployment Script for Bakery IA # ============================================================================ # This script deploys SigNoz monitoring stack using Helm # Supports both development and production environments # ============================================================================ set -e # Color codes for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Function to display help show_help() { echo "Usage: $0 [OPTIONS] ENVIRONMENT" echo "" echo "Deploy SigNoz monitoring stack for Bakery IA" echo "" echo "Arguments: ENVIRONMENT Environment to deploy to (dev|prod)" echo "" echo "Options: -h, --help Show this help message -d, --dry-run Dry run - show what would be done without actually deploying -u, --upgrade Upgrade existing deployment -r, --remove Remove/Uninstall SigNoz deployment -n, --namespace NAMESPACE Specify namespace (default: bakery-ia)" echo "" echo "Examples: $0 dev # Deploy to development $0 prod # Deploy to production $0 --upgrade prod # Upgrade production deployment $0 --remove dev # Remove development deployment" echo "" echo "Docker Hub Authentication:" echo " This script automatically creates a Docker Hub secret for image pulls." echo " Provide credentials via environment variables (recommended):" echo " export DOCKERHUB_USERNAME='your-username'" echo " export DOCKERHUB_PASSWORD='your-personal-access-token'" echo " Or ensure you're logged in with Docker CLI:" echo " docker login" } # Parse command line arguments DRY_RUN=false UPGRADE=false REMOVE=false NAMESPACE="bakery-ia" while [[ $# -gt 0 ]]; do case $1 in -h|--help) show_help exit 0 ;; -d|--dry-run) DRY_RUN=true shift ;; -u|--upgrade) UPGRADE=true shift ;; -r|--remove) REMOVE=true shift ;; -n|--namespace) NAMESPACE="$2" shift 2 ;; dev|prod) ENVIRONMENT="$1" shift ;; *) echo "Unknown argument: $1" show_help exit 1 ;; esac done # Validate environment if [[ -z "$ENVIRONMENT" ]]; then echo "Error: Environment not specified. Use 'dev' or 'prod'." show_help exit 1 fi if [[ "$ENVIRONMENT" != "dev" && "$ENVIRONMENT" != "prod" ]]; then echo "Error: Invalid environment. Use 'dev' or 'prod'." exit 1 fi # Function to check if Helm is installed check_helm() { if ! command -v helm &> /dev/null; then echo "${RED}Error: Helm is not installed. Please install Helm first.${NC}" echo "Installation instructions: https://helm.sh/docs/intro/install/" exit 1 fi } # Function to check if kubectl is configured check_kubectl() { if ! kubectl cluster-info &> /dev/null; then echo "${RED}Error: kubectl is not configured or cannot connect to cluster.${NC}" echo "Please ensure you have access to a Kubernetes cluster." exit 1 fi } # Function to check if namespace exists, create if not ensure_namespace() { if ! kubectl get namespace "$NAMESPACE" &> /dev/null; then echo "${BLUE}Creating namespace $NAMESPACE...${NC}" if [[ "$DRY_RUN" == true ]]; then echo " (dry-run) Would create namespace $NAMESPACE" else kubectl create namespace "$NAMESPACE" echo "${GREEN}Namespace $NAMESPACE created.${NC}" fi else echo "${BLUE}Namespace $NAMESPACE already exists.${NC}" fi } # Function to create Docker Hub secret for image pulls create_dockerhub_secret() { echo "${BLUE}Setting up Docker Hub image pull secret...${NC}" if [[ "$DRY_RUN" == true ]]; then echo " (dry-run) Would create Docker Hub secret in namespace $NAMESPACE" return fi # Check if secret already exists if kubectl get secret dockerhub-creds -n "$NAMESPACE" &> /dev/null; then echo "${GREEN}Docker Hub secret already exists in namespace $NAMESPACE.${NC}" return fi # Check if Docker Hub credentials are available if [[ -n "$DOCKERHUB_USERNAME" ]] && [[ -n "$DOCKERHUB_PASSWORD" ]]; then echo "${BLUE}Found DOCKERHUB_USERNAME and DOCKERHUB_PASSWORD environment variables${NC}" kubectl create secret docker-registry dockerhub-creds \ --docker-server=https://index.docker.io/v1/ \ --docker-username="$DOCKERHUB_USERNAME" \ --docker-password="$DOCKERHUB_PASSWORD" \ --docker-email="${DOCKERHUB_EMAIL:-noreply@bakery-ia.local}" \ -n "$NAMESPACE" echo "${GREEN}Docker Hub secret created successfully.${NC}" elif [[ -f "$HOME/.docker/config.json" ]]; then echo "${BLUE}Attempting to use Docker CLI credentials...${NC}" # Try to extract credentials from Docker config if grep -q "credsStore" "$HOME/.docker/config.json"; then echo "${YELLOW}Docker is using a credential store. Please set environment variables:${NC}" echo " export DOCKERHUB_USERNAME='your-username'" echo " export DOCKERHUB_PASSWORD='your-password-or-token'" echo "${YELLOW}Continuing without Docker Hub authentication...${NC}" return fi # Try to extract from base64 encoded auth AUTH=$(cat "$HOME/.docker/config.json" | jq -r '.auths["https://index.docker.io/v1/"].auth // empty' 2>/dev/null) if [[ -n "$AUTH" ]]; then echo "${GREEN}Found Docker Hub credentials in Docker config${NC}" local DOCKER_USERNAME=$(echo "$AUTH" | base64 -d | cut -d: -f1) local DOCKER_PASSWORD=$(echo "$AUTH" | base64 -d | cut -d: -f2-) kubectl create secret docker-registry dockerhub-creds \ --docker-server=https://index.docker.io/v1/ \ --docker-username="$DOCKER_USERNAME" \ --docker-password="$DOCKER_PASSWORD" \ --docker-email="${DOCKERHUB_EMAIL:-noreply@bakery-ia.local}" \ -n "$NAMESPACE" echo "${GREEN}Docker Hub secret created successfully.${NC}" else echo "${YELLOW}Could not find Docker Hub credentials${NC}" echo "${YELLOW}To enable automatic Docker Hub authentication:${NC}" echo " 1. Run 'docker login', OR" echo " 2. Set environment variables:" echo " export DOCKERHUB_USERNAME='your-username'" echo " export DOCKERHUB_PASSWORD='your-password-or-token'" echo "${YELLOW}Continuing without Docker Hub authentication...${NC}" fi else echo "${YELLOW}Docker Hub credentials not found${NC}" echo "${YELLOW}To enable automatic Docker Hub authentication:${NC}" echo " 1. Run 'docker login', OR" echo " 2. Set environment variables:" echo " export DOCKERHUB_USERNAME='your-username'" echo " export DOCKERHUB_PASSWORD='your-password-or-token'" echo "${YELLOW}Continuing without Docker Hub authentication...${NC}" fi echo "" } # Function to add and update Helm repository setup_helm_repo() { echo "${BLUE}Setting up SigNoz Helm repository...${NC}" if [[ "$DRY_RUN" == true ]]; then echo " (dry-run) Would add SigNoz Helm repository" return fi # Add SigNoz Helm repository if helm repo list | grep -q "^signoz"; then echo "${BLUE}SigNoz repository already added, updating...${NC}" helm repo update signoz else echo "${BLUE}Adding SigNoz Helm repository...${NC}" helm repo add signoz https://charts.signoz.io helm repo update fi echo "${GREEN}Helm repository ready.${NC}" echo "" } # Function to deploy SigNoz deploy_signoz() { local values_file="infrastructure/helm/signoz-values-$ENVIRONMENT.yaml" if [[ ! -f "$values_file" ]]; then echo "${RED}Error: Values file $values_file not found.${NC}" exit 1 fi echo "${BLUE}Deploying SigNoz to $ENVIRONMENT environment...${NC}" echo " Using values file: $values_file" echo " Target namespace: $NAMESPACE" echo " Chart version: Latest from signoz/signoz" if [[ "$DRY_RUN" == true ]]; then echo " (dry-run) Would deploy SigNoz with:" echo " helm upgrade --install signoz signoz/signoz -n $NAMESPACE -f $values_file --wait --timeout 15m" return fi # Use upgrade --install to handle both new installations and upgrades echo "${BLUE}Installing/Upgrading SigNoz...${NC}" echo "This may take 10-15 minutes..." helm upgrade --install signoz signoz/signoz \ -n "$NAMESPACE" \ -f "$values_file" \ --wait \ --timeout 15m \ --create-namespace echo "${GREEN}SigNoz deployment completed.${NC}" echo "" # Show deployment status show_deployment_status } # Function to remove SigNoz remove_signoz() { echo "${BLUE}Removing SigNoz deployment from namespace $NAMESPACE...${NC}" if [[ "$DRY_RUN" == true ]]; then echo " (dry-run) Would remove SigNoz deployment" return fi if helm list -n "$NAMESPACE" | grep -q signoz; then helm uninstall signoz -n "$NAMESPACE" --wait echo "${GREEN}SigNoz deployment removed.${NC}" # Optionally remove PVCs (commented out by default for safety) echo "" echo "${YELLOW}Note: Persistent Volume Claims (PVCs) were NOT deleted.${NC}" echo "To delete PVCs and all data, run:" echo " kubectl delete pvc -n $NAMESPACE -l app.kubernetes.io/instance=signoz" else echo "${YELLOW}No SigNoz deployment found in namespace $NAMESPACE.${NC}" fi } # Function to show deployment status show_deployment_status() { echo "" echo "${BLUE}=== SigNoz Deployment Status ===${NC}" echo "" # Get pods echo "Pods:" kubectl get pods -n "$NAMESPACE" -l app.kubernetes.io/instance=signoz echo "" # Get services echo "Services:" kubectl get svc -n "$NAMESPACE" -l app.kubernetes.io/instance=signoz echo "" # Get ingress echo "Ingress:" kubectl get ingress -n "$NAMESPACE" -l app.kubernetes.io/instance=signoz echo "" # Show access information show_access_info } # Function to show access information show_access_info() { echo "${BLUE}=== Access Information ===${NC}" if [[ "$ENVIRONMENT" == "dev" ]]; then echo "SigNoz UI: http://monitoring.bakery-ia.local" echo "" echo "OpenTelemetry Collector Endpoints (from within cluster):" echo " gRPC: signoz-otel-collector.$NAMESPACE.svc.cluster.local:4317" echo " HTTP: signoz-otel-collector.$NAMESPACE.svc.cluster.local:4318" echo "" echo "Port-forward for local access:" echo " kubectl port-forward -n $NAMESPACE svc/signoz 8080:8080" echo " kubectl port-forward -n $NAMESPACE svc/signoz-otel-collector 4317:4317" echo " kubectl port-forward -n $NAMESPACE svc/signoz-otel-collector 4318:4318" else echo "SigNoz UI: https://monitoring.bakewise.ai" echo "" echo "OpenTelemetry Collector Endpoints (from within cluster):" echo " gRPC: signoz-otel-collector.$NAMESPACE.svc.cluster.local:4317" echo " HTTP: signoz-otel-collector.$NAMESPACE.svc.cluster.local:4318" echo "" echo "External endpoints (if exposed):" echo " Check ingress configuration for external OTLP endpoints" fi echo "" echo "Default credentials:" echo " Username: admin@example.com" echo " Password: admin" echo "" echo "Note: Change default password after first login!" echo "" } # Main execution main() { echo "${BLUE}" echo "==========================================" echo "🚀 SigNoz Deployment for Bakery IA" echo "==========================================" echo "${NC}" # Check prerequisites check_helm check_kubectl # Ensure namespace ensure_namespace if [[ "$REMOVE" == true ]]; then remove_signoz exit 0 fi # Setup Helm repository setup_helm_repo # Create Docker Hub secret for image pulls create_dockerhub_secret # Deploy SigNoz deploy_signoz echo "${GREEN}" echo "==========================================" echo "✅ SigNoz deployment completed!" echo "==========================================" echo "${NC}" } # Run main function main