Trovare e risolvere i problemi delle applicazioni con Gemini Cloud Assist

1. Introduzione

Gemini Cloud Assist è un agente completo che supporta i carichi di lavoro di Google Cloud. L'agente è il tuo partner per la progettazione di nuove applicazioni o l'aggiornamento di quelle esistenti, il deployment e l'esecuzione di carichi di lavoro in Google Cloud, la risoluzione dei problemi dei carichi di lavoro e l'ottimizzazione per costi e prestazioni.

Gemini Cloud Assist migliora la tua capacità di rispondere a errori imprevisti e tempi di inattività.

Cosa imparerai a fare

  1. Deployment: come eseguire il deployment di un backend e di un database di base su Google Cloud.
  2. Debug: come Gemini Cloud Assist automatizza l'indagine e l'analisi della causa principale dei problemi di codice e cloud.
  3. Correzione: come Gemini Cloud Assist aiuta a identificare le correzioni in base alla causa principale.

2. Configurazione del progetto

Account Google

Se non hai già un Account Google personale, devi creare un Account Google.

Utilizza un account personale anziché un account di lavoro o della scuola.

Accedi alla console Google Cloud

Accedi alla console Google Cloud utilizzando un Account Google personale.

Abilita fatturazione

Configura un account di fatturazione personale

Se hai configurato la fatturazione utilizzando i crediti Google Cloud, puoi saltare questo passaggio.

Per configurare un account di fatturazione personale, vai qui per abilitare la fatturazione nella console Cloud.

Alcune note:

  • Il completamento di questo lab dovrebbe costare meno di 1 $in risorse cloud.
  • Puoi seguire i passaggi alla fine di questo lab per eliminare le risorse ed evitare ulteriori addebiti.
  • I nuovi utenti possono usufruire della prova senza costi di 300$.

Creare un progetto (facoltativo)

Se non hai un progetto attuale che vuoi utilizzare per questo lab, creane uno nuovo qui.

3. Apri editor di Cloud Shell

  1. Fai clic su questo link per passare direttamente all'editor di Cloud Shell
  2. Se ti viene chiesto di autorizzare in qualsiasi momento, fai clic su Autorizza per continuare.Fai clic per autorizzare Cloud Shell
  3. Se il terminale non viene visualizzato nella parte inferiore dello schermo, aprilo:
    • Fai clic su Visualizza
    • Fai clic su TerminaleApri un nuovo terminale nell'editor di Cloud Shell
  4. Nel terminale, imposta il progetto con questo comando:
    gcloud config set project [PROJECT_ID]
    
    • Esempio:
      gcloud config set project lab-project-id-example
      
    • Se non ricordi l'ID progetto, puoi elencare tutti gli ID progetto con:
      gcloud projects list
      
      Imposta l'ID progetto nel terminale dell'editor di Cloud Shell
  5. Dovresti visualizzare questo messaggio:
    Updated property [core/project].
    

4. Abilita API

Abilita le seguenti API per eseguire il deployment dei componenti dell'applicazione e per utilizzare Google Cloud Assist:

Nel terminale, abilita le API:

```bash
gcloud services enable \
  container.googleapis.com \
  artifactregistry.googleapis.com \
  cloudbuild.googleapis.com \
  alloydb.googleapis.com \
  run.googleapis.com
```
<br>
When the command finishes, you should see an output like the following: 
<br>

```console
Operation "operations/acf.p2-176675280136-b03ab5e4-3483-4ebf-9655-43dc3b345c63" finished successfully.
```

5. Prepara il progetto

Creerai l'applicazione e il deployment di base per testare Cloud Assist.

Crea la directory

  1. Apri l'editor di Cloud Shell o l'ambiente di sviluppo che preferisci.
  2. Crea una nuova cartella:
    mkdir -p ~/gemini-cloud-assist-debug
    mkdir -p ~/gemini-cloud-assist-debug/auth_issue_demo
    mkdir -p ~/gemini-cloud-assist-debug/terraform
    cd ~/gemini-cloud-assist-debug
    
  3. Nel terminale, esegui il seguente comando per aprire uno spazio di lavoro dell'editor di Cloud Shell:
cloudshell open-workspace ~/gemini-cloud-assist-debug

Crea i file

Ora creerai i file di avvio necessari per l'applicazione.

  1. Crea il Dockerfile eseguendo il seguente comando nel terminale. Questo file gestisce la creazione del container dell'applicazione.
