Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
61d73b4
initial commit for the Disneyland gHack...
meken Apr 21, 2026
cefd0bf
updating names and fixing references...
meken Apr 21, 2026
ff5fc22
adding the new hack to the front page...
meken Apr 21, 2026
306e7bf
simplified the challenge titles...
meken Apr 21, 2026
bfb11a5
working on TF...
meken Apr 21, 2026
549f3ee
working on TF...
meken Apr 22, 2026
61a4f33
working on challenge 1...
meken Apr 22, 2026
67069b4
finalized challenge 1...
meken Apr 22, 2026
0a30696
working on challenge 2...
meken Apr 23, 2026
5768a04
overhaul of remaining challenges, working on challenge 3...
meken Apr 23, 2026
de3d4f5
working on challenge 4...
meken Apr 23, 2026
9a52b79
working on challenge 5...
meken Apr 24, 2026
84c640f
working on challenge 6...
meken Apr 24, 2026
9ee0a6b
fixed a typo...
meken Apr 24, 2026
7d7f18e
split the challenges into multiple ones...
meken Apr 24, 2026
ff6ad18
improving wording for the first 6 challenges...
meken Apr 25, 2026
174f145
rewording and adding more links...
meken Apr 28, 2026
c1c8817
improving the introduction sections...
meken Apr 28, 2026
35f2bff
docs: align disneyland-on-gcp README with new Agentic Data Cloud gHac…
Matthieu68857 Jun 25, 2026
18f90cd
fixed markdown linter issues...
meken Jun 26, 2026
1180e8c
enabling 8 users...
meken Jun 26, 2026
353a392
enabling 8 users, with owner permissions now...
meken Jun 26, 2026
58ee108
using - as list items as expected by the parser...
meken Jun 26, 2026
f3c0f70
docs: simplify and sentence-case disneyland challenge titles
Matthieu68857 Jun 26, 2026
60e2176
docs: rename Challenge 1 to include AlloyDB setup
Matthieu68857 Jun 26, 2026
9fe9387
docs: rename Challenge 2 to 'Creating the agentic database layer'
Matthieu68857 Jun 26, 2026
abe61b0
feat(disneyland-on-gcp): add dedicated disney database creation step …
Matthieu68857 Jun 29, 2026
1e0aced
Update Disneyland hackathon diagrams to 9-challenge structure
Matthieu68857 Jun 29, 2026
5b2e8d3
Update Disneyland on GCP: Add ADK guest assistant agent, Streamlit ap…
Matthieu68857 Jun 29, 2026
6271c27
Update Disneyland on GCP hack: rename to Data Cloud, optimize SQL sol…
Matthieu68857 Jun 30, 2026
9ef0aed
Clean
Matthieu68857 Jul 1, 2026
eb170e2
Update README.md
rayrz22 Jun 30, 2026
bdad9e5
Move to gcloud for Data API
Matthieu68857 Jul 1, 2026
59f45e7
Update README.md: add knowledge catalog integration
rayrz22 Jul 1, 2026
4e19e12
docs(disneyland-on-gcp): update challenge indexing, AlloyDB table sch…
Matthieu68857 Jul 1, 2026
87cf51b
docs: Update Disneyland hackathon description to Disneyland Agentic D…
Matthieu68857 Jul 1, 2026
76b6701
Update learning objectives to add KC
Matthieu68857 Jul 1, 2026
d9f8acd
SImplify GQL asks
Matthieu68857 Jul 1, 2026
9f296f6
Fix split
Matthieu68857 Jul 1, 2026
a38ac86
Update MCP Toolbox challenge
Matthieu68857 Jul 1, 2026
50c75d5
Final clean and new images
Matthieu68857 Jul 1, 2026
d8aef9e
Fix md lint
Matthieu68857 Jul 1, 2026
331987c
Fix lint and change project type
Matthieu68857 Jul 1, 2026
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
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ Teams are not left on their own to solve the challenges. Coaches work with each
> We will be going through replicating and processing operational data from an Oracle database into Google Cloud in real time. You'll also figure out how to forecast future demand, and how to visualize this forecast data as it arrives.
- [Hack to the Future: Data Track](./hacks/httf-data/README.md)
> In this hack we'll help the fictitious Cymbal Shops e-commerce platform to modernize their tech stack, primarily focusing on the migration of the legacy application MySQL database to Cloud Spanner. From that point we'll create BigQuery analytics datasets to handle both historical and live data using federation, use advanced generative AI to enhance the existing dataset with descriptions and images, and finally implement semantic search on this dataset.
- [Disneyland Agentic Data Cloud](./hacks/disneyland-on-gcp/README.md)
> Build an end-to-end intelligent guest assistance system. You will ingest operational data into AlloyDB and generate vector embeddings natively using AlloyDB AI, configure QueryData for predictable SQL generation, and set up real-time replication to BigQuery using Datastream. In BigQuery, you will train forecasting models using BigQuery ML, build a multimodal RAG pipeline on images and PDF brochures, and map visitor movement patterns using BigQuery's native SQL Graph (GQL) capabilities. After cataloging your assets in Knowledge Catalog, you will use Conversational Analytics to query insights, sync these insights back to AlloyDB via BigQuery FDW, expose operational and analytical tools using the MCP Toolbox, and build and deploy a conversational assistant web app powered by the Agent Development Kit (ADK).

