Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 10 additions & 45 deletions hacks/disneyland-on-gcp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ In this hack, you will build an end-to-end data pipeline with AI and database ca
8. **Conversational analytics**: Build a natural language assistant using BigQuery Studio.
9. **AlloyDB sync**: Copy insights back to AlloyDB using FDW for fast serving.
10. **MCP tools**: Expose database capabilities using the MCP Toolbox.
11. **App deployment**: Build a web app with the ADK and deploy it to Cloud Run.
11. **App deployment**: Build a web app with the ADK and deploy it locally.

---

Expand All @@ -55,7 +55,7 @@ In this hack, you will build an end-to-end data pipeline with AI and database ca

## Prerequisites

- Basic knowledge of Google Cloud services (AlloyDB, BigQuery, Datastream, Cloud Run)
- Basic knowledge of Google Cloud services (AlloyDB, BigQuery, Datastream)
- Intermediate knowledge of SQL and PostgreSQL
- Basic familiarity with Python and Agentic AI concepts (MCP, ADK)
- Access to a Google Cloud project with the necessary APIs and resources provisioned
Expand Down Expand Up @@ -251,42 +251,30 @@ curl -X PATCH \

#### Task 2.2: Register IAM Users in AlloyDB

To interact with the database, QueryData relies on **IAM Database Authentication**. This means both you (the developer) and the AI agent must be registered as database users.
To interact with the database, QueryData relies on **IAM Database Authentication**. This means that each user that needs to use querydata must be registered as a database user and given privileges. We will just use personal accounts for querydata.

Specifically, you must register:

1. **Your Google Account** – to manage Context Sets via the AlloyDB Console.
2. **The Agent's Service Account** – to allow the agent to connect and execute queries.

To register these users, follow these steps:
To register your user, follow these steps:

1. **Log in using Basic Authentication:**
- In the Google Cloud Console, navigate to **AlloyDB > Clusters** and select your cluster.
- Click **AlloyDB Studio** in the left menu.
- Sign in to the `disney` database using **Basic Authentication** (Username: `postgres`, Password: `<your_cluster_password>`).

2. **Register the IAM Users:**
Open a new query editor and run the following SQL commands to register your own Google account (so you can manage context sets) and the agent's Service Account (so the agent can connect), granting them the necessary table privileges:
2. **Register the IAM User:**
Open a new query editor and run the following SQL commands to register your own Google account (so you can manage context sets and allow the agent to connect) and grant it the necessary table privileges:

```sql
-- 1. Register your own Google account (replace with your actual GCP login email)
CREATE USER "your-email@domain.com" WITH FLAGS ('IAMUser');
GRANT USAGE ON SCHEMA public TO "your-email@domain.com";
GRANT SELECT, INSERT, UPDATE ON ALL TABLES IN SCHEMA public TO "your-email@domain.com";

-- 2. Register the dedicated Agent Service Account (replace with your project ID)
CREATE USER "disney-agent-sa@<YOUR_PROJECT_ID>.iam.gserviceaccount.com" WITH FLAGS ('IAMUser');
GRANT USAGE ON SCHEMA public TO "disney-agent-sa@<YOUR_PROJECT_ID>.iam.gserviceaccount.com";
GRANT SELECT, INSERT, UPDATE ON ALL TABLES IN SCHEMA public TO "disney-agent-sa@<YOUR_PROJECT_ID>.iam.gserviceaccount.com";

-- 3. Ensure future tables grant access automatically
-- 2. Ensure future tables grant access automatically
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT, INSERT, UPDATE ON TABLES TO "your-email@domain.com";
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT, INSERT, UPDATE ON TABLES TO "disney-agent-sa@<YOUR_PROJECT_ID>.iam.gserviceaccount.com";
```

*(Note: Replace `<YOUR_PROJECT_ID>` with your actual Google Cloud Project ID, and `your-email@domain.com` with the email you use to log into the Google Cloud Console.)*
*(Note: Replace `your-email@domain.com` with the email you use to log into the Google Cloud Console.)*

#### Task 2.3: Set Up the QueryData Context Set in AlloyDB

Expand Down Expand Up @@ -934,13 +922,8 @@ tools:

#### Task 9.3: Start and Validate the Server

Before running the toolbox, you must authenticate your local environment and configure it to impersonate the dedicated Agent Service Account. This allows the toolbox to call the QueryData API using the service account's identity:

```bash
# 1. Authenticate and set up service account impersonation
gcloud auth application-default login --impersonate-service-account=disney-agent-sa@<YOUR_PROJECT_ID>.iam.gserviceaccount.com

# 2. Start the toolbox
# Start the toolbox
./toolbox --config tools.yaml --ui
```