cat <<EOF > ~/gemini-cloud-assist-debug/auth_issue_demo/Dockerfile
FROM python:3.11-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY main.py .

CMD ["gunicorn", "--bind", "0.0.0.0:8080", "main:app"]
EOF
  1. Crea il file main.py eseguendo il seguente comando nel terminale. Questo file contiene l'applicazione scritta in Python.
cat <<EOF > ~/gemini-cloud-assist-debug/auth_issue_demo/main.py
import os
import logging
from flask import Flask
from google.cloud.alloydb.connector import Connector
import sqlalchemy

app = Flask(__name__)

# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# Configuration from Environment Variables
# The fully qualified instance URI: projects/<PROJECT>/locations/<REGION>/clusters/<CLUSTER>/instances/<INSTANCE>
ALLOYDB_URI = os.environ.get("ALLOYDB_URI") 
DB_USER = os.environ.get("DB_USER", "auth-debug")
DB_PASS = os.environ.get("DB_PASS", "debug-auth")
DB_NAME = os.environ.get("DB_NAME", "postgres")
USE_PUBLIC_IP = os.environ.get("USE_PUBLIC_IP", "false").lower() == "true"

# Initialize Connector lazily
_connector = None

def get_connector():
    global _connector
    if _connector is None:
        _connector = Connector()
    return _connector

def getconn():
    connector = get_connector()
    ip_type = "PUBLIC" if USE_PUBLIC_IP else "PRIVATE"
    
    conn = connector.connect(
        ALLOYDB_URI,
        "pg8000",
        user=DB_USER,
        password=DB_PASS,
        db=DB_NAME,
        ip_type=ip_type
    )
    return conn

@app.route("/")
def index():
    return "AlloyDB Auth Demo. /connect to test.", 200

@app.route("/connect")
def connect_db():
    if not ALLOYDB_URI:
        return "FAILURE: ALLOYDB_URI env var is not set.", 500

    try:
        logger.info(f"Attempting connection to {ALLOYDB_URI} with user {DB_USER}...")
        
        # Create connection pool
        pool = sqlalchemy.create_engine(
            "postgresql+pg8000://",
            creator=getconn,
        )
        
        with pool.connect() as db_conn:
            # Simple query to validate connection
            result = db_conn.execute(sqlalchemy.text("SELECT NOW()")).fetchone()
            timestamp = result[0]
            
        msg = f"SUCCESS: Connected to AlloyDB! DB Time: {timestamp}"
        logger.info(msg)
        return msg, 200

    except Exception as e:
        logger.exception("Connection failed")
        # Return the error to the caller to visualize the auth failure
        return f"FAILURE: Connection Error.\nDetails: {str(e)}", 500

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=int(os.environ.get("PORT", 8080)))
EOF
  1. Crea il file requirements.txt eseguendo il seguente comando nel terminale. Questo file gestisce i requisiti dei pacchetti Python.
cat <<EOF > ~/gemini-cloud-assist-debug/auth_issue_demo/requirements.txt
flask==3.1.3
gunicorn==25.3.0
google-cloud-alloydb-connector[pg8000]==1.12.1
sqlalchemy==2.0.49
EOF
  1. Crea il file main.tf eseguendo il seguente comando nel terminale. Questo file gestisce le risorse Google Cloud da creare.
cat <<EOF > ~/gemini-cloud-assist-debug/terraform/main.tf
provider "google" {
  project = var.project_id
  region  = var.region
}

# Enable APIs
locals {
  apis = [
    "alloydb.googleapis.com",
    "run.googleapis.com",
    "artifactregistry.googleapis.com",
    "compute.googleapis.com",
    "geminicloudassist.googleapis.com",
    "monitoring.googleapis.com",
    "cloudasset.googleapis.com",
    "cloudbuild.googleapis.com",
    "recommender.googleapis.com",
    "appoptimize.googleapis.com"
  ]
}

resource "random_password" "db_pass" {
  count            = var.db_password == null ? 1 : 0
  length           = 16
  special          = true
  override_special = "!#$%&*()-_=+[]{}<>:?"
}

locals {
  db_password = var.db_password != null ? var.db_password : random_password.db_pass[0].result
}

resource "google_project_service" "apis" {
  for_each           = toset(local.apis)
  service            = each.value
  disable_on_destroy = false
}

# Service Account
resource "google_service_account" "auth_demo_sa" {
  account_id   = var.service_account_name
  display_name = "Auth Demo SA"
}