### Infrastructure

Expand Down
3 changes: 3 additions & 0 deletions hacks/disneyland-on-gcp/QL_OWNER
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
meken@google.com
# Collaborators
ginof@google.com
1,038 changes: 1,038 additions & 0 deletions hacks/disneyland-on-gcp/README.md

Large diffs are not rendered by default.

21 changes: 21 additions & 0 deletions hacks/disneyland-on-gcp/artifacts/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Copyright 2023 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
TARGET=ghacks-setup.zip
OBJS=*.tf runtime.yaml

$(TARGET): $(OBJS)
zip -r $(TARGET) $(OBJS)

clean:
rm -f $(TARGET)
261 changes: 261 additions & 0 deletions hacks/disneyland-on-gcp/artifacts/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,261 @@
# Copyright 2023 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

resource "google_project_service" "default" {
project = var.gcp_project_id
for_each = toset([
"cloudresourcemanager.googleapis.com",
"serviceusage.googleapis.com",
"iam.googleapis.com",
"storage.googleapis.com",
"compute.googleapis.com",
"alloydb.googleapis.com",
"bigquery.googleapis.com",
"bigqueryconnection.googleapis.com",
"datastream.googleapis.com",
"aiplatform.googleapis.com",
"dataplex.googleapis.com",
"artifactregistry.googleapis.com",
"run.googleapis.com",
"servicenetworking.googleapis.com",
"cloudaicompanion.googleapis.com",
"geminicloudassist.googleapis.com",
"geminidataanalytics.googleapis.com"
])
service = each.key

disable_on_destroy = false
}

# In case a default network is not present in the project, this variable needs to be set
resource "google_compute_network" "default_network_created" {
name = "default"
auto_create_subnetworks = true
count = var.create_default_network ? 1 : 0
depends_on = [
google_project_service.default
]
}

# Enabling comms between VMs for auto mode subnets (needed by Dataproc/Dataflow workers)
resource "google_compute_firewall" "fwr_allow_custom" {
name = "fwr-ingress-allow-custom"
network = google_compute_network.default_network_created[0].self_link
count = var.create_default_network ? 1 : 0
source_ranges = ["10.128.0.0/9"]
allow {
protocol = "all"
}
}

# Enabling Identity-Aware-Proxy for TCP forwarding (for SSH access from Console)
resource "google_compute_firewall" "fwr_allow_iap" {
name = "fwr-ingress-allow-iap"
network = google_compute_network.default_network_created[0].self_link
count = var.create_default_network ? 1 : 0
source_ranges = ["35.235.240.0/20"]
allow {
protocol = "tcp"
ports = ["22"]
}
}

# This piece of code makes it possible to deal with the default network the same way,
# regardless of how it has been created. Make sure to refer to the default network through
# this resource when needed.
data "google_compute_network" "default_network" {
name = "default"
depends_on = [
google_project_service.default,
google_compute_network.default_network_created
]
}

# Reserve a range for Private Service Access
resource "google_compute_global_address" "private_ip_alloc" {
name = "alloydb-private-ip-alloc"
purpose = "VPC_PEERING"
address_type = "INTERNAL"
prefix_length = 16
network = data.google_compute_network.default_network.id
}

