Skip to content

Commit fbe47c0

Browse files
danniel1205daniellguo
andauthored
add the notes for Google SaaSRuntime (#166)
Co-authored-by: daniellguo <daniellguo@google.com>
1 parent 30fbe94 commit fbe47c0

10 files changed

Lines changed: 242 additions & 0 deletions

File tree

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Explore Google SaaS Runtime
2+
3+
Doc: <https://cloud.google.com/saas-runtime/docs>
4+
5+
## Hands on Lab
6+
7+
### Goals
8+
9+
* Define a SaaSRuntime Unit to create a basic GKE cluster.
10+
* Define a SaaSRuntime Unit to deploy a sample K8S workload to the basic GKE
11+
cluster.
12+
* Build above blueprint as an OCI image. Follow
13+
[this](https://cloud.google.com/saas-runtime/docs/create-upload-blueprint#manual_build_push)
14+
documentation.
15+
16+
## References
17+
18+
* <https://cloud.google.com/saas-runtime/docs/overview>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
IMAGE_NAME=us-west2-docker.pkg.dev/daniellguo-anthos-dev/daniellguo-easysaas-ar/gke-cluster-bp:dev
2+
ENGINE_TYPE=inframanager
3+
ENGINE_VERSION=1.5.7
4+
5+
docker buildx build -t $IMAGE_NAME \
6+
--platform linux/amd64,linux/arm64 \
7+
--builder=container \
8+
--push \
9+
--annotation "com.easysaas.engine.type=$ENGINE_TYPE" \
10+
--annotation "com.easysaas.engine.version=$ENGINE_VERSION" \
11+
--provenance=false .
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Dockerfile used to build the terraform configuration files
2+
FROM scratch
3+
COPY --exclude=Dockerfile --exclude=.git --exclude=.gitignore --exclude=.terraform --exclude=.terraform.d . /
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# main.tf
2+
3+
# -----------------------------------------------------------------------------
4+
# REQUIRED SAAS RUNTIME INPUT VARIABLES
5+
# -----------------------------------------------------------------------------
6+
# These variables are automatically populated by SaaS Runtime when a unit
7+
# is created. You MUST declare them so Terraform can accept the values.
8+
# -----------------------------------------------------------------------------
9+
10+
variable "tenant_project_id" {
11+
type = string
12+
description = "The project ID of the tenant project where resources will be deployed."
13+
}
14+
15+
variable "tenant_project_number" {
16+
type = string
17+
description = "The project number of the tenant project."
18+
}
19+
20+
# -----------------------------------------------------------------------------
21+
# PROVIDER CONFIGURATION
22+
# -----------------------------------------------------------------------------
23+
# The provider now uses the injected 'project_id' from SaaS Runtime
24+
# instead of a hardcoded value.
25+
# -----------------------------------------------------------------------------
26+
27+
provider "google" {
28+
project = var.tenant_project_id # USE THE VARIABLE HERE
29+
region = "<replace>" # e.g., us-west2
30+
}
31+
32+
# -----------------------------------------------------------------------------
33+
# RESOURCE DEFINITION
34+
# -----------------------------------------------------------------------------
35+
# Your GKE cluster resource remains largely the same.
36+
# -----------------------------------------------------------------------------
37+
38+
resource "google_container_cluster" "primary" {
39+
# Add the project attribute here for clarity, using the passed-in variable.
40+
project = var.tenant_project_id
41+
name = "<replace>" # e.g., basic-gke-cluster
42+
location = "<replace>" # e.g., us-west2
43+
44+
initial_node_count = 1
45+
46+
node_config {
47+
machine_type = "e2-medium"
48+
oauth_scopes = [
49+
"https://www.googleapis.com/auth/cloud-platform"
50+
]
51+
}
52+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# outputs.tf (FOR GKE CLUSTER UNIT)
2+
3+
output "gke_cluster_name" {
4+
description = "The name of the created GKE cluster."
5+
value = google_container_cluster.primary.name
6+
}
7+
8+
output "gke_cluster_location" {
9+
description = "The location (region) of the GKE cluster."
10+
value = google_container_cluster.primary.location
11+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Dockerfile used to build the terraform configuration files
2+
FROM scratch
3+
COPY --exclude=Dockerfile --exclude=.git --exclude=.gitignore --exclude=.terraform --exclude=.terraform.d . /
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# main.tf (FOR K8S APP UNIT)
2+
3+
# -----------------------------------------------------------------------------
4+
# PROVIDER CONFIGURATION
5+
# -----------------------------------------------------------------------------
6+
7+
provider "google" {
8+
project = var.tenant_project_id
9+
}
10+
11+
# -----------------------------------------------------------------------------
12+
# DATA SOURCE: GET GKE CLUSTER CREDENTIALS
13+
# -----------------------------------------------------------------------------
14+
# Use the input variables (from Unit 1) to find the cluster and get its auth data.
15+
# -----------------------------------------------------------------------------
16+
17+
data "google_container_cluster" "cluster" {
18+
project = var.tenant_project_id
19+
name = var.gke_cluster_name
20+
location = var.gke_cluster_location
21+
}
22+
23+
# -----------------------------------------------------------------------------
24+
# PROVIDER CONFIGURATION: KUBERNETES & HELM
25+
# -----------------------------------------------------------------------------
26+
# Configure the Kubernetes and Helm providers using the cluster data we just fetched.
27+
# -----------------------------------------------------------------------------
28+
29+
provider "kubernetes" {
30+
host = "https://${data.google_container_cluster.cluster.endpoint}"
31+
cluster_ca_certificate = base64decode(data.google_container_cluster.cluster.master_auth[0].cluster_ca_certificate)
32+
token = data.google_client_config.default.access_token
33+
}
34+
35+
provider "helm" {
36+
kubernetes = {
37+
host = "https://${data.google_container_cluster.cluster.endpoint}"
38+
cluster_ca_certificate = base64decode(data.google_container_cluster.cluster.master_auth[0].cluster_ca_certificate)
39+
token = data.google_client_config.default.access_token
40+
}
41+
}
42+
43+
data "google_client_config" "default" {}
44+
45+
# -----------------------------------------------------------------------------
46+
# RESOURCE: DEPLOY NGINX VIA HELM
47+
# -----------------------------------------------------------------------------
48+
# This creates a Helm release for NGINX from the public Bitnami chart repo.
49+
# We set the service type to LoadBalancer so we can get an external IP.
50+
# -----------------------------------------------------------------------------
51+
52+
resource "helm_release" "nginx_ingress" {
53+
name = "my-nginx"
54+
repository = "https://charts.bitnami.com/bitnami"
55+
chart = "nginx"
56+
version = "15.5.1" # Pinning version is best practice
57+
namespace = "default"
58+
59+
# Set values for the Helm chart
60+
set = [
61+
{
62+
name = "service.type"
63+
value = "ClusterIP"
64+
}
65+
]
66+
}
67+
68+
resource "time_sleep" "wait_for_service_ip" {
69+
# This sleep will only start AFTER the helm release is "done"
70+
depends_on = [helm_release.nginx_ingress]
71+
72+
create_duration = "60s"
73+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# outputs.tf (Corrected for ClusterIP)
2+
3+
data "kubernetes_service" "nginx_service" {
4+
metadata {
5+
name = "${helm_release.nginx_ingress.name}-nginx"
6+
namespace = helm_release.nginx_ingress.namespace
7+
}
8+
depends_on = [
9+
helm_release.nginx_ingress,
10+
time_sleep.wait_for_service_ip
11+
]
12+
}
13+
14+
output "nginx_internal_cluster_ip" {
15+
description = "The internal cluster IP of the NGINX service."
16+
# Read the .spec.cluster_ip instead of the load balancer status
17+
value = data.kubernetes_service.nginx_service.spec[0].cluster_ip
18+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# -----------------------------------------------------------------------------
2+
# REQUIRED SAAS RUNTIME INPUT VARIABLES
3+
# -----------------------------------------------------------------------------
4+
variable "tenant_project_id" {
5+
type = string
6+
description = "The project ID of the tenant project where resources will be deployed."
7+
}
8+
9+
variable "tenant_project_number" {
10+
type = string
11+
description = "The project number of the tenant project."
12+
}
13+
14+
# -----------------------------------------------------------------------------
15+
# CUSTOM INPUT VARIABLES (FROM GKE CLUSTER UNIT)
16+
# -----------------------------------------------------------------------------
17+
# These variables will be populated by the outputs from Unit Kind 1.
18+
# SaaS Runtime handles this mapping when you define the dependency.
19+
# -----------------------------------------------------------------------------
20+
21+
variable "gke_cluster_name" {
22+
type = string
23+
description = "The name of the GKE cluster to deploy to (from GKE unit output)."
24+
}
25+
26+
variable "gke_cluster_location" {
27+
type = string
28+
description = "The location of the GKE cluster (from GKE unit output)."
29+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# versions.tf (FOR K8S APP UNIT)
2+
3+
terraform {
4+
required_version = ">= 1.0"
5+
6+
required_providers {
7+
google = {
8+
source = "hashicorp/google"
9+
version = ">= 4.0.0"
10+
}
11+
kubernetes = {
12+
source = "hashicorp/kubernetes"
13+
version = ">= 2.10.0"
14+
}
15+
helm = {
16+
source = "hashicorp/helm"
17+
version = ">= 2.5.0"
18+
}
19+
time = {
20+
source = "hashicorp/time"
21+
version = ">= 0.9.0"
22+
}
23+
}
24+
}

0 commit comments

Comments
 (0)