From 0d11d9035d42a8276b1c3bfe73eddf531551aaad Mon Sep 17 00:00:00 2001 From: Umesh Kumhar Date: Tue, 12 Mar 2024 12:02:30 +0530 Subject: [PATCH] Update Marketplace output for Rag and Jupyter Application (#324) * Add outputs for Jupyter, Ray & Rag Marketplace --- applications/jupyter/metadata.display.yaml | 15 ++++++++--- applications/jupyter/metadata.yaml | 4 +++ applications/jupyter/outputs.tf | 4 +++ applications/rag/metadata.display.yaml | 27 ++++++++++++++----- applications/rag/metadata.yaml | 7 ++++- applications/rag/outputs.tf | 16 ++++++++--- applications/ray/main.tf | 2 ++ applications/ray/metadata.display.yaml | 16 ++++++++++- applications/ray/metadata.yaml | 1 + applications/ray/outputs.tf | 4 +++ applications/ray/variables.tf | 5 ++++ applications/ray/workloads.tfvars | 3 ++- modules/jupyter/outputs.tf | 4 +++ .../kuberay-cluster/{kuberay.tf => main.tf} | 13 +++++++-- modules/kuberay-cluster/outputs.tf | 20 ++++++++++++++ modules/kuberay-cluster/variables.tf | 6 +++++ 16 files changed, 129 insertions(+), 18 deletions(-) rename modules/kuberay-cluster/{kuberay.tf => main.tf} (90%) diff --git a/applications/jupyter/metadata.display.yaml b/applications/jupyter/metadata.display.yaml index 69fba5241..1b5a8da65 100644 --- a/applications/jupyter/metadata.display.yaml +++ b/applications/jupyter/metadata.display.yaml @@ -164,11 +164,20 @@ spec: runtime: outputMessage: Deployment can take several minutes to complete. suggestedActions: - - heading: No external IP configured - description: The application has been configured with no external IP or domain. + - heading: "Access JupyterHub Application" + description: |- + Go to the JupyterHub Application, log in with Jupyterhub User and Jupyterhub Password (from the Outputs section). + Once logged in, choose the appropriate preset and execute notebooks. + showIf: '!variables.add_auth' + - heading: "Access JupyterHub Application" + description: |- + Go to the JupyterHub Application, log in with your organization's credentials. Once logged in, choose the appropriate preset and execute notebooks. + Note: Application endpoint can take around 15-20 minutes to become accessible. + showIf: 'variables.add_auth' outputs: jupyterhub_password: {} + jupyterhub_user: {} jupyterhub_uri: openInNewTab: true showInNotification: true - label: Go to Jupyter Application + label: Go to JupyterHub Application diff --git a/applications/jupyter/metadata.yaml b/applications/jupyter/metadata.yaml index 69ea0d8c2..8380fd38f 100644 --- a/applications/jupyter/metadata.yaml +++ b/applications/jupyter/metadata.yaml @@ -132,4 +132,8 @@ spec: defaultValue: jupyter-service-account outputs: - name: jupyterhub_password + description: "JupyterHub password is only required for standard authentication. Ignore in case of IAP authentication" + - name: jupyterhub_user + description: "JupyterHub user is only required for standard authentication. Ignore in case of IAP authentication" - name: jupyterhub_uri + description: "JupyterHub Endpoint to access user interface. In case of private IP consider port-forwarding." diff --git a/applications/jupyter/outputs.tf b/applications/jupyter/outputs.tf index 3a04e758f..c66635682 100644 --- a/applications/jupyter/outputs.tf +++ b/applications/jupyter/outputs.tf @@ -16,6 +16,10 @@ output "jupyterhub_uri" { value = "http://${module.jupyterhub.jupyterhub_uri}" } +output "jupyterhub_user" { + value = module.jupyterhub.jupyterhub_user +} + output "jupyterhub_password" { value = module.jupyterhub.jupyterhub_password sensitive = true diff --git a/applications/rag/metadata.display.yaml b/applications/rag/metadata.display.yaml index 0befbff0a..bd0dcca5f 100644 --- a/applications/rag/metadata.display.yaml +++ b/applications/rag/metadata.display.yaml @@ -186,19 +186,34 @@ spec: runtime: outputMessage: Deployment can take several minutes to complete. suggestedActions: - - heading: No external IP configured + - heading: "Step 1: Generate Vector Embeddings for the Dataset" description: |- - The VM instance has been configured with no external IP or internet access. Connecting - to it directly may not be possible. Consider using a bastion host - to access this VM. + Go to the JupyterHub Application, log in with Jupyterhub User and Jupyterhub Password (from the Outputs section). + Once logged in, choose the CPU preset. Go to File -> Open From URL & upload and execute the notebook + rag-kaggle-ray-sql.ipynb. + Follow the README.md for detailed instructions. + showIf: '!variables.add_auth' + - heading: "Step 1: Generate Vector Embeddings for the Dataset" + description: |- + Go to the JupyterHub Application, log in with your organization's credentials. + Once logged in, choose the CPU preset. Go to File -> Open From URL & upload and execute the notebook + rag-kaggle-ray-sql.ipynb. + Follow the README.md for detailed instructions. + showIf: 'variables.add_auth' + - heading: "Step 2: Prompt the Inference Server via a Chatbot" + description: |- + Go to the RAG Frontend Application, scroll to Ports section and initiate PORT FORWARDING (Run in Cloud Shell) to the front end application. + Launch Fronted Chat app via OPEN IN WEB PREVIEW button and prompt the LLM. This will fetch context related to your prompt from the generated vector embeddings, + augment the original prompt with the context & query the inference model (mistral-7b) with the augmented prompt. outputs: jupyterhub_password: {} + jupyterhub_user: {} jupyterhub_uri: openInNewTab: true showInNotification: true - label: Go to Jupyter Application + label: Go to JupyterHub Application frontend_uri: openInNewTab: true showInNotification: true - label: Go to Rag Frontend Application + label: Go to RAG Frontend Application diff --git a/applications/rag/metadata.yaml b/applications/rag/metadata.yaml index 35873823c..44fc12c7e 100644 --- a/applications/rag/metadata.yaml +++ b/applications/rag/metadata.yaml @@ -134,5 +134,10 @@ spec: defaultValue: "pgvector-instance" outputs: - name: jupyterhub_password - - name: jupyterhub_uri + description: "JupyterHub password is only required for standard authentication. Ignore, in case of IAP authentication" + - name: jupyterhub_user + description: "JupyterHub user is only required for standard authentication. Ignore, in case of IAP authentication" - name: frontend_uri + description: "RAG Frontend Endpoint to access user interface. In case of private IP, consider port-forwarding." + - name: jupyterhub_uri + description: "JupyterHub Endpoint to access user interface. In case of private IP, consider port-forwarding." diff --git a/applications/rag/outputs.tf b/applications/rag/outputs.tf index b789a661e..d264bec65 100644 --- a/applications/rag/outputs.tf +++ b/applications/rag/outputs.tf @@ -13,14 +13,22 @@ # limitations under the License. output "jupyterhub_uri" { - value = "http://${module.jupyterhub.jupyterhub_uri}" + description = "JupyterHub Endpoint to access user interface. In case of private IP, consider port-forwarding." + value = "http://${module.jupyterhub.jupyterhub_uri}" +} + +output "jupyterhub_user" { + description = "JupyterHub user is only required for standard authentication. Ignore, in case of IAP authentication" + value = module.jupyterhub.jupyterhub_user } output "jupyter_password" { - value = module.jupyterhub.jupyterhub_password - sensitive = true + description = "JupyterHub password is only required for standard authentication. Ignore, in case of IAP authentication" + value = module.jupyterhub.jupyterhub_password + sensitive = true } output "frontend_uri" { - value = module.frontend.frontend_uri != "" ? "http://${module.frontend.frontend_uri}" : local.frontend_default_uri + description = "RAG Frontend Endpoint to access user interface. In case of private IP, consider port-forwarding." + value = module.frontend.frontend_uri != "" ? "http://${module.frontend.frontend_uri}" : local.frontend_default_uri } diff --git a/applications/ray/main.tf b/applications/ray/main.tf index 830ca621f..24dc7cd2e 100644 --- a/applications/ray/main.tf +++ b/applications/ray/main.tf @@ -62,6 +62,7 @@ locals { locals { workload_identity_service_account = var.goog_cm_deployment_name != "" ? "${var.goog_cm_deployment_name}-${var.workload_identity_service_account}" : var.workload_identity_service_account + ray_cluster_default_uri = "https://console.cloud.google.com/kubernetes/service/${var.cluster_location}/${var.cluster_name}/${var.kubernetes_namespace}/${var.ray_cluster_name}-kuberay-head-svc/overview?project=${var.project_id}" } provider "kubernetes" { @@ -144,6 +145,7 @@ module "kuberay-cluster" { count = var.create_ray_cluster == true ? 1 : 0 source = "../../modules/kuberay-cluster" providers = { helm = helm.ray, kubernetes = kubernetes.ray } + name = var.ray_cluster_name namespace = var.kubernetes_namespace project_id = var.project_id enable_tpu = local.enable_tpu diff --git a/applications/ray/metadata.display.yaml b/applications/ray/metadata.display.yaml index f404141df..0c83663a2 100644 --- a/applications/ray/metadata.display.yaml +++ b/applications/ray/metadata.display.yaml @@ -115,4 +115,18 @@ spec: - name: ray title: Ray Application - name: iap_auth - title: IAP Authentication \ No newline at end of file + title: IAP Authentication + runtime: + outputMessage: Deployment can take several minutes to complete. + suggestedActions: + - heading: "Connect to Ray Cluster" + description: |- + Connect to Ray Cluster, scroll to Ports section and initiate PORT FORWARDING (Run in Cloud Shell) to the ray cluster head node. + - heading: "Submit Ray Jobs" + description: |- + Open the ray dashboard via the OPEN IN WEB PREVIEW button and submit ray jobs following these instructions. + outputs: + ray_cluster_uri: + openInNewTab: true + showInNotification: true + label: Connect to Ray Cluster diff --git a/applications/ray/metadata.yaml b/applications/ray/metadata.yaml index cce74f5e0..61b2fe8b7 100644 --- a/applications/ray/metadata.yaml +++ b/applications/ray/metadata.yaml @@ -80,3 +80,4 @@ spec: defaultValue: v2.7.1 outputs: - name: grafana_uri + - name: ray_cluster_uri diff --git a/applications/ray/outputs.tf b/applications/ray/outputs.tf index f0d79a53c..efacbb1c3 100644 --- a/applications/ray/outputs.tf +++ b/applications/ray/outputs.tf @@ -1,3 +1,7 @@ output "grafana_uri" { value = module.kuberay-monitoring[0].grafana_uri } + +output "ray_cluster_uri" { + value = module.kuberay-cluster[0].ray_cluster_uri != "" ? "http://${module.kuberay-cluster[0].ray_cluster_uri}" : local.ray_cluster_default_uri +} \ No newline at end of file diff --git a/applications/ray/variables.tf b/applications/ray/variables.tf index 8c32ecd82..4eeb03265 100644 --- a/applications/ray/variables.tf +++ b/applications/ray/variables.tf @@ -75,6 +75,11 @@ variable "create_ray_cluster" { default = false } +variable "ray_cluster_name" { + type = string + default = "example-cluster" +} + variable "enable_gpu" { type = bool default = false diff --git a/applications/ray/workloads.tfvars b/applications/ray/workloads.tfvars index e59169be5..1adddfab9 100644 --- a/applications/ray/workloads.tfvars +++ b/applications/ray/workloads.tfvars @@ -27,7 +27,7 @@ cluster_location = "us-central1" ####################################################### ## GKE environment variables -ray_namespace = "ml" +kubernetes_namespace = "ml" # Creates a google service account & k8s service account & configures workload identity with appropriate permissions. # Set to false & update the variable `workload_identity_service_account` to use an existing IAM service account. @@ -38,4 +38,5 @@ workload_identity_service_account = "ray-service-account" create_gcs_bucket = true gcs_bucket = "ray-bucket-zydg" create_ray_cluster = true +ray_cluster_name = "example-cluster" enable_grafana_on_ray_dashboard = false diff --git a/modules/jupyter/outputs.tf b/modules/jupyter/outputs.tf index a6a4ef30f..69b088203 100644 --- a/modules/jupyter/outputs.tf +++ b/modules/jupyter/outputs.tf @@ -16,6 +16,10 @@ output "jupyterhub_uri" { value = var.add_auth ? module.iap_auth[0].domain : (data.kubernetes_service.jupyter-ingress.status != null ? (data.kubernetes_service.jupyter-ingress.status[0].load_balancer != null ? "${data.kubernetes_service.jupyter-ingress.status[0].load_balancer[0].ingress[0].ip}" : "") : "") } +output "jupyterhub_user" { + value = var.add_auth ? "" : "admin" +} + output "jupyterhub_password" { value = var.add_auth ? "" : random_password.generated_password[0].result sensitive = true diff --git a/modules/kuberay-cluster/kuberay.tf b/modules/kuberay-cluster/main.tf similarity index 90% rename from modules/kuberay-cluster/kuberay.tf rename to modules/kuberay-cluster/main.tf index 1f67a658d..42dac1c5e 100644 --- a/modules/kuberay-cluster/kuberay.tf +++ b/modules/kuberay-cluster/main.tf @@ -23,7 +23,7 @@ locals { } resource "helm_release" "ray-cluster" { - name = "example-cluster" + name = var.name repository = "https://ray-project.github.io/kuberay-helm/" chart = "ray-cluster" namespace = var.namespace @@ -69,7 +69,8 @@ resource "helm_release" "ray-cluster" { resource "kubernetes_service" "tpu-worker-svc" { count = var.enable_tpu ? 1 : 0 metadata { - name = "${helm_release.ray-cluster.name}-kuberay-tpu-worker-svc" + name = "${helm_release.ray-cluster.name}-kuberay-tpu-worker-svc" + namespace = var.namespace } spec { selector = { @@ -78,3 +79,11 @@ resource "kubernetes_service" "tpu-worker-svc" { cluster_ip = "None" } } + +data "kubernetes_service" "head-svc" { + metadata { + name = "${helm_release.ray-cluster.name}-kuberay-head-svc" + namespace = var.namespace + } + depends_on = [helm_release.ray-cluster] +} \ No newline at end of file diff --git a/modules/kuberay-cluster/outputs.tf b/modules/kuberay-cluster/outputs.tf index e69de29bb..377b1e7ae 100644 --- a/modules/kuberay-cluster/outputs.tf +++ b/modules/kuberay-cluster/outputs.tf @@ -0,0 +1,20 @@ +# 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 +# +# http://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 "ray_cluster_uri" { + value = data.kubernetes_service.head-svc.status != null ? ( + length(data.kubernetes_service.head-svc.status[0].load_balancer) > 0 ? ( + length(data.kubernetes_service.head-svc.status[0].load_balancer[0].ingress) > 0 ? + "${data.kubernetes_service.head-svc.status[0].load_balancer[0].ingress[0].ip}" : "") : "") : "" +} \ No newline at end of file diff --git a/modules/kuberay-cluster/variables.tf b/modules/kuberay-cluster/variables.tf index ce09dfac2..544ed8fc0 100644 --- a/modules/kuberay-cluster/variables.tf +++ b/modules/kuberay-cluster/variables.tf @@ -17,6 +17,12 @@ variable "project_id" { description = "GCP project id" } +variable "name" { + type = string + description = "Name of the ray cluster" + default = "example-cluster" +} + variable "db_region" { type = string description = "Cloud SQL instance region"