# Create the VPC Peering connection
resource "google_service_networking_connection" "vpc_connection" {
network = data.google_compute_network.default_network.id
service = "servicenetworking.googleapis.com"
reserved_peering_ranges = [google_compute_global_address.private_ip_alloc.name]
depends_on = [google_project_service.default]
}

# Random password for the AlloyDB database user
resource "random_string" "password" {
length = 12
special = false
}

# AlloyDB Cluster
resource "google_alloydb_cluster" "default" {
cluster_id = "disney-cluster"
location = var.gcp_region

network_config {
network = data.google_compute_network.default_network.id
}

initial_user {
user = "postgres"
password = random_string.password.result
}

depends_on = [
google_project_service.default,
google_service_networking_connection.vpc_connection
]
}

resource "google_alloydb_instance" "default" {
cluster = google_alloydb_cluster.default.name
instance_id = "disney-instance"
instance_type = "PRIMARY"

database_flags = {
"alloydb.logical_decoding" = "on" # needed for replication
"bigquery_fdw.enabled" = "on" # needed for connecting to bq
"alloydb.iam_authentication" = "on"
}

machine_config {
cpu_count = 2
}

network_config {
enable_public_ip = true
authorized_external_networks {
cidr_range = "0.0.0.0/0"
}
}

depends_on = [google_alloydb_cluster.default]
}

# Storage Bucket
resource "google_storage_bucket" "disney" {
name = var.gcp_project_id
location = var.gcp_region
uniform_bucket_level_access = true
}

# BigQuery Dataset
resource "google_bigquery_dataset" "disney" {
dataset_id = "disney"
friendly_name = "Disneyland Data"
description = "Dataset for Disneyland Data Cloud"
location = var.gcp_region
delete_contents_on_destroy = true

depends_on = [google_project_service.default]
}

resource "google_bigquery_reservation" "bq_edition" {
name = "disneyland-analytics"
location = var.gcp_region
edition = "ENTERPRISE"
slot_capacity = 0

autoscale {
max_slots = 100
}
}

resource "google_bigquery_reservation_assignment" "default" {
assignee = "projects/${var.gcp_project_id}"
reservation = google_bigquery_reservation.bq_edition.id
job_type = "QUERY"
}

# BigQuery Cloud Resource Connection
resource "google_bigquery_connection" "agent_platform" {
connection_id = "conn"
location = var.gcp_region
friendly_name = "Connection to Agent Platform"
cloud_resource {}

depends_on = [google_project_service.default]
}

# Grant Agent Platform User and Storage Viewer to BigQuery Connection Service Account
resource "google_project_iam_member" "bq_connection_roles" {
for_each = toset([
"roles/aiplatform.user",
"roles/storage.objectViewer"
])
project = var.gcp_project_id
role = each.key
member = "serviceAccount:${google_bigquery_connection.agent_platform.cloud_resource[0].service_account_id}"
}

# AlloyDB Service Agent
resource "google_project_service_identity" "alloydb_sa" {
provider = google-beta
project = var.gcp_project_id
service = "alloydb.googleapis.com"
}

# Grant Agent Platform User, BQ Viewer and BQ Read Session User to AlloyDB Service Agent
resource "google_project_iam_member" "alloydb_sa_roles" {
for_each = toset([
"roles/aiplatform.user",
# "roles/bigquery.dataViewer", # these need to be granted to another service account
# "roles/bigquery.readSessionUser"
])
project = var.gcp_project_id
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}"
]
}

30 changes: 30 additions & 0 deletions hacks/disneyland-on-gcp/artifacts/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Copyright 2023 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

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
}

output "alloydb_pwd" {
value = google_alloydb_cluster.default.initial_user[0].password
sensitive = true
}
37 changes: 37 additions & 0 deletions hacks/disneyland-on-gcp/artifacts/providers.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Copyright 2023 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
terraform {
required_providers {
google = {
source = "hashicorp/google"
version = "~> 7.24.0"
}
google-beta = {
source = "hashicorp/google-beta"
version = "~> 7.24.0"
}
}
}

provider "google" {
project = var.gcp_project_id
region = var.gcp_region
zone = var.gcp_zone
}

provider "google-beta" {
project = var.gcp_project_id
region = var.gcp_region
zone = var.gcp_zone
}
15 changes: 15 additions & 0 deletions hacks/disneyland-on-gcp/artifacts/runtime.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Copyright 2023 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
runtime: terraform
version: 1.4.6
Loading
Loading