#!/usr/bin/env bash # ============================================================================== # Script de Déploiement Automatisé du Microservice FastAPI sur Google Cloud Run # ============================================================================== # Ingrédients : Google Artifact Registry + GCP Secret Manager + Google Cloud Run # Usage : ./deploy_gcp_cloud_run.sh [--dry-run] [--region europe-west1] [--project-id MON_PROJET] # ============================================================================== set -euo pipefail # Configuration par défaut REGION="europe-west1" SERVICE_NAME="traducteur-i18n-api" REPO_NAME="traducteur-i18n-repo" IMAGE_NAME="fastapi-api" DRY_RUN=false PROJECT_ID="" # Traitement des arguments CLI while [[ $# -gt 0 ]]; do case "$1" in --dry-run) DRY_RUN=true shift ;; --region) REGION="$2" shift 2 ;; --project-id) PROJECT_ID="$2" shift 2 ;; --help|-h) echo "Usage: ./deploy_gcp_cloud_run.sh [OPTIONS]" echo "" echo "Options:" echo " --dry-run Affiche les commandes gcloud sans les exécuter." echo " --region REGION Région Google Cloud (défaut: europe-west1)." echo " --project-id ID ID du projet GCP (détecté via gcloud si omis)." echo " --help, -h Affiche ce manuel d'aide." exit 0 ;; *) echo "Option inconnue : $1" echo "Utilisez --help pour afficher les options disponibles." exit 1 ;; esac done echo "======================================================================" echo "🚀 PRÉPARATION DU DÉPLOIEMENT GOOGLE CLOUD RUN (MICROSERVICE FASTAPI)" echo "======================================================================" # Détection de l'ID projet GCP si non spécifié if [ -z "$PROJECT_ID" ]; then if command -v gcloud &> /dev/null; then PROJECT_ID=$(gcloud config get-value project 2>/dev/null || true) fi if [ -z "$PROJECT_ID" ]; then PROJECT_ID="project-a4d4c6a4-fc22-4805-aec" fi fi IMAGE_URI="${REGION}-docker.pkg.dev/${PROJECT_ID}/${REPO_NAME}/${IMAGE_NAME}:latest" echo "📌 Projet GCP ID : ${PROJECT_ID}" echo "📌 Région Cloud : ${REGION}" echo "📌 Service Name : ${SERVICE_NAME}" echo "📌 Target Image : ${IMAGE_URI}" echo "📌 Mode Simulé : ${DRY_RUN}" echo "----------------------------------------------------------------------" run_cmd() { if [ "$DRY_RUN" = true ]; then echo "[DRY-RUN] $" "$@" else echo "➜ Executing: $" "$@" "$@" fi } echo "Step 1/5 : Activation des APIs Google Cloud requises (Artifact Registry, Cloud Run, Secret Manager, Cloud Build)..." run_cmd gcloud services enable \ artifactregistry.googleapis.com \ run.googleapis.com \ secretmanager.googleapis.com \ cloudbuild.googleapis.com \ --project="${PROJECT_ID}" echo "Step 2/5 : Création du dépôt Google Artifact Registry (si absent)..." run_cmd gcloud artifacts repositories create "${REPO_NAME}" \ --repository-format=docker \ --location="${REGION}" \ --description="Dépôt Docker pour le Microservice Traducteur i18n FastAPI" \ --project="${PROJECT_ID}" || true echo "Step 3/5 : Configuration du Bucket Staging & Build Docker via Cloud Build..." STAGING_BUCKET="gs://traducteur-i18n-builds-${PROJECT_ID}" if [ "$DRY_RUN" = true ]; then echo "[DRY-RUN] $ gcloud storage buckets create ${STAGING_BUCKET} --location=${REGION} --project=${PROJECT_ID}" echo "[DRY-RUN] $ gcloud builds submit --gcs-source-staging-dir=${STAGING_BUCKET}/source --tag=${IMAGE_URI} --project=${PROJECT_ID} ." else gcloud storage buckets create "${STAGING_BUCKET}" --location="${REGION}" --project="${PROJECT_ID}" || true # Octroi des permissions au service d'exécution Cloud Build sur le bucket Staging PROJECT_NUM=$(gcloud projects describe "${PROJECT_ID}" --format="value(projectNumber)" 2>/dev/null || echo "") if [ -n "$PROJECT_NUM" ]; then gcloud storage buckets add-iam-policy-binding "${STAGING_BUCKET}" \ --member="serviceAccount:${PROJECT_NUM}-compute@developer.gserviceaccount.com" \ --role="roles/storage.admin" || true gcloud storage buckets add-iam-policy-binding "${STAGING_BUCKET}" \ --member="serviceAccount:${PROJECT_NUM}@cloudbuild.gserviceaccount.com" \ --role="roles/storage.admin" || true fi gcloud builds submit \ --gcs-source-staging-dir="${STAGING_BUCKET}/source" \ --tag="${IMAGE_URI}" \ --project="${PROJECT_ID}" \ . fi echo "Step 4/5 : Configuration du Secret GCP pour la clé GEMINI_API_KEY (si présente dans .env)..." if [ -f .env ] && grep -q "^GEMINI_API_KEY=" .env; then SECRET_VAL=$(grep "^GEMINI_API_KEY=" .env | cut -d '=' -f2- | tr -d '"' | tr -d "'") if [ -n "$SECRET_VAL" ]; then echo "Clé GEMINI_API_KEY trouvée dans .env. Enregistrement dans GCP Secret Manager..." PROJECT_NUM=$(gcloud projects describe "${PROJECT_ID}" --format="value(projectNumber)" 2>/dev/null || echo "") if [ "$DRY_RUN" = true ]; then echo "[DRY-RUN] $ echo -n '***' | gcloud secrets versions add GEMINI_API_KEY --data-file=- --project=${PROJECT_ID}" if [ -n "$PROJECT_NUM" ]; then echo "[DRY-RUN] $ gcloud secrets add-iam-policy-binding GEMINI_API_KEY --member=serviceAccount:${PROJECT_NUM}-compute@developer.gserviceaccount.com --role=roles/secretmanager.secretAccessor --project=${PROJECT_ID}" fi else run_cmd gcloud secrets create GEMINI_API_KEY \ --replication-policy="automatic" \ --project="${PROJECT_ID}" || true echo -n "${SECRET_VAL}" | gcloud secrets versions add GEMINI_API_KEY --data-file=- --project="${PROJECT_ID}" || true if [ -n "$PROJECT_NUM" ]; then run_cmd gcloud secrets add-iam-policy-binding GEMINI_API_KEY \ --member="serviceAccount:${PROJECT_NUM}-compute@developer.gserviceaccount.com" \ --role="roles/secretmanager.secretAccessor" \ --project="${PROJECT_ID}" || true fi fi fi fi echo "Step 5/5 : Déploiement Serverless sur Google Cloud Run..." run_cmd gcloud run deploy "${SERVICE_NAME}" \ --image="${IMAGE_URI}" \ --platform=managed \ --region="${REGION}" \ --allow-unauthenticated \ --port=8000 \ --set-secrets="GEMINI_API_KEY=GEMINI_API_KEY:latest" \ --cpu=1 \ --memory=512Mi \ --concurrency=80 \ --project="${PROJECT_ID}" echo "======================================================================" if [ "$DRY_RUN" = true ]; then echo "✅ [DRY-RUN] Script de déploiement Google Cloud Run validé avec succès !" else echo "🎉 DÉPLOIEMENT CLOUD RUN TERMINÉ AVEC SUCCÈS !" echo "🌐 Documentation Swagger API : https://${SERVICE_NAME}-xxxx-${REGION}.a.run.app/docs" echo "💚 Healthcheck Probe : https://${SERVICE_NAME}-xxxx-${REGION}.a.run.app/health" fi echo "======================================================================"