# AlloyDB Cluster
resource "google_alloydb_cluster" "rma_cluster" {
  cluster_id = var.cluster_id
  location   = var.region

  # Initial password, managed via variable or generated randomly
  initial_user {
    password = local.db_password
  }

  # Use default network as in the manual setup
  network_config {
    network = "projects/${var.project_id}/global/networks/default"
  }

  depends_on = [google_project_service.apis["alloydb.googleapis.com"]]
}

# AlloyDB Instance
resource "google_alloydb_instance" "rma_instance_1" {
  cluster       = google_alloydb_cluster.rma_cluster.name
  instance_id   = var.instance_id
  instance_type = "PRIMARY"

  machine_config {
    cpu_count = 2
  }

  network_config {
    enable_public_ip = true
  }

  depends_on = [google_alloydb_cluster.rma_cluster]
}

# Cloud Run Service
resource "google_cloud_run_service" "auth_issue_demo" {
  name     = var.cloud_run_service_name
  location = var.region

  template {
    spec {
      containers {
        image = var.cloud_run_image
        env {
          name  = "ALLOYDB_URI"
          value = "projects/${var.project_id}/locations/${var.region}/clusters/${var.cluster_id}/instances/${var.instance_id}"
        }
        env {
          name  = "DB_USER"
          value = "postgres"
        }
        env {
          name  = "DB_PASS"
          value = local.db_password
        }
        env {
          name  = "USE_PUBLIC_IP"
          value = "true"
        }
      }
      service_account_name = google_service_account.auth_demo_sa.email
    }
  }

  traffic {
    percent         = 100
    latest_revision = true
  }

  depends_on = [google_project_service.apis["run.googleapis.com"], google_alloydb_instance.rma_instance_1]
}

# Allow unauthenticated access to Cloud Run service (matching --allow-unauthenticated)
resource "google_cloud_run_service_iam_member" "public_access" {
  location = google_cloud_run_service.auth_issue_demo.location
  project  = google_cloud_run_service.auth_issue_demo.project
  service  = google_cloud_run_service.auth_issue_demo.name
  role     = "roles/run.invoker"
  member   = "allUsers"
}
EOF
  1. Crea il file variables.tf eseguendo il seguente comando nel terminale. Questo file gestisce le variabili Terraform per le risorse Google Cloud.
cat <<EOF > ~/gemini-cloud-assist-debug/terraform/variables.tf
variable "project_id" {
  description = "The ID of the Google Cloud project."
  type        = string
}

variable "region" {
  description = "The region to deploy resources in."
  type        = string
  default     = "us-central1"
}

variable "cluster_id" {
  description = "The ID of the AlloyDB cluster."
  type        = string
  default     = "rma-cluster"
}

variable "instance_id" {
  description = "The ID of the AlloyDB instance."
  type        = string
  default     = "rma-instance-1"
}

variable "service_account_name" {
  description = "The name of the service account."
  type        = string
  default     = "auth-demo-sa"
}

variable "cloud_run_service_name" {
  description = "The name of the Cloud Run service."
  type        = string
  default     = "auth-issue-demo"
}

variable "cloud_run_image" {
  description = "The container image for the Cloud Run service."
  type        = string
}

variable "db_password" {
  description = "The database password. If not provided, a random one will be generated."
  type        = string
  sensitive   = true
  default     = null
}
EOF
  1. Crea il file setup_via_tf.sh eseguendo il seguente comando nel terminale. Questo file gestisce i requisiti dei pacchetti Python.
cat <<EOF > ~/gemini-cloud-assist-debug/setup_via_tf.sh
#!/bin/bash
set -e

# Get script directory and change to project root
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd "$SCRIPT_DIR"

# Load configuration from .env
if [ -f .env ]; then
    set -a
    source .env
    set +a
else
    echo "ERROR: .env file not found. Please create one with PROJECT_ID."
    exit 1
fi

if [ -z "$PROJECT_ID" ]; then
    echo "ERROR: PROJECT_ID is not set in .env file."
    exit 1
fi

REGION="us-central1"
CLUSTER_ID="rma-cluster"
INSTANCE_ID="rma-instance-1"
SA_NAME="auth-demo-sa"
SERVICE_NAME="auth-issue-demo"

echo "--- Terraform Setup for Auth Demo ---"
echo "Using Project: $PROJECT_ID"

