#!/bin/bash # Continuous Deployment Script for Kubernetes # This script deploys your application to a Kubernetes cluster # ============================================================================= # Environment Variables (with default values) # ============================================================================= # Kubernetes Configuration KUBECONFIG_DATA="${KUBECONFIG_DATA:-}" KUBERNETES_URL="${KUBERNETES_URL:-https://kubernetes.default.svc}" KUBERNETES_NAMESPACE="${KUBERNETES_NAMESPACE:-default}" KUBERNETES_INGRESS_HOST="${KUBERNETES_INGRESS_HOST:-example.com}" # Container Registry (inherited from ci.sh) CONTAINER_REGISTRY_URL="${CONTAINER_REGISTRY_URL:-127.0.0.1}" CONTAINER_REGISTRY_USERNAME="${CONTAINER_REGISTRY_USERNAME:-username}" CONTAINER_REGISTRY_NAMESPACE="${CONTAINER_REGISTRY_NAMESPACE:-username}" CONTAINER_REGISTRY_PASSWORD="${CONTAINER_REGISTRY_PASSWORD:-password}" CONTAINER_IMAGE_NAME="${CONTAINER_IMAGE_NAME:-image-name}" CONTAINER_IMAGE_TAG="${CONTAINER_IMAGE_TAG:-latest}" FORCE_RESTART="${FORCE_RESTART:-true}" # ============================================================================= # Functions # ============================================================================= # Print help message print_help() { echo "Usage: $0 [OPTIONS]" echo "" echo "Options:" echo " deploy Deploy application to Kubernetes" echo " help Show this help message (default)" echo "" echo "Environment Variables:" echo " KUBECONFIG_DATA Base64 encoded kubeconfig file" echo " KUBERNETES_URL Kubernetes API server URL" echo " KUBERNETES_NAMESPACE Deploy namespace (default: default)" echo " KUBERNETES_INGRESS_HOST Ingress host (default: example.com)" echo "" echo " Container Registry Variables (from ci.sh):" echo " CONTAINER_REGISTRY_URL" echo " CONTAINER_REGISTRY_USERNAME" echo " CONTAINER_REGISTRY_NAMESPACE" echo " CONTAINER_REGISTRY_PASSWORD" echo " CONTAINER_IMAGE_NAME" echo " CONTAINER_IMAGE_TAG" echo " FORCE_RESTART Force rollout restart (default: true)" echo "" echo "Examples:" echo " $0 deploy" echo " KUBERNETES_NAMESPACE=production $0 deploy" } # Setup Kubernetes configuration setup_kubeconfig() { echo "==========================================" echo "Setting up Kubernetes Configuration" echo "==========================================" # Check if KUBECONFIG_DATA is provided if [ -z "$KUBECONFIG_DATA" ]; then echo "Warning: KUBECONFIG_DATA not provided, using existing kubectl config" return 0 fi # Create temporary kubeconfig file from base64 encoded data echo "Decoding kubeconfig..." echo "$KUBECONFIG_DATA" | base64 -d > /tmp/kubeconfig # Set KUBECONFIG environment variable to use the temporary file export KUBECONFIG=/tmp/kubeconfig echo "✓ Kubeconfig configured" echo "" } # Create Docker registry secret for pulling private images create_registry_secret() { echo "==========================================" echo "Creating Docker Registry Secret" echo "==========================================" # Create or update the docker registry secret in the namespace kubectl create secret docker-registry regcred \ --docker-server="${CONTAINER_REGISTRY_URL}" \ --docker-username="${CONTAINER_REGISTRY_USERNAME}" \ --docker-password="${CONTAINER_REGISTRY_PASSWORD}" \ --namespace="${KUBERNETES_NAMESPACE}" \ --dry-run=client -o yaml | kubectl apply -f - if [ $? -eq 0 ]; then echo "✓ Registry secret created/updated" echo "" else echo "✗ Failed to create registry secret" exit 1 fi } # Deploy application to Kubernetes deploy_application() { # Construct the full image name FULL_IMAGE_NAME="${CONTAINER_REGISTRY_URL}/${CONTAINER_REGISTRY_NAMESPACE}/${CONTAINER_IMAGE_NAME}:${CONTAINER_IMAGE_TAG}" echo "==========================================" echo "Deploying Application to Kubernetes" echo "==========================================" echo "Namespace: ${KUBERNETES_NAMESPACE}" echo "Image: ${FULL_IMAGE_NAME}" echo "Ingress Host: ${KUBERNETES_INGRESS_HOST}" echo "" # Setup kubeconfig setup_kubeconfig # Test kubectl connection echo "Testing Kubernetes connection..." kubectl cluster-info > /dev/null 2>&1 if [ $? -ne 0 ]; then echo "✗ Failed to connect to Kubernetes cluster" exit 1 fi echo "✓ Connected to Kubernetes cluster" echo "" # Create namespace if it doesn't exist echo "Creating namespace..." envsubst < script/k8s/namespace.yaml | kubectl apply -f - echo "" # Create registry secret for pulling images create_registry_secret # Export environment variables for envsubst (template substitution) export KUBERNETES_NAMESPACE export KUBERNETES_INGRESS_HOST export FULL_IMAGE_NAME # Apply Kubernetes manifests with environment variable substitution echo "Applying Kubernetes manifests..." # Apply deployment echo "- Applying deployment..." envsubst < script/k8s/deployment.yaml | kubectl apply -f - # Apply service echo "- Applying service..." envsubst < script/k8s/service.yaml | kubectl apply -f - # Apply ingress echo "- Applying ingress..." envsubst < script/k8s/ingress.yaml | kubectl apply -f - echo "" # Wait for deployment to be ready echo "Waiting for deployment to be ready..." # Force restart if enabled if [ "${FORCE_RESTART}" = "true" ]; then echo "Forcing rollout restart..." kubectl rollout restart deployment/${CONTAINER_IMAGE_NAME} -n ${KUBERNETES_NAMESPACE} fi kubectl rollout status deployment/${CONTAINER_IMAGE_NAME} \ -n ${KUBERNETES_NAMESPACE} \ --timeout=300s if [ $? -eq 0 ]; then echo "" echo "==========================================" echo "✓ Deployment Successful!" echo "==========================================" echo "Application: ${CONTAINER_IMAGE_NAME}" echo "Namespace: ${KUBERNETES_NAMESPACE}" echo "URL: http://${KUBERNETES_INGRESS_HOST}" echo "" # Show pod status echo "Pod Status:" kubectl get pods -n ${KUBERNETES_NAMESPACE} -l app=${CONTAINER_IMAGE_NAME} echo "" # Show service status echo "Service Status:" kubectl get svc -n ${KUBERNETES_NAMESPACE} -l app=${CONTAINER_IMAGE_NAME} echo "" # Show ingress status echo "Ingress Status:" kubectl get ingress -n ${KUBERNETES_NAMESPACE} else echo "" echo "✗ Deployment failed or timed out" exit 1 fi # Cleanup temporary kubeconfig if it was created if [ -f /tmp/kubeconfig ]; then rm -f /tmp/kubeconfig fi } # ============================================================================= # Main Script Logic # ============================================================================= # If no arguments provided, show help if [ $# -eq 0 ]; then print_help exit 0 fi # Process command line arguments case "$1" in deploy) deploy_application ;; help|--help|-h) print_help ;; *) echo "Error: Unknown option '$1'" echo "" print_help exit 1 ;; esac