Expand All @@ -963,7 +946,7 @@ To validate this challenge, you must demonstrate the following:

### Introduction

This is the final integration and application challenge! Because the entire database agentic layer—including BigQuery FDW data sync, operational/analytical SQL tools, and MCP Toolbox—has already been securely structured in Challenges 7, 8, and 9, this challenge focuses exclusively on the developer's magic: constructing the conversational guest assistant, vibe-coding a premium web application, and deploying it to **Cloud Run**.
This is the final integration and application challenge! Because the entire database agentic layer—including BigQuery FDW data sync, operational/analytical SQL tools, and MCP Toolbox—has already been securely structured in Challenges 7, 8, and 9, this challenge focuses exclusively on the developer's magic: constructing the conversational guest assistant, vibe-coding a premium web application, and deploying it **locally**.

![Challenge 10 Architecture](images/challenge10_architecture.png)

Expand Down Expand Up @@ -1007,24 +990,6 @@ Rather than a generic, plain interface, you will **vibe-code a stunning, premium
- **Google Antigravity 2.0 & CLI:** Use the `antigravity` CLI and its Agentic IDE capabilities to autonomously scaffold and vibe-code the frontend logic, hooking it directly to your ADK agent.
- **Google AI Studio:** Prototype, experiment, and fine-tune any complex conversational interactions or multimodal prompts before integrating them into your codebase.

#### Task 10.3: Deploy to Google Cloud Run (Optional)

To complete the gHack and make the guest assistant publicly accessible, you will containerize and push the application to **Cloud Run**.

1. **Write the Dockerfile:**
Create a `Dockerfile` that packages both the ADK python backend (exposing the agent API) and the built frontend assets.
2. **Deploy Command:**
Use `gcloud run deploy` to push the application in one step, making sure to associate it with the dedicated Agent Service Account so it can authenticate to AlloyDB QueryData:

```bash
gcloud run deploy disneyland-guest-assistant \
--source . \
--platform managed \
--region europe-west1 \
--service-account=disney-agent-sa@<YOUR_PROJECT_ID>.iam.gserviceaccount.com \
--allow-unauthenticated
```

### Success Criteria

To validate this challenge, you must demonstrate the following:
Expand Down
36 changes: 1 addition & 35 deletions hacks/disneyland-on-gcp/artifacts/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ resource "google_alloydb_instance" "default" {
"alloydb.logical_decoding" = "on" # needed for replication
"bigquery_fdw.enabled" = "on" # needed for connecting to bq
"alloydb.iam_authentication" = "on"
"password.enforce_complexity" = "on"
}

machine_config {
Expand Down Expand Up @@ -224,38 +225,3 @@ resource "google_project_iam_member" "alloydb_sa_roles" {
role = each.key
member = "serviceAccount:${google_project_service_identity.alloydb_sa.email}"
}

# =========================================================================
# Dedicated SA for the agent & QueryData
# =========================================================================

# 1. Create the Service Account
resource "google_service_account" "agent_sa" {
account_id = "disney-agent-sa"
display_name = "Disneyland Guest Assistant Agent Service Account"
}

# 2. Grant required roles to the Service Account
resource "google_project_iam_member" "agent_sa_roles" {
for_each = toset([
"roles/geminidataanalytics.queryDataUser",
"roles/alloydb.databaseUser",
"roles/serviceusage.serviceUsageConsumer",
"roles/aiplatform.user"
])
project = var.gcp_project_id
role = each.key
member = "serviceAccount:${google_service_account.agent_sa.email}"
}

# 3. Allow all Project Editors and Owners to impersonate this Service Account
resource "google_service_account_iam_binding" "sa_impersonation" {
service_account_id = google_service_account.agent_sa.name
role = "roles/iam.serviceAccountTokenCreator"

members = [
"projectEditor:${var.gcp_project_id}",
"projectOwner:${var.gcp_project_id}"
]
}

8 changes: 4 additions & 4 deletions hacks/disneyland-on-gcp/artifacts/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@ output "project_id" {
value = var.gcp_project_id
}

output "alloydb_proxy_ip" {
value = google_compute_instance.gce_tcp_proxy.network_interface[0].access_config[0].nat_ip
}

output "alloydb_usr" {
value = google_alloydb_cluster.default.initial_user[0].user
}
Expand All @@ -28,3 +24,7 @@ output "alloydb_pwd" {
value = google_alloydb_cluster.default.initial_user[0].password
sensitive = true
}

output "alloydb_ip" {
value = google_alloydb_instance.default.public_ip_address
}
Loading