# Get current Cloud Run image
echo "Fetching current Cloud Run image..."
IMAGE=$(gcloud run services describe $SERVICE_NAME --region=$REGION --project=$PROJECT_ID --format="value(spec.template.spec.containers[0].image)" 2>/dev/null || true)

if [ -z "$IMAGE" ]; then
    echo "WARNING: Could not find existing Cloud Run service image."
    echo "Using a placeholder image (gcr.io/cloudrun/hello) for initial Terraform apply."
    IMAGE="gcr.io/cloudrun/hello"
fi

echo "Found Image: $IMAGE"

cd terraform

# Initialize Terraform
echo "Initializing Terraform..."
terraform init

echo "Formatting Terraform files..."
terraform fmt

echo "Validating Terraform configuration..."
terraform validate

echo "------------------------------------------------"
echo "Applying changes..."
echo "------------------------------------------------"

terraform apply -var="project_id=$PROJECT_ID" -var="cloud_run_image=$IMAGE" -auto-approve

echo "------------------------------------------------"
echo "Building and deploying updated Cloud Run service..."
echo "------------------------------------------------"

gcloud run deploy $SERVICE_NAME \
  --source ../auth_issue_demo \
  --region $REGION \
  --project $PROJECT_ID \
  --service-account $SA_NAME@$PROJECT_ID.iam.gserviceaccount.com \
  --quiet
EOF
  1. Esegui il seguente comando per rendere eseguibile lo script della shell:
chmod +x ~/gemini-cloud-assist-debug/setup_via_tf.sh
  1. Crea un file .env contenente l'ID progetto Google Cloud per il deployment. Aggiorna il campo YOUR_PROJECT_ID:
cat <<EOF > ~/gemini-cloud-assist-debug/.env
PROJECT_ID=YOUR_PROJECT_ID
USE_PUBLIC_IP=true
EOF

6. Esegui il deployment dell'applicazione

Il codice dell'applicazione e le risorse Google Cloud sono pronti per il deployment. L'operazione potrebbe richiedere fino a 15 minuti.

Esegui questo comando dal terminale:

cd ~/gemini-cloud-assist-debug
./setup_via_tf.sh

Durante il deployment dei componenti, sfoglia i file nell'editor di Cloud Shell per saperne di più.

7. Crea ed esegui il debug di un errore

Ora attiveremo un errore dall'applicazione. Apri Cloud Run nel riquadro a sinistra. Quindi, fai clic sul servizio auth-issue-demo.

  1. Nella parte superiore della pagina Dettagli servizio è presente un URL. Copia l'URL e apri una nuova scheda del browser. Incolla l'URL e aggiungi /connect. L'URL avrà un aspetto simile al seguente:

https://auth-issue-demo-.us-central1.run.app/connect

  1. Vai all'URL. L'avvio dell'istanza di Cloud Run potrebbe richiedere alcuni secondi. Riceverai un errore.
  2. Torna alla pagina dei dettagli del servizio Cloud Run. Fai clic su Osservabilità, quindi su Log. Vedrai i log del container, incluso un errore. Se il log degli errori non è ancora disponibile, attendi qualche secondo e aggiorna la pagina utilizzando l'icona in alto a destra.
  3. Fai clic sul log degli errori per saperne di più. Fai clic sull'icona Indaga nella riga del log principale. Quindi, fai clic su Indaga sul log.

Si apre il riquadro della chat di Cloud Assist. Il completamento dell'indagine richiede 2-3 minuti.

Al termine dell'indagine, puoi leggere i risultati e i consigli. È consigliabile aggiungere la concessione appropriata al service account per consentire a Cloud Run di accedere all'istanza di AlloyDB.

8. Correggi l'errore

Correggi l'errore di autorizzazione del service account.

  1. Vai a Cloud IAM.
  2. Fai clic sul pulsante Concedi accesso. Nel riquadro dell'entità, inizia a digitare auth-demo e attendi che venga visualizzato il service account.
  3. Poi, aggiungi il ruolo AlloyDB Client al service account e fai clic su Salva.

La propagazione richiede fino a un minuto.

Dopo aver atteso, torna indietro e aggiorna l'applicazione. Ora vedrai un messaggio di conferma dalla banca dati AlloyDB.

9. Complimenti

Complimenti! Hai completato l'introduzione a Indagini cloud e alla procedura di debug delle autorizzazioni di un'applicazione su Google Cloud.

Passaggi successivi