diff --git a/docs/deployment/docker/README.md b/docs/deployment/docker/README.md index ae0fd3c..a75e482 100644 --- a/docs/deployment/docker/README.md +++ b/docs/deployment/docker/README.md @@ -28,7 +28,7 @@ To run the application using [Docker Compose](https://docs.docker.com/compose/), version: '3.5' services: mysql: - image: mysql:5.7 + image: mysql:8.0 restart: always volumes: - './mysql:/var/lib/mysql' @@ -44,8 +44,7 @@ services: JAVA_TOOL_OPTIONS: '-Xms512m -Xmx1024m' SPRING_DATASOURCE_USERNAME: 'karaplan' SPRING_DATASOURCE_PASSWORD: 'toComplete' - SPRING_DATASOURCE_URL: 'jdbc:mysql://mysql:3306/karaplan?useSSL=false' - SPRING_JPA_DATABASEPLATFORM: 'org.hibernate.dialect.MySQL5InnoDBDialect' + SPRING_DATASOURCE_URL: 'jdbc:mysql://mysql:3306/karaplan' SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_GOOGLE_CLIENTID: 'toComplete' SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_GOOGLE_CLIENTSECRET: 'toComplete' SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_FACEBOOK_CLIENTID: 'toComplete' diff --git a/docs/deployment/gcp/README.md b/docs/deployment/gcp/README.md index 1203fc8..06e4d98 100644 --- a/docs/deployment/gcp/README.md +++ b/docs/deployment/gcp/README.md @@ -4,7 +4,6 @@ This directory contains specific deployment instructions and examples for [Googl 1. [**Build**](build): using [Cloud Build](https://cloud.google.com/cloud-build/) to build and push a WAR file to [Cloud Storage](https://cloud.google.com/storage/), and a Docker image to [Container Registry](https://cloud.google.com/container-registry/). 2. [**SQL**](sql): using [Cloud SQL](https://cloud.google.com/sql/) to deploy a database for persistence. -2. [**Memorystore**](memorystore): using [Cloud Memorystore](https://cloud.google.com/memorystore/) to deploy a Redis instance for distributed caching. 3. [**GCE Classic**](gce-classic): using [Compute Engine](https://cloud.google.com/compute/) to run the WAR file with a Tomcat application server in a Managed Instance Group, and [HTTPS Load Balancing](https://cloud.google.com/load-balancing/) to expose the service. 4. [**GCE Container**](gce-container): using [Compute Engine](https://cloud.google.com/compute/) to run the Docker image in a Managed Instance Group, and [HTTPS Load Balancing](https://cloud.google.com/load-balancing/) to expose the service. 5. [**GKE**](gke): using [Kubernetes Engine](https://cloud.google.com/kubernetes-engine/) to run the Docker image in a Kubernetes cluster, and an Ingress to expose the service over HTTPS. diff --git a/docs/deployment/gcp/architecture.drawio b/docs/deployment/gcp/architecture.drawio new file mode 100644 index 0000000..68613dc --- /dev/null +++ b/docs/deployment/gcp/architecture.drawio @@ -0,0 +1,997 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/deployment/gcp/build/README.md b/docs/deployment/gcp/build/README.md index 4caf9a1..347f766 100644 --- a/docs/deployment/gcp/build/README.md +++ b/docs/deployment/gcp/build/README.md @@ -1,6 +1,6 @@ # Google Cloud Build -This example uses [Cloud Build](https://cloud.google.com/cloud-build/) to build the application, upload a WAR file to [Cloud Storage](https://cloud.google.com/storage/), and push a Docker image to [Container Registry](https://cloud.google.com/container-registry/). +This example uses [Cloud Build](https://cloud.google.com/cloud-build/) to build the application, upload a WAR file to [Cloud Storage](https://cloud.google.com/storage/), and push a Docker image to [Artifact Registry](https://cloud.google.com/artifact-registry/). ## Prerequisites @@ -10,24 +10,33 @@ Before starting, **create a fork** of the project on GitHub (https://github.com/ Go to [Cloud Console](https://console.cloud.google.com) and make sure the appropriate project is selected in the header menu. -In the side menu, go to **Storage > Browser** to prepare the bucket where the WAR file will be stored: +In the side menu, go to **Cloud Storage > Browser** to prepare the bucket where the WAR file will be stored: * Click **Create Bucket**. * Enter your project ID as the bucket **name**, then **Continue**. -* Select **Region** and your preferred **Location** (e.g. `europe-west1`), then **Continue**. +* Select **Region** and your preferred region (e.g. `europe-west1`), then **Continue**. * Click **Create**. * Click **Create folder**, type `karaplan` and click **Create**. +In the side menu, go to **Artifact Registry** to prepare the repository where the container image will be stored: +* Click **Create Repository**. +* Enter the repository **name** (e.g. `docker`). +* Select **Docker** as the repository **format**. +* Select your preferred **region** (e.g. `europe-west1`). +* Click **Create**. + In the side menu, go to **Cloud Build > Triggers**: -* Click **Connect repository**. -* Select **GitHub** and click **Continue**. -* Link your GitHub account, then select `karaplan` in the repository list and click **Connect repository**. -* Review the default **push trigger** and click **Create push trigger** to setup automatic builds. -* Click **Run trigger** to start a build immediately. +* Click **Manage repositories**, then **Connect repository**. +* Select your preferred region (e.g. `europe-west1`), select **GitHub** and click **Continue**. +* Link your GitHub account, then select `karaplan` in the repository list and click **Connect**. +* Click **Create a trigger**. +* Enter the trigger **name** (e.g. `master`). +* Leave default values and click **Create**. +* Click **Run** to start a build immediately. * Go to the **History** section of the side menu to see the current build. When the build is successful, you may check the results in: * **Cloud Storage > Browser**: in the `karaplan` folder of your bucket, you should now see the `karaplan.war` file. -* **Container Registry > Images**: a `karaplan` image should be available with the `master` tag. +* **Artifact Registry > Repositories**: a `karaplan` image should be available in the `docker` repository with the `master` tag. ## Using Cloud Shell / SDK @@ -41,6 +50,9 @@ Use the following commands in [Cloud Shell](https://cloud.google.com/shell/) or # Create Cloud Storage Bucket to store the WAR file gsutil mb -l $REGION -p $PROJECT_ID gs://$BUCKET_NAME + # Create Artifact Registry repository to store the Docker image + gcloud artifacts repositories create docker --repository-format=docker --location=$REGION + # Clone source and launch Cloud Build git clone https://github.com/fcrespel/karaplan.git karaplan cd karaplan @@ -49,5 +61,6 @@ Use the following commands in [Cloud Shell](https://cloud.google.com/shell/) or # List builds gcloud builds list - # When done, list created Storage objects + # When done, list created Storage objects and Docker images gsutil ls gs://$BUCKET_NAME/karaplan + gcloud artifacts docker images list $REGION-docker.pkg.dev/$PROJECT_ID/docker/karaplan diff --git a/docs/deployment/gcp/cloudrun/README.md b/docs/deployment/gcp/cloudrun/README.md index 2aebbbe..5d0db28 100644 --- a/docs/deployment/gcp/cloudrun/README.md +++ b/docs/deployment/gcp/cloudrun/README.md @@ -4,33 +4,30 @@ This example uses [Cloud Run](https://cloud.google.com/run) to run the Docker im ## Prerequisites -Before starting, follow the [Build](../build), [SQL](../sql) and [Memorystore](../memorystore) guides to create the container image, database and Redis instance. +Before starting, follow the [Build](../build) and [SQL](../sql) guides to create the container image and database. Then, refer to the deployment [README](../../README.md) file for information about configuring identity providers. -Finally, configure [Serverless VPC Access](https://cloud.google.com/vpc/docs/configure-serverless-vpc-access#creating_a_connector) as described in the official documentation, to allow communication between Cloud Run and the Memorystore (Redis) instance. - ## Using Cloud Console Go to [Cloud Console](https://console.cloud.google.com) and make sure the appropriate project is selected in the header menu. -In the side menu, go to **Serverless > Cloud Run**: +In the side menu, go to **Cloud Run**: * Click **Create service**. +* Enter the **Container image name**, e.g. `europe-west1-docker.pkg.dev/YOUR_PROJECT_ID/docker/karaplan:master`. * Enter `karaplan` as the service **name**. * Select your preferred **Region** (e.g. `europe-west1`). -* Click **Next**. -* Enter the **Container image name**, e.g. `eu.gcr.io/YOUR_PROJECT_ID/karaplan:master`. -* Click **Advanced settings**. - * In the **Container** tab, set **Memory allocated** to `1 GiB` and configure **Autoscaling** minimum/maximum numbers of instances (e.g. 0 to 5). - * In the **Connections** tab, select the appropriate **VPC Connector** to access the Redis instance over the VPC network. +* Configure the **maximum number of instances** (e.g. `5`). +* Select **Allow unauthenticated invocations**. +* Expand additional settings at the bottom. + * In the **Container** tab, set **Memory** to `1 GiB`. * In the **Variables and secrets** tab, add the following **Environment variables** (replace `toComplete` with appropriate values): | Name | Value | | ---- | ----- | | SPRING_DATASOURCE_USERNAME | karaplan | | SPRING_DATASOURCE_PASSWORD | toComplete | - | SPRING_DATASOURCE_URL | jdbc:mysql:///toComplete?useSSL=false&socketFactory=com.google.cloud.sql.mysql.SocketFactory&cloudSqlInstance=toComplete | - | SPRING_JPA_DATABASEPLATFORM | org.hibernate.dialect.MySQL5InnoDBDialect | + | SPRING_DATASOURCE_URL | jdbc:mysql:///karaplan?useSSL=false&socketFactory=com.google.cloud.sql.mysql.SocketFactory&cloudSqlInstance=toComplete | | SPRING_PROFILES_ACTIVE | gcp | | SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_GOOGLE_CLIENTID | toComplete | | SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_GOOGLE_CLIENTSECRET | toComplete | @@ -38,17 +35,14 @@ In the side menu, go to **Serverless > Cloud Run**: | SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_FACEBOOK_CLIENTSECRET | toComplete | | SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_GITHUB_CLIENTID | toComplete | | SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_GITHUB_CLIENTSECRET | toComplete | - | SPRING_SESSION_STORETYPE | redis | - | SPRING_REDIS_HOST | toComplete | - -* Click **Next**. -* Configure **Ingress** to **Allow all traffic** and **Authentication** to **Allow unauthenticated invocations**. + * Click **Create**. If you have a custom domain name: * From the Cloud Run services list, click **Manage custom domains**. * Click **Add mapping**. -* Select the `karaplan` service, your **verified domain** and enter the **subdomain** to use. +* Select the `karaplan` service and **Cloud Run Domain Mappings**. +* Select your **verified domain** and enter the **subdomain** to use. * Add the **CNAME record** to your domain as instructed. After a few minutes, the application should become available at the generated service URL and/or at the custom domain name. @@ -60,33 +54,29 @@ Use the following commands in [Cloud Shell](https://cloud.google.com/shell/) or # Set variables, adjust them as needed PROJECT_ID=$(gcloud config get-value project) REGION=$(gcloud config get-value compute/region) - VPC_CONNECTOR=toComplete # Create environment variables (replace 'toComplete' with appropriate values) ENV_VARS="\ SPRING_DATASOURCE_USERNAME=karaplan,\ SPRING_DATASOURCE_PASSWORD=toComplete,\ - SPRING_DATASOURCE_URL=jdbc:mysql:///toComplete?useSSL=false&socketFactory=com.google.cloud.sql.mysql.SocketFactory&cloudSqlInstance=$PROJECT_ID:$REGION:toComplete,\ - SPRING_JPA_DATABASEPLATFORM=org.hibernate.dialect.MySQL5InnoDBDialect,\ + SPRING_DATASOURCE_URL=jdbc:mysql:///karaplan?useSSL=false&socketFactory=com.google.cloud.sql.mysql.SocketFactory&cloudSqlInstance=$PROJECT_ID:$REGION:toComplete,\ SPRING_PROFILES_ACTIVE=gcp,\ SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_GOOGLE_CLIENTID=toComplete,\ SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_GOOGLE_CLIENTSECRET=toComplete,\ SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_FACEBOOK_CLIENTID=toComplete,\ SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_FACEBOOK_CLIENTSECRET=toComplete,\ SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_GITHUB_CLIENTID=toComplete,\ - SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_GITHUB_CLIENTSECRET=toComplete,\ - SPRING_SESSION_STORETYPE=redis,\ - SPRING_REDIS_HOST=toComplete" + SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_GITHUB_CLIENTSECRET=toComplete # Deploy Cloud Run service - gcloud run deploy karaplan --image eu.gcr.io/$PROJECT_ID/karaplan:master --cpu=1 --memory=1Gi --min-instances=0 --max-instances=5 --allow-unauthenticated --vpc-connector=$VPC_CONNECTOR --region=$REGION --set-env-vars="$ENV_VARS" + gcloud run deploy karaplan --image $REGION-docker.pkg.dev/$PROJECT_ID/docker/karaplan:master --cpu=1 --memory=1Gi --min-instances=0 --max-instances=5 --allow-unauthenticated --region=$REGION --set-env-vars="$ENV_VARS" If you have a custom domain name: DOMAIN=your.custom.domain # Create domain mapping - gcloud beta run domain-mappings create --service=karaplan --domain=$DOMAIN --region=$REGION + gcloud run domain-mappings create --service=karaplan --domain=$DOMAIN --region=$REGION # Add the CNAME record to your domain as instructed. diff --git a/docs/deployment/gcp/cloudrun/architecture.png b/docs/deployment/gcp/cloudrun/architecture.png index 7f7d155..8474d2f 100644 Binary files a/docs/deployment/gcp/cloudrun/architecture.png and b/docs/deployment/gcp/cloudrun/architecture.png differ diff --git a/docs/deployment/gcp/cloudrun/main.tf b/docs/deployment/gcp/cloudrun/main.tf index dfb4dc6..e85ff4e 100644 --- a/docs/deployment/gcp/cloudrun/main.tf +++ b/docs/deployment/gcp/cloudrun/main.tf @@ -16,15 +16,6 @@ resource "google_dns_record_set" "karaplan-dns-record" { rrdatas = ["ghs.googlehosted.com."] } -// Serverless VPC access connector -resource "google_vpc_access_connector" "karaplan-vpc-connector" { - name = "${var.name}-connector" - project = var.project_id - region = var.region - ip_cidr_range = var.vpc_connector_ip_range - network = var.network -} - // Cloud Run service resource "google_cloud_run_service" "karaplan-service" { name = "${var.name}-service" @@ -39,16 +30,14 @@ resource "google_cloud_run_service" "karaplan-service" { template { metadata { annotations = { - "autoscaling.knative.dev/minScale" = var.min_instances_count - "autoscaling.knative.dev/maxScale" = var.max_instances_count - "run.googleapis.com/vpc-access-connector" = google_vpc_access_connector.karaplan-vpc-connector.id - "run.googleapis.com/vpc-access-egress" = "private-ranges-only" - "run.googleapis.com/client-name" = "terraform" + "autoscaling.knative.dev/minScale" = var.min_instances_count + "autoscaling.knative.dev/maxScale" = var.max_instances_count + "run.googleapis.com/client-name" = "terraform" } } spec { containers { - image = "eu.gcr.io/${var.project_id}/karaplan:master" + image = "${var.region}-docker.pkg.dev/${var.project_id}/docker/karaplan:master" resources { limits = { cpu = "1000m" @@ -71,10 +60,6 @@ resource "google_cloud_run_service" "karaplan-service" { name = "SPRING_DATASOURCE_URL" value = "jdbc:mysql:///${var.db_name}?useSSL=false&socketFactory=com.google.cloud.sql.mysql.SocketFactory&cloudSqlInstance=${var.db_instance}" } - env { - name = "SPRING_JPA_DATABASEPLATFORM" - value = "org.hibernate.dialect.MySQL5InnoDBDialect" - } env { name = "SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_GOOGLE_CLIENTID" value = var.google_oauth_clientid @@ -99,14 +84,6 @@ resource "google_cloud_run_service" "karaplan-service" { name = "SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_GITHUB_CLIENTSECRET" value = var.github_oauth_clientsecret } - env { - name = "SPRING_SESSION_STORETYPE" - value = "redis" - } - env { - name = "SPRING_REDIS_HOST" - value = var.redis_host - } } } } diff --git a/docs/deployment/gcp/cloudrun/variables.tf b/docs/deployment/gcp/cloudrun/variables.tf index cd1a500..3f5b95c 100644 --- a/docs/deployment/gcp/cloudrun/variables.tf +++ b/docs/deployment/gcp/cloudrun/variables.tf @@ -24,10 +24,6 @@ variable "dns_name_prefix" { default = "karaplan" description = "DNS name prefix" } -variable "vpc_connector_ip_range" { - default = "10.8.0.0/28" - description = "Serverless VPC access connector IP range (/28)" -} variable "min_instances_count" { default = 0 description = "Minimum number of instances to create" @@ -48,9 +44,6 @@ variable "db_username" { variable "db_password" { description = "Database user password" } -variable "redis_host" { - description = "Redis host" -} variable "google_oauth_clientid" { description = "Google OAuth 2.0 client ID" } diff --git a/docs/deployment/gcp/cloudrun/versions.tf b/docs/deployment/gcp/cloudrun/versions.tf index b82c601..e7aa8c7 100644 --- a/docs/deployment/gcp/cloudrun/versions.tf +++ b/docs/deployment/gcp/cloudrun/versions.tf @@ -2,8 +2,7 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = "~> 3.0" + version = "~> 5.10" } } - required_version = ">= 0.13" } diff --git a/docs/deployment/gcp/gae/README.md b/docs/deployment/gcp/gae/README.md index b7c4a8d..dd72bea 100644 --- a/docs/deployment/gcp/gae/README.md +++ b/docs/deployment/gcp/gae/README.md @@ -4,14 +4,10 @@ This example uses [App Engine](https://cloud.google.com/appengine/) to run the a ## Prerequisites -Before starting, follow the [SQL](../sql) and [Memorystore](../memorystore) guides to create the database and Redis instance. - -Then, configure [Serverless VPC Access](https://cloud.google.com/vpc/docs/configure-serverless-vpc-access#creating_a_connector) as described in the official documentation, to allow communication between App Engine and the Memorystore (Redis) instance. +Before starting, follow the [SQL](../sql) guide to create the database. ## Configure the application -Open the `src/main/appengine/app.yaml` file with your preferred editor, uncomment and configure the `vpc_access_connector` block accordingly. - Copy the `src/main/appengine/files/application.example.yml` as `application.yml` in the same directory. Open it with your preferred editor and replace `toComplete` with appropriate values. Refer to the deployment [README](../../README.md) file for information about configuring identity providers. ## Deploy the application diff --git a/docs/deployment/gcp/gce-classic/README.md b/docs/deployment/gcp/gce-classic/README.md index ee2f83c..053b852 100644 --- a/docs/deployment/gcp/gce-classic/README.md +++ b/docs/deployment/gcp/gce-classic/README.md @@ -4,11 +4,11 @@ This example uses [Compute Engine](https://cloud.google.com/compute/) to run the ## Prerequisites -Before starting, follow the [Build](../build), [SQL](../sql) and [Memorystore](../memorystore) guides to create the WAR file, database and Redis instance. +Before starting, follow the [Build](../build) and [SQL](../sql) guides to create the WAR file and database. Then, if you are _not_ going to use Terraform: * Update the `${...}` variables in the `karaplan-startup.sh` file with appropriate values using your preferred editor. Refer to the deployment [README](../../README.md) file for information about configuring identity providers. -* In the side menu, go to **Storage > Browser**: +* In the side menu, go to **Cloud Storage > Browser**: * Select your bucket and enter the `karaplan` folder. * Click **Upload file** and select the `karaplan-startup.sh` file. @@ -18,35 +18,28 @@ Finally, to expose the application over HTTPS, you will need to obtain a **domai Go to [Cloud Console](https://console.cloud.google.com) and make sure the appropriate project is selected in the header menu. -In the side menu, go to **Compute > Instance templates**: +In the side menu, go to **Compute Engine > Instance templates**: * Click **Create instance template**. * Enter `karaplan-classic-template-1` as the template **name**. -* Leave the default **Machine type** as `n1-standard-1` and distribution as **Debian GNU/Linux 9 (stretch)**. -* Expand the configuration options at the bottom. -* In the **Management > Automation > Metadata** section, enter `startup-script-url` as the key and `gs://YOUR_BUCKET_NAME/karaplan/karaplan-startup.sh` as the value (replace `YOUR_BUCKET_NAME` as needed). +* Select `e2-medium` as the **Machine type** and **Debian GNU/Linux 12 (bookworm)** as the distribution. +* Select **Allow full access to all Cloud APIs** under **Access scopes**. +* Expand the advanced options at the bottom. +* In the **Management > Metadata** section, enter `startup-script-url` as the key and `gs://YOUR_BUCKET_NAME/karaplan/karaplan-startup.sh` as the value (replace `YOUR_BUCKET_NAME` as needed). * Click **Create**. -In the side menu, go to **Compute > Instance groups**: +In the side menu, go to **Compute Engine > Instance groups**: * Click **Create instance group**. * Enter `karaplan-classic-ig` as the group name. -* Select **Multiple zones** as the **Location**, then select your preferred **Region** (e.g. `europe-west1`). * Select `karaplan-classic-template-1` as the **Instance template**. +* Select **Multiple zones** as the **Location**, then select your preferred **Region** (e.g. `europe-west1`). * Set **Autoscaling** to **Off**, and set **Number of instances** to **3**. * Click **Create**. In the side menu, go to **Network services > Load balancing**: * Click **Create load balancer** -* Under **HTTP(S) Load Balancing**, click **Start configuration**. +* Under **Application Load Balancer (HTTP/S)**, click **Start configuration**. * Select **From Internet to my VMs**, then click **Continue**. * Enter `karaplan-classic-lb` as the load balancer **name**. -* In **Backend configuration**, click the dropdown menu to select **Backend services > Create a backend service**. - * Enter `karaplan-classic-bes` as the backend service **name**. - * Select `karaplan-classic-ig` as the **Instance group**, `8080` as the port number, then click **Done**. - * In **Health check**, click **Create a health check** - * Enter `karaplan-classic-hc` as the health check **name**. - * Select **HTTP** as the **Protocol**, and `8080` as the port number. - * Enter `/actuator/health/readiness` as the **Request path**. - * Click **Create**. * In **Frontend configuration**: * Enter `karaplan-classic-frontend` as the frontend service **name**. * In the **IP Address** dropdown, **Create IP address** named `karaplan-classic-ip`. @@ -55,6 +48,15 @@ In the side menu, go to **Network services > Load balancing**: * Select **HTTPS** as the **Protocol**. * In the **Certificate** dropdown, **Create a new certificate** named `karaplan-classic-ssl-cert` for your custom domain name. * Click **Done**. +* In **Backend configuration**, click the dropdown menu to select **Create a backend service**. + * Enter `karaplan-classic-bes` as the backend service **name**. + * Select `karaplan-classic-ig` as the **Instance group**, `8080` as the port number, then click **Done**. + * Uncheck **Enable Cloud CDN**. + * In **Health check**, click **Create a health check** + * Enter `karaplan-classic-hc` as the health check **name**. + * Select **HTTP** as the **Protocol**, and `8080` as the port number. + * Enter `/actuator/health/readiness` as the **Request path**. + * Click **Create**. * Click **Create**. When the loadbalancer is created, click on it to reveal its **IP address**. @@ -72,7 +74,7 @@ Use the following commands in [Cloud Shell](https://cloud.google.com/shell/) or BUCKET_NAME=$PROJECT_ID # Create Instance template - gcloud compute instance-templates create karaplan-classic-template-1 --machine-type=n1-standard-1 --image=debian-9-stretch-v20191121 --image-project=debian-cloud --boot-disk-size=10GB --boot-disk-type=pd-standard --metadata=startup-script-url=gs://$BUCKET_NAME/karaplan/karaplan-startup.sh + gcloud compute instance-templates create karaplan-classic-template-1 --machine-type=e2-medium --image-family=debian-12 --image-project=debian-cloud --boot-disk-size=10GB --boot-disk-type=pd-standard --metadata=startup-script-url=gs://$BUCKET_NAME/karaplan/karaplan-startup.sh --scopes=https://www.googleapis.com/auth/cloud-platform # Create Instance group gcloud compute instance-groups managed create karaplan-classic-ig --size=3 --template=karaplan-classic-template-1 --region=$REGION @@ -82,7 +84,8 @@ Use the following commands in [Cloud Shell](https://cloud.google.com/shell/) or gcloud compute health-checks create http karaplan-classic-hc --port=8080 --request-path=/actuator/health/readiness # Create Backend service - gcloud compute backend-services create karaplan-classic-bes --global --load-balancing-scheme=EXTERNAL --health-checks=karaplan-classic-hc --port-name=http --protocol=HTTP + gcloud compute backend-services create karaplan-classic-bes --global --load-balancing-scheme=EXTERNAL_MANAGED --health-checks=karaplan-classic-hc --port-name=http --protocol=HTTP + gcloud compute backend-services add-backend karaplan-classic-bes --global --instance-group=karaplan-classic-ig --instance-group-region=$REGION # Create URL map gcloud compute url-maps create karaplan-classic-url-map --default-service=karaplan-classic-bes @@ -97,20 +100,20 @@ If you *don't* have a custom domain name: gcloud compute target-http-proxies create karaplan-classic-http-proxy --url-map=karaplan-classic-url-map # Create Forwarding rule - gcloud compute forwarding-rules create karaplan-classic-fwd-http --global --load-balancing-scheme=EXTERNAL --target-http-proxy=karaplan-classic-http-proxy --global-address --address=karaplan-classic-ip --ports=80 + gcloud compute forwarding-rules create karaplan-classic-fwd-http --global --load-balancing-scheme=EXTERNAL_MANAGED --target-http-proxy=karaplan-classic-http-proxy --global-address --address=karaplan-classic-ip --ports=80 If you *do* have a custom domain name, add the created IP address in a **A record**, then: DOMAIN=your.custom.domain # Create SSL certificate - gcloud beta compute ssl-certificates create karaplan-classic-ssl-cert --domains=$DOMAIN --global + gcloud compute ssl-certificates create karaplan-classic-ssl-cert --domains=$DOMAIN --global # Create Target HTTPS proxy gcloud compute target-https-proxies create karaplan-classic-https-proxy --ssl-certificates=karaplan-classic-ssl-cert --url-map=karaplan-classic-url-map # Create Forwarding rule - gcloud compute forwarding-rules create karaplan-classic-fwd-https --global --load-balancing-scheme=EXTERNAL --target-https-proxy=karaplan-classic-https-proxy --global-address --address=karaplan-classic-ip --ports=443 + gcloud compute forwarding-rules create karaplan-classic-fwd-https --global --load-balancing-scheme=EXTERNAL_MANAGED --target-https-proxy=karaplan-classic-https-proxy --global-address --address=karaplan-classic-ip --ports=443 After several minutes, the application should become available at this IP address and/or at the custom domain name. diff --git a/docs/deployment/gcp/gce-classic/architecture.png b/docs/deployment/gcp/gce-classic/architecture.png index 4e2c554..3388986 100644 Binary files a/docs/deployment/gcp/gce-classic/architecture.png and b/docs/deployment/gcp/gce-classic/architecture.png differ diff --git a/docs/deployment/gcp/gce-classic/karaplan-startup.sh b/docs/deployment/gcp/gce-classic/karaplan-startup.sh index ac15376..04d45c9 100644 --- a/docs/deployment/gcp/gce-classic/karaplan-startup.sh +++ b/docs/deployment/gcp/gce-classic/karaplan-startup.sh @@ -6,30 +6,27 @@ BUCKET_NAME=$PROJECT_ID # Install Tomcat apt-get update -apt-get install -y tomcat8 -systemctl stop tomcat8 -rm -Rf /var/lib/tomcat8/webapps/ROOT +apt-get install -y openjdk-17-jre-headless tomcat10 +systemctl stop tomcat10 +rm -Rf /var/lib/tomcat10/webapps/ROOT # Download app -gsutil cp gs://$BUCKET_NAME/karaplan/karaplan.war /var/lib/tomcat8/webapps/ROOT.war +gsutil cp gs://$BUCKET_NAME/karaplan/karaplan.war /var/lib/tomcat10/webapps/ROOT.war # Configure app -mkdir -p /var/lib/tomcat8/bin -cat - > /var/lib/tomcat8/bin/setenv.sh <<'EOF' +mkdir -p /var/lib/tomcat10/bin +cat - > /var/lib/tomcat10/bin/setenv.sh <<'EOF' export SPRING_PROFILES_ACTIVE='gcp' export SPRING_DATASOURCE_USERNAME='${db_username}' export SPRING_DATASOURCE_PASSWORD='${db_password}' export SPRING_DATASOURCE_URL='jdbc:mysql:///${db_name}?useSSL=false&socketFactory=com.google.cloud.sql.mysql.SocketFactory&cloudSqlInstance=${db_instance}' -export SPRING_JPA_DATABASEPLATFORM='org.hibernate.dialect.MySQL5InnoDBDialect' export SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_GOOGLE_CLIENTID='${google_oauth_clientid}' export SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_GOOGLE_CLIENTSECRET='${google_oauth_clientsecret}' export SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_FACEBOOK_CLIENTID='${facebook_oauth_clientid}' export SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_FACEBOOK_CLIENTSECRET='${facebook_oauth_clientsecret}' export SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_GITHUB_CLIENTID='${github_oauth_clientid}' export SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_GITHUB_CLIENTSECRET='${github_oauth_clientsecret}' -export SPRING_SESSION_STORETYPE='redis' -export SPRING_REDIS_HOST='${redis_host}' EOF # Start Tomcat -systemctl restart tomcat8 +systemctl restart tomcat10 diff --git a/docs/deployment/gcp/gce-classic/main.tf b/docs/deployment/gcp/gce-classic/main.tf index 834eacc..cab88af 100644 --- a/docs/deployment/gcp/gce-classic/main.tf +++ b/docs/deployment/gcp/gce-classic/main.tf @@ -40,22 +40,24 @@ resource "google_compute_managed_ssl_certificate" "karaplan-ssl-cert" { // Forwarding rule (HTTP) resource "google_compute_global_forwarding_rule" "karaplan-fwd-http" { - count = var.http_enabled ? 1 : 0 - name = "${var.name}-fwd-http" - project = var.project_id - target = google_compute_target_http_proxy.karaplan-http-proxy[0].self_link - ip_address = google_compute_global_address.karaplan-ip.address - port_range = "80" + count = var.http_enabled ? 1 : 0 + name = "${var.name}-fwd-http" + project = var.project_id + target = google_compute_target_http_proxy.karaplan-http-proxy[0].self_link + ip_address = google_compute_global_address.karaplan-ip.address + port_range = "80" + load_balancing_scheme = "EXTERNAL_MANAGED" } // Forwarding rule (HTTPS) resource "google_compute_global_forwarding_rule" "karaplan-fwd-https" { - count = var.https_enabled ? 1 : 0 - name = "${var.name}-fwd-https" - project = var.project_id - target = google_compute_target_https_proxy.karaplan-https-proxy[0].self_link - ip_address = google_compute_global_address.karaplan-ip.address - port_range = "443" + count = var.https_enabled ? 1 : 0 + name = "${var.name}-fwd-https" + project = var.project_id + target = google_compute_target_https_proxy.karaplan-https-proxy[0].self_link + ip_address = google_compute_global_address.karaplan-ip.address + port_range = "443" + load_balancing_scheme = "EXTERNAL_MANAGED" } // Target proxy (HTTP) @@ -91,7 +93,8 @@ resource "google_compute_backend_service" "karaplan-bes" { backend { group = google_compute_region_instance_group_manager.karaplan-ig.instance_group } - health_checks = [google_compute_http_health_check.karaplan-hc.self_link] + health_checks = [google_compute_http_health_check.karaplan-hc.self_link] + load_balancing_scheme = "EXTERNAL_MANAGED" } // Health check @@ -118,7 +121,6 @@ resource "google_compute_region_instance_group_manager" "karaplan-ig" { type = "PROACTIVE" minimal_action = "RESTART" max_unavailable_fixed = 3 - min_ready_sec = 60 } named_port { @@ -139,7 +141,7 @@ resource "google_compute_instance_template" "karaplan-template" { } disk { - source_image = "debian-cloud/debian-9" + source_image = data.google_compute_image.karaplan-image.self_link auto_delete = true boot = true } @@ -169,7 +171,6 @@ resource "google_storage_bucket_object" "karaplan-startup" { db_name = var.db_name db_username = var.db_username db_password = var.db_password - redis_host = var.redis_host google_oauth_clientid = var.google_oauth_clientid google_oauth_clientsecret = var.google_oauth_clientsecret facebook_oauth_clientid = var.facebook_oauth_clientid @@ -178,3 +179,9 @@ resource "google_storage_bucket_object" "karaplan-startup" { github_oauth_clientsecret = var.github_oauth_clientsecret }) } + +// VM image +data "google_compute_image" "karaplan-image" { + family = "debian-12" + project = "debian-cloud" +} diff --git a/docs/deployment/gcp/gce-classic/variables.tf b/docs/deployment/gcp/gce-classic/variables.tf index 51bb9ee..72a0146 100644 --- a/docs/deployment/gcp/gce-classic/variables.tf +++ b/docs/deployment/gcp/gce-classic/variables.tf @@ -36,7 +36,7 @@ variable "instances_count" { description = "Number of instances to create" } variable "machine_type" { - default = "n1-standard-1" + default = "e2-medium" description = "Machine type" } variable "db_instance" { @@ -51,9 +51,6 @@ variable "db_username" { variable "db_password" { description = "Database user password" } -variable "redis_host" { - description = "Redis host" -} variable "google_oauth_clientid" { description = "Google OAuth 2.0 client ID" } diff --git a/docs/deployment/gcp/gce-classic/versions.tf b/docs/deployment/gcp/gce-classic/versions.tf index b82c601..e7aa8c7 100644 --- a/docs/deployment/gcp/gce-classic/versions.tf +++ b/docs/deployment/gcp/gce-classic/versions.tf @@ -2,8 +2,7 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = "~> 3.0" + version = "~> 5.10" } } - required_version = ">= 0.13" } diff --git a/docs/deployment/gcp/gce-container/README.md b/docs/deployment/gcp/gce-container/README.md index eb59c9f..e0c441f 100644 --- a/docs/deployment/gcp/gce-container/README.md +++ b/docs/deployment/gcp/gce-container/README.md @@ -4,7 +4,7 @@ This example uses [Compute Engine](https://cloud.google.com/compute/) to run the ## Prerequisites -Before starting, follow the [Build](../build), [SQL](../sql) and [Memorystore](../memorystore) guides to create the container image, database and Redis instance. +Before starting, follow the [Build](../build) and [SQL](../sql) guides to create the container image and database. Then, refer to the deployment [README](../../README.md) file for information about configuring identity providers. @@ -14,52 +14,44 @@ Finally, to expose the application over HTTPS, you will need to obtain a **domai Go to [Cloud Console](https://console.cloud.google.com) and make sure the appropriate project is selected in the header menu. -In the side menu, go to **Compute > Instance templates**: +In the side menu, go to **Compute Engine > Instance templates**: * Click **Create instance template**. * Enter `karaplan-container-template-1` as the template **name**. -* Leave the default **Machine type** as `n1-standard-1`. -* Check **Deploy a container image to this VM instance** and enter the container image name, e.g. `eu.gcr.io/YOUR_PROJECT_ID/karaplan:master`, or the official image `ghcr.io/fcrespel/karaplan:master`. -* Expand the advanced container options just below. +* Select `e2-medium` as the **Machine type**. +* Click **Deploy container** +* Enter the container image name, e.g. `europe-west1-docker.pkg.dev/YOUR_PROJECT_ID/docker/karaplan:master`, or the official image `ghcr.io/fcrespel/karaplan:master`. * Add the following **Environment variables** (replace `toComplete` with appropriate values): | Name | Value | | ---- | ----- | +| SPRING_PROFILES_ACTIVE | gcp | | SPRING_DATASOURCE_USERNAME | karaplan | | SPRING_DATASOURCE_PASSWORD | toComplete | -| SPRING_DATASOURCE_URL | jdbc:mysql:///toComplete?useSSL=false&socketFactory=com.google.cloud.sql.mysql.SocketFactory&cloudSqlInstance=toComplete | -| SPRING_JPA_DATABASEPLATFORM | org.hibernate.dialect.MySQL5InnoDBDialect | +| SPRING_DATASOURCE_URL | jdbc:mysql:///karaplan?useSSL=false&socketFactory=com.google.cloud.sql.mysql.SocketFactory&cloudSqlInstance=toComplete | | SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_GOOGLE_CLIENTID | toComplete | | SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_GOOGLE_CLIENTSECRET | toComplete | | SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_FACEBOOK_CLIENTID | toComplete | | SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_FACEBOOK_CLIENTSECRET | toComplete | | SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_GITHUB_CLIENTID | toComplete | | SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_GITHUB_CLIENTSECRET | toComplete | -| SPRING_SESSION_STORETYPE | redis | -| SPRING_REDIS_HOST | toComplete | +* Click **Select**. +* Select **Allow full access to all Cloud APIs** under **Access scopes**. * Click **Create**. -In the side menu, go to **Compute > Instance groups**: +In the side menu, go to **Compute Engine > Instance groups**: * Click **Create instance group**. * Enter `karaplan-container-ig` as the group name. -* Select **Multiple zones** as the **Location**, then select your preferred **Region** (e.g. `europe-west1`). * Select `karaplan-container-template-1` as the **Instance template**. +* Select **Multiple zones** as the **Location**, then select your preferred **Region** (e.g. `europe-west1`). * Set **Autoscaling** to **Off**, and set **Number of instances** to **3**. * Click **Create**. In the side menu, go to **Network services > Load balancing**: * Click **Create load balancer** -* Under **HTTP(S) Load Balancing**, click **Start configuration**. +* Under **Application Load Balancer (HTTP/S)**, click **Start configuration**. * Select **From Internet to my VMs**, then click **Continue**. * Enter `karaplan-container-lb` as the load balancer **name**. -* In **Backend configuration**, click the dropdown menu to select **Backend services > Create a backend service**. - * Enter `karaplan-container-bes` as the backend service **name**. - * Select `karaplan-container-ig` as the **Instance group**, `8080` as the port number, then click **Done**. - * In **Health check**, click **Create a health check** - * Enter `karaplan-container-hc` as the health check **name**. - * Select **HTTP** as the **Protocol**, and `8080` as the port number. - * Enter `/actuator/health/readiness` as the **Request path**. - * Click **Create**. * In **Frontend configuration**: * Enter `karaplan-container-frontend` as the frontend service **name**. * In the **IP Address** dropdown, **Create IP address** named `karaplan-container-ip`. @@ -68,6 +60,15 @@ In the side menu, go to **Network services > Load balancing**: * Select **HTTPS** as the **Protocol**. * In the **Certificate** dropdown, **Create a new certificate** named `karaplan-container-ssl-cert` for your custom domain name. * Click **Done**. +* In **Backend configuration**, click the dropdown menu to select **Create a backend service**. + * Enter `karaplan-container-bes` as the backend service **name**. + * Select `karaplan-container-ig` as the **Instance group**, `8080` as the port number, then click **Done**. + * Uncheck **Enable Cloud CDN**. + * In **Health check**, click **Create a health check** + * Enter `karaplan-container-hc` as the health check **name**. + * Select **HTTP** as the **Protocol**, and `8080` as the port number. + * Enter `/actuator/health/readiness` as the **Request path**. + * Click **Create**. * Click **Create**. When the loadbalancer is created, click on it to reveal its **IP address**. @@ -85,22 +86,20 @@ Use the following commands in [Cloud Shell](https://cloud.google.com/shell/) or # Create environment variables (replace 'toComplete' with appropriate values) cat - > karaplan.env < Clusters** if you don't already have a Kubernetes Cluster: -* Click **Create cluster**. +* Click **Create cluster** and use Autopilot mode. * Enter `karaplan-gke-cluster` as the cluster **name**. -* Select **Regional** as the **Location type**, then select your preferred **Region** (e.g. `europe-west1`). -* In the default **Node pool**, specify `1` for the **number of nodes**. -* Select `n1-standard-2` as the **Machine type**. +* Select your preferred **Region** (e.g. `europe-west1`). * Click **Create**. In the side menu, go to **VPC network > External IP addresses**: @@ -44,23 +42,32 @@ In the side menu, go to **Kubernetes Engine > Workloads** to monitor the deploym Use the following commands in [Cloud Shell](https://cloud.google.com/shell/) or anywhere the [Cloud SDK](https://cloud.google.com/sdk/) is installed: # Set variables, adjust them as needed + PROJECT_ID=$(gcloud config get-value project) REGION=$(gcloud config get-value compute/region) + NAMESPACE=default # Create GKE cluster, if necessary - gcloud container clusters create karaplan-gke-cluster --region=$REGION --machine-type=n1-standard-2 --num-nodes=1 + gcloud container clusters create-auto karaplan-gke-cluster --region=$REGION # Create IP address gcloud compute addresses create karaplan-gke-ip --global gcloud compute addresses list + # Create service account and grant access to the SQL database + gcloud iam service-accounts create karaplan + gcloud projects add-iam-policy-binding $PROJECT_ID --member="serviceAccount:karaplan@$PROJECT_ID.iam.gserviceaccount.com" --role=roles/cloudsql.client + + # Configure Workload Identity + gcloud iam service-accounts add-iam-policy-binding karaplan@$PROJECT_ID.iam.gserviceaccount.com --member="serviceAccount:$PROJECT_ID.svc.id.goog[$NAMESPACE/karaplan]" --role=roles/iam.workloadIdentityUser + If you have a custom domain name, add the created IP address in a **A record**, then: DOMAIN=your.custom.domain # Create SSL certificate - gcloud beta compute ssl-certificates create karaplan-gke-ssl-cert --domains=$DOMAIN --global + gcloud compute ssl-certificates create karaplan-gke-ssl-cert --domains=$DOMAIN --global -If you are using **Cloud Shell**, you may use the 3-dots menu to upload the `karaplan.yaml` file prepared in *Prerequisites* to your current session. +If you are using **Cloud Shell**, you may use the 3-dots menu to upload the `values.yaml` file prepared in *Prerequisites* to your current session. **Deploy** the application to Kubernetes: @@ -68,10 +75,10 @@ If you are using **Cloud Shell**, you may use the 3-dots menu to upload the `kar gcloud container clusters get-credentials karaplan-gke-cluster --region=$REGION # Preview template before installing it - helm template -f karaplan.yaml ../../helm/karaplan + helm template karaplan ../../helm/karaplan -f values.yaml # Install application - helm install -f karaplan.yaml ../../helm/karaplan + helm upgrade -i karaplan ../../helm/karaplan -f values.yaml After several minutes, the application should become available at the reserved IP address and/or at the custom domain name. diff --git a/docs/deployment/gcp/gke/architecture.png b/docs/deployment/gcp/gke/architecture.png index 6e0421b..75f6973 100644 Binary files a/docs/deployment/gcp/gke/architecture.png and b/docs/deployment/gcp/gke/architecture.png differ diff --git a/docs/deployment/gcp/gke/karaplan.yaml b/docs/deployment/gcp/gke/karaplan.yaml deleted file mode 100644 index a60e406..0000000 --- a/docs/deployment/gcp/gke/karaplan.yaml +++ /dev/null @@ -1,33 +0,0 @@ -replicaCount: 3 - -ingress: - enabled: true - annotations: - kubernetes.io/ingress.global-static-ip-name: karaplan-gke-ip - ingress.gcp.kubernetes.io/pre-shared-cert: karaplan-gke-ssl-cert - -resources: - limits: - cpu: 1000m - memory: 1Gi - requests: - cpu: 500m - memory: 512Mi - -backendConfig: - enabled: true - -env: - SPRING_PROFILES_ACTIVE: "gcp" - SPRING_DATASOURCE_USERNAME: "karaplan" - SPRING_DATASOURCE_PASSWORD: "toComplete" - SPRING_DATASOURCE_URL: "jdbc:mysql:///toComplete?useSSL=false&socketFactory=com.google.cloud.sql.mysql.SocketFactory&cloudSqlInstance=toComplete" - SPRING_JPA_DATABASEPLATFORM: "org.hibernate.dialect.MySQL5InnoDBDialect" - SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_GOOGLE_CLIENTID: "toComplete" - SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_GOOGLE_CLIENTSECRET: "toComplete" - SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_FACEBOOK_CLIENTID: "toComplete" - SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_FACEBOOK_CLIENTSECRET: "toComplete" - SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_GITHUB_CLIENTID: "toComplete" - SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_GITHUB_CLIENTSECRET: "toComplete" - SPRING_SESSION_STORETYPE: "redis" - SPRING_REDIS_HOST: "toComplete" diff --git a/docs/deployment/gcp/gke/main.tf b/docs/deployment/gcp/gke/main.tf index 606d83a..26b8d64 100644 --- a/docs/deployment/gcp/gke/main.tf +++ b/docs/deployment/gcp/gke/main.tf @@ -38,26 +38,20 @@ resource "google_compute_managed_ssl_certificate" "karaplan-ssl-cert" { } } -// Environment secret -resource "kubernetes_secret" "karaplan-env-secret" { - metadata { - name = "${var.name}-env-secret" - namespace = var.namespace - } - data = { - SPRING_DATASOURCE_USERNAME = var.db_username - SPRING_DATASOURCE_PASSWORD = var.db_password - SPRING_DATASOURCE_URL = "jdbc:mysql:///${var.db_name}?useSSL=false&socketFactory=com.google.cloud.sql.mysql.SocketFactory&cloudSqlInstance=${var.db_instance}" - SPRING_JPA_DATABASEPLATFORM = "org.hibernate.dialect.MySQL5InnoDBDialect" - SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_GOOGLE_CLIENTID = var.google_oauth_clientid - SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_GOOGLE_CLIENTSECRET = var.google_oauth_clientsecret - SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_FACEBOOK_CLIENTID = var.facebook_oauth_clientid - SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_FACEBOOK_CLIENTSECRET = var.facebook_oauth_clientsecret - SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_GITHUB_CLIENTID = var.github_oauth_clientid - SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_GITHUB_CLIENTSECRET = var.github_oauth_clientsecret - SPRING_SESSION_STORETYPE = "redis" - SPRING_REDIS_HOST = var.redis_host - } +// Service account +resource "google_service_account" "karaplan-sa" { + project = var.project_id + account_id = var.name +} +resource "google_service_account_iam_member" "karaplan-sa-workload-identity" { + service_account_id = google_service_account.karaplan-sa.name + role = "roles/iam.workloadIdentityUser" + member = "serviceAccount:${var.project_id}.svc.id.goog[${var.namespace}/${var.name}]" +} +resource "google_project_iam_member" "karaplan-sa-sql-client" { + project = var.project_id + role = "roles/cloudsql.client" + member = "serviceAccount:${google_service_account.karaplan-sa.email}" } // Helm release @@ -66,55 +60,22 @@ resource "helm_release" "karaplan-helm-release" { chart = "${path.module}/../../helm/karaplan" namespace = var.namespace - set { - name = "replicaCount" - value = var.replica_count - } - set { - name = "ingress.enabled" - value = var.http_enabled || var.https_enabled - } - set { - name = "ingress.annotations.kubernetes\\.io/ingress\\.allow-http" - type = "string" - value = var.http_enabled - } - set { - name = "ingress.annotations.kubernetes\\.io/ingress\\.global-static-ip-name" - type = "string" - value = google_compute_global_address.karaplan-ip.name - } - set { - name = "ingress.annotations.ingress\\.gcp\\.kubernetes\\.io/pre-shared-cert" - type = "string" - value = var.https_enabled ? google_compute_managed_ssl_certificate.karaplan-ssl-cert[0].name : "" - } - set { - name = "backendConfig.enabled" - value = true - } - set { - name = "application.enabled" - value = var.application_enabled - } - set { - name = "resources.limits.cpu" - value = "1000m" - } - set { - name = "resources.limits.memory" - value = "1Gi" - } - set { - name = "resources.requests.cpu" - value = "500m" - } - set { - name = "resources.requests.memory" - value = "512Mi" - } - set { - name = "envFromSecret" - value = kubernetes_secret.karaplan-env-secret.metadata[0].name - } + values = [templatefile("${path.module}/values.yaml", { + replica_count = var.replica_count + gcp_service_account = google_service_account.karaplan-sa.email + gcp_ip_address = google_compute_global_address.karaplan-ip.name + gcp_ssl_cert = var.https_enabled ? google_compute_managed_ssl_certificate.karaplan-ssl-cert[0].name : "" + ingress_enabled = var.http_enabled || var.https_enabled + ingress_allow_http = var.http_enabled + db_instance = var.db_instance + db_name = var.db_name + db_username = var.db_username + db_password = var.db_password + google_oauth_clientid = var.google_oauth_clientid + google_oauth_clientsecret = var.google_oauth_clientsecret + facebook_oauth_clientid = var.facebook_oauth_clientid + facebook_oauth_clientsecret = var.facebook_oauth_clientsecret + github_oauth_clientid = var.github_oauth_clientid + github_oauth_clientsecret = var.github_oauth_clientsecret + })] } diff --git a/docs/deployment/gcp/gke/values.yaml b/docs/deployment/gcp/gke/values.yaml new file mode 100644 index 0000000..4c8ec54 --- /dev/null +++ b/docs/deployment/gcp/gke/values.yaml @@ -0,0 +1,40 @@ +replicaCount: ${replica_count} + +serviceAccount: + annotations: + iam.gke.io/gcp-service-account: "${gcp_service_account}" + +ingress: + enabled: ${ingress_enabled} + annotations: + kubernetes.io/ingress.allow-http: "${ingress_allow_http}" + kubernetes.io/ingress.global-static-ip-name: "${gcp_ip_address}" + ingress.gcp.kubernetes.io/pre-shared-cert: "${gcp_ssl_cert}" + hosts: + - host: "" + paths: + - path: /* + pathType: ImplementationSpecific + +resources: + limits: + cpu: 500m + memory: 1Gi + requests: + cpu: 500m + memory: 1Gi + +backendConfig: + enabled: true + +env: + SPRING_PROFILES_ACTIVE: "gcp" + SPRING_DATASOURCE_USERNAME: "${db_username}" + SPRING_DATASOURCE_PASSWORD: "${db_password}" + SPRING_DATASOURCE_URL: "jdbc:mysql:///${db_name}?useSSL=false&socketFactory=com.google.cloud.sql.mysql.SocketFactory&cloudSqlInstance=${db_instance}" + SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_GOOGLE_CLIENTID: "${google_oauth_clientid}" + SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_GOOGLE_CLIENTSECRET: "${google_oauth_clientsecret}" + SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_FACEBOOK_CLIENTID: "${facebook_oauth_clientid}" + SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_FACEBOOK_CLIENTSECRET: "${facebook_oauth_clientsecret}" + SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_GITHUB_CLIENTID: "${github_oauth_clientid}" + SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_GITHUB_CLIENTSECRET: "${github_oauth_clientsecret}" diff --git a/docs/deployment/gcp/gke/variables.tf b/docs/deployment/gcp/gke/variables.tf index b2feefc..ec40347 100644 --- a/docs/deployment/gcp/gke/variables.tf +++ b/docs/deployment/gcp/gke/variables.tf @@ -36,10 +36,6 @@ variable "replica_count" { default = 3 description = "Deployment replica count" } -variable "application_enabled" { - default = false - description = "Enable application metadata (requires Application CRD, see https://github.com/kubernetes-sigs/application)" -} variable "db_instance" { description = "Database instance (project_id:region:instance_name)" } @@ -52,9 +48,6 @@ variable "db_username" { variable "db_password" { description = "Database user password" } -variable "redis_host" { - description = "Redis host" -} variable "google_oauth_clientid" { description = "Google OAuth 2.0 client ID" } diff --git a/docs/deployment/gcp/gke/versions.tf b/docs/deployment/gcp/gke/versions.tf index 9a6f3da..82b2b9d 100644 --- a/docs/deployment/gcp/gke/versions.tf +++ b/docs/deployment/gcp/gke/versions.tf @@ -2,16 +2,15 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = "~> 3.0" + version = "~> 5.10" } helm = { source = "hashicorp/helm" - version = "~> 1.0" + version = "~> 2.12" } kubernetes = { source = "hashicorp/kubernetes" - version = "~> 1.10" + version = "~> 2.24" } } - required_version = ">= 0.13" } diff --git a/docs/deployment/gcp/memorystore/README.md b/docs/deployment/gcp/memorystore/README.md deleted file mode 100644 index b9c5eca..0000000 --- a/docs/deployment/gcp/memorystore/README.md +++ /dev/null @@ -1,35 +0,0 @@ -# Google Cloud Memorystore - -This example uses [Cloud Memorystore](https://cloud.google.com/memorystore/) to deploy a Redis instance for distributed caching. - -It can then be used for sharing sessions across multiple instances of the application, as an alternative to sticky sessions. - -## Using Cloud Console - -Go to [Cloud Console](https://console.cloud.google.com) and make sure the appropriate project is selected in the header menu. - -In the side menu, go to **Memorystore**: -* Click **Create instance**. -* Choose an **Instance ID** such as `karaplan-redis`. -* Choose a **Region** (e.g. `europe-west1`). -* Click **Create**. - -Take note of the **IP address** for use during application deployment. - -## Using Cloud Shell / SDK - -Use the following commands in [Cloud Shell](https://cloud.google.com/shell/) or anywhere the [Cloud SDK](https://cloud.google.com/sdk/) is installed: - - # Set variables, adjust them as needed - REGION=$(gcloud config get-value compute/region) - - # Create Redis instance (takes some time) - gcloud redis instances create karaplan-redis --region=$REGION - -Take note of the **IP address** for use during application deployment. - -## Using Terraform - -This directory contains a [Terraform](https://terraform.io) module to provision all resources automatically. See the `main.tf`, `variables.tf` and `outputs.tf` files for more information. - -Please refer to the [Terraform](../terraform) guide for a full example. diff --git a/docs/deployment/gcp/memorystore/main.tf b/docs/deployment/gcp/memorystore/main.tf deleted file mode 100644 index d48685c..0000000 --- a/docs/deployment/gcp/memorystore/main.tf +++ /dev/null @@ -1,14 +0,0 @@ -// Network -data "google_compute_network" "karaplan-network" { - name = var.network - project = var.project_id -} - -// Redis instance -resource "google_redis_instance" "karaplan-redis" { - name = "${var.name}-redis" - project = var.project_id - region = var.region - memory_size_gb = 1 - authorized_network = data.google_compute_network.karaplan-network.self_link -} diff --git a/docs/deployment/gcp/memorystore/outputs.tf b/docs/deployment/gcp/memorystore/outputs.tf deleted file mode 100644 index 05fb520..0000000 --- a/docs/deployment/gcp/memorystore/outputs.tf +++ /dev/null @@ -1,8 +0,0 @@ -output "redis_host" { - value = google_redis_instance.karaplan-redis.host - description = "Redis host" -} -output "redis_port" { - value = google_redis_instance.karaplan-redis.port - description = "Redis port" -} diff --git a/docs/deployment/gcp/memorystore/variables.tf b/docs/deployment/gcp/memorystore/variables.tf deleted file mode 100644 index 8a44188..0000000 --- a/docs/deployment/gcp/memorystore/variables.tf +++ /dev/null @@ -1,14 +0,0 @@ -variable "name" { - default = "karaplan" - description = "Name to use in all resources of this module" -} -variable "project_id" { - description = "GCP project ID" -} -variable "region" { - description = "GCP region" -} -variable "network" { - default = "default" - description = "VPC network name" -} diff --git a/docs/deployment/gcp/memorystore/versions.tf b/docs/deployment/gcp/memorystore/versions.tf deleted file mode 100644 index b82c601..0000000 --- a/docs/deployment/gcp/memorystore/versions.tf +++ /dev/null @@ -1,9 +0,0 @@ -terraform { - required_providers { - google = { - source = "hashicorp/google" - version = "~> 3.0" - } - } - required_version = ">= 0.13" -} diff --git a/docs/deployment/gcp/sql/README.md b/docs/deployment/gcp/sql/README.md index 5b88561..87e8ba0 100644 --- a/docs/deployment/gcp/sql/README.md +++ b/docs/deployment/gcp/sql/README.md @@ -10,6 +10,8 @@ In the side menu, go to **SQL**: * Click **Create instance** and choose **MySQL**. * Choose an **Instance ID** such as `karaplan`. * Generate a **root password** or type a secure one. +* Select **MySQL 8.0** as the database version. +* Select the **Cloud SQL Edition** and **preset** (e.g. Enterprise and Sandbox). * Choose a **Region** (e.g. `europe-west1`). * Expand the configuration options at the bottom. * Adjust **Backup** and **Maintenance** settings if necessary. @@ -31,7 +33,7 @@ Use the following commands in [Cloud Shell](https://cloud.google.com/shell/) or USER_PASSWORD=$(