Menemukan dan memperbaiki masalah aplikasi dengan Gemini Cloud Assist

1. Pengantar

Gemini Cloud Assist adalah agen berfitur lengkap yang mendukung workload Google Cloud Anda. Agen ini adalah partner Anda untuk mendesain aplikasi baru atau memperbarui aplikasi yang ada, men-deploy dan menjalankan workload di Google Cloud, memecahkan masalah workload, serta mengoptimalkannya untuk biaya dan performa.

Gemini Cloud Assist meningkatkan kemampuan Anda untuk merespons error dan periode nonaktif yang tidak terduga.

Yang akan Anda pelajari

  1. Deployment: Cara men-deploy backend dan database dasar ke Google Cloud.
  2. Debug: Cara Gemini Cloud Assist mengotomatiskan investigasi dan analisis akar masalah terkait masalah cloud dan kode.
  3. Perbaikan: Cara Gemini Cloud Assist membantu mengidentifikasi perbaikan berdasarkan akar masalah.

2. Penyiapan project

Akun Google

Jika belum memiliki Akun Google pribadi, Anda harus membuat Akun Google.

Gunakan akun pribadi, bukan akun kantor atau sekolah.

Login ke Konsol Google Cloud

Login ke Konsol Google Cloud menggunakan Akun Google pribadi.

Aktifkan Penagihan

Menyiapkan akun penagihan pribadi

Jika menyiapkan penagihan menggunakan kredit Google Cloud, Anda dapat melewati langkah ini.

Untuk menyiapkan akun penagihan pribadi, buka di sini untuk mengaktifkan penagihan di Cloud Console.

Beberapa Catatan:

  • Menyelesaikan lab ini akan dikenai biaya kurang dari $1 USD untuk resource Cloud.
  • Anda dapat mengikuti langkah-langkah di akhir lab ini untuk menghapus resource agar tidak dikenai biaya lebih lanjut.
  • Pengguna baru memenuhi syarat untuk mengikuti Uji Coba Gratis senilai$300 USD.

Membuat project (opsional)

Jika Anda tidak memiliki project saat ini yang ingin digunakan untuk lab ini, buat project baru di sini.

3. Buka Cloud Shell Editor

  1. Klik link ini untuk langsung membuka Cloud Shell Editor
  2. Jika diminta untuk memberikan otorisasi kapan saja hari ini, klik Authorize untuk melanjutkan.Klik untuk memberikan otorisasi pada Cloud Shell
  3. Jika terminal tidak muncul di bagian bawah layar, buka terminal:
    • Klik Lihat
    • Klik TerminalMembuka terminal baru di Cloud Shell Editor
  4. Di terminal, tetapkan project Anda dengan perintah ini:
    gcloud config set project [PROJECT_ID]
    
    • Contoh:
      gcloud config set project lab-project-id-example
      
    • Jika tidak ingat project ID, Anda dapat mencantumkan semua project ID dengan:
      gcloud projects list
      
      Menetapkan project ID di terminal Cloud Shell Editor
  5. Anda akan melihat pesan ini:
    Updated property [core/project].
    

4. Mengaktifkan API

Aktifkan API berikut untuk men-deploy komponen aplikasi, dan untuk menggunakan Google Cloud Assist:

Di terminal, aktifkan 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. Menyiapkan Project

Anda akan membuat aplikasi dan deployment dasar untuk menguji Cloud Assist.

Membuat direktori

  1. Buka Cloud Shell Editor, atau lingkungan pengembangan pilihan Anda.
  2. Membuat folder baru:
    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. Di terminal, jalankan perintah berikut untuk membuka ruang kerja Cloud Shell Editor:
cloudshell open-workspace ~/gemini-cloud-assist-debug

Buat file

Sekarang Anda akan membuat file awal yang diperlukan untuk aplikasi.

  1. Buat Dockerfile dengan menjalankan perintah berikut di terminal. File ini menangani pembuatan container aplikasi.
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. Buat file main.py dengan menjalankan perintah berikut di terminal. File ini berisi aplikasi yang ditulis dalam 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. Buat file requirements.txt dengan menjalankan perintah berikut di terminal. File ini menangani persyaratan paket 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. Buat file main.tf dengan menjalankan perintah berikut di terminal. File ini menangani resource Google Cloud yang akan dibuat.
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. Buat file variables.tf dengan menjalankan perintah berikut di terminal. File ini menangani variabel Terraform untuk resource 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. Buat file setup_via_tf.sh dengan menjalankan perintah berikut di terminal. File ini menangani persyaratan paket 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. Jalankan perintah berikut untuk membuat skrip shell dapat dieksekusi:
chmod +x ~/gemini-cloud-assist-debug/setup_via_tf.sh
  1. Buat file .env yang berisi project ID Google Cloud Anda untuk deployment. Perbarui kolom YOUR_PROJECT_ID:
cat <<EOF > ~/gemini-cloud-assist-debug/.env
PROJECT_ID=YOUR_PROJECT_ID
USE_PUBLIC_IP=true
EOF

6. Men-deploy Aplikasi

Kode aplikasi dan resource Google Cloud siap di-deploy. Proses ini dapat memerlukan waktu hingga 15 menit.

Jalankan perintah berikut dari terminal:

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

Saat komponen di-deploy, jelajahi file di Cloud Shell Editor untuk mempelajari lebih lanjut.

7. Membuat dan men-debug error

Sekarang, kita akan memicu error dari aplikasi. Buka Cloud Run di panel kiri. Kemudian, klik layanan auth-issue-demo.

  1. Di bagian atas halaman Service details, terdapat URL. Salin URL dan buka tab browser baru. Tempelkan URL dan tambahkan /connect ke URL tersebut. URL Anda akan terlihat seperti:

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

  1. Buka URL. Mungkin perlu waktu beberapa detik hingga instance Cloud Run dimulai. Anda akan mendapatkan error.
  2. Kembali ke halaman Detail layanan Cloud Run. Klik Observability, lalu klik Logs. Anda akan melihat log untuk penampung, termasuk error. Jika log error belum tersedia, tunggu beberapa detik dan muat ulang halaman menggunakan ikon di kanan atas.
  3. Klik log error untuk membaca selengkapnya. Klik ikon Selidiki di baris log utama. Kemudian, klik Selidiki Log

Panel chat Cloud Assist akan terbuka. Penyelidikan ini memerlukan waktu 2 hingga 3 menit untuk diselesaikan.

Setelah penyelidikan selesai, Anda dapat membaca hasil dan rekomendasi. Ada rekomendasi untuk menambahkan pemberian yang tepat ke akun layanan untuk Cloud Run agar dapat mengakses instance AlloyDB.

8. Memperbaiki error

Perbaiki error izin akun layanan.

  1. Buka Cloud IAM.
  2. Klik tombol Grant Access. Di panel akun utama, mulai dengan mengetik auth-demo, lalu tunggu hingga akun layanan ditampilkan.
  3. Selanjutnya, tambahkan peran AlloyDB Client ke akun layanan, lalu klik Simpan.

Perubahan ini memerlukan waktu hingga satu menit untuk diterapkan.

Setelah Anda menunggu, kembali dan muat ulang aplikasi. Sekarang Anda akan melihat pesan keberhasilan dari database AlloyDB.

9. Selamat

Selamat! Anda telah berhasil menyelesaikan pengantar Investigasi Cloud ini dan proses men-debug izin aplikasi di Google Cloud.

Apa langkah selanjutnya?