Skip to content

Commit 3e03976

Browse files
authored
[Cloud Run] Identity platform sample (GoogleCloudPlatform#4496)
* draft * Rename sample * Identity platform sample * remove extra file * Lint * Update region tags * Update license * Update table name and JS comments * Get header and lint * Add secret for deployment * fix error in kokoro script * Fix env var name * Throw error when env var is not found * lint
1 parent f58c4ff commit 3e03976

18 files changed

Lines changed: 1026 additions & 13 deletions

File tree

.kokoro/tests/build_cloud_run.sh

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -36,31 +36,35 @@ if [ -n "$JIB" ]; then
3636
}
3737
requireEnv SAMPLE_NAME
3838

39-
# Version is in the format <PR#>-<GIT COMMIT SHA>.
40-
# Ensures PR-based triggers of the same branch don't collide if Kokoro attempts
41-
# to run them concurrently.
42-
export SAMPLE_VERSION="${KOKORO_GIT_COMMIT:-latest}"
43-
# Builds not triggered by a PR will fall back to the commit hash then "latest".
44-
SUFFIX=${KOKORO_GITHUB_PULL_REQUEST_NUMBER:-${SAMPLE_VERSION:0:12}}
45-
export SERVICE_NAME="${SAMPLE_NAME}-${SUFFIX}"
46-
# Remove "/" from the Cloud Run service name
47-
export SERVICE_NAME="${SERVICE_NAME//\//$'-'}"
48-
export CONTAINER_IMAGE="gcr.io/${GOOGLE_CLOUD_PROJECT}/run-${SAMPLE_NAME}:${SAMPLE_VERSION}"
49-
export SPECIAL_BASE_IMAGE="gcr.io/${GOOGLE_CLOUD_PROJECT}/imagemagick"
50-
BASE_IMAGE_SAMPLES=("image-processing" "system-packages")
39+
# Version is in the format <PR#>-<GIT COMMIT SHA>.
40+
# Ensures PR-based triggers of the same branch don't collide if Kokoro attempts
41+
# to run them concurrently.
42+
export SAMPLE_VERSION="${KOKORO_GIT_COMMIT:-latest}"
43+
# Builds not triggered by a PR will fall back to the commit hash then "latest".
44+
SUFFIX=${KOKORO_GITHUB_PULL_REQUEST_NUMBER:-${SAMPLE_VERSION:0:12}}
45+
export SERVICE_NAME="${SAMPLE_NAME}-${SUFFIX}"
46+
# Remove "/" from the Cloud Run service name
47+
export SERVICE_NAME="${SERVICE_NAME//\//$'-'}"
48+
export CONTAINER_IMAGE="gcr.io/${GOOGLE_CLOUD_PROJECT}/run-${SAMPLE_NAME}:${SAMPLE_VERSION}"
49+
export SPECIAL_BASE_IMAGE="gcr.io/${GOOGLE_CLOUD_PROJECT}/imagemagick"
50+
BASE_IMAGE_SAMPLES=("image-processing" "system-packages")
5151

5252
# Build the service
5353
set -x
5454

5555
mvn -q -B jib:build -Dimage="${CONTAINER_IMAGE}" \
5656
`if [[ "${BASE_IMAGE_SAMPLES[@]}" =~ "${SAMPLE_NAME}" ]]; then echo "-Djib.from.image=${SPECIAL_BASE_IMAGE}"; fi`
5757

58+
59+
export MEMORY_NEEDED=("image-processing" "idp-sql"); # Samples that need more memory
60+
5861
gcloud run deploy "${SERVICE_NAME}" \
5962
--image="${CONTAINER_IMAGE}" \
6063
--region="${REGION:-us-central1}" \
6164
--platform=managed \
6265
--quiet --no-user-output-enabled \
63-
`if [ $SAMPLE_NAME = "image-processing" ]; then echo "--memory 512M"; fi`
66+
`if [[ "${MEMORY_NEEDED[@]}" =~ "${SAMPLE_NAME}" ]]; then echo "--memory 512M"; fi` \
67+
`if [ $SAMPLE_NAME = "idp-sql" ]; then echo "--update-env-vars SECRET_NAME=idp-sql-secret"; fi`
6468

6569

6670
set +x

run/idp-sql/README.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Cloud Run End User Authentication with PostgreSQL Database Sample
2+
3+
This sample integrates with the Identity Platform to authenticate users to the
4+
application and connects to a Cloud SQL postgreSQL database for data storage.
5+
6+
Use it with the [End user Authentication for Cloud Run](http://cloud.google.com/run/docs/tutorials/identity-platform).
7+
8+
For more details on how to work with this sample read the [Google Cloud Run Java Samples README](https://github.com/GoogleCloudPlatform/java-docs-samples/tree/master/run).
9+
10+
[![Run on Google Cloud](https://deploy.cloud.run/button.svg)](https://deploy.cloud.run/)
11+
12+
## Dependencies
13+
14+
* **Spring Boot**: Web server framework.
15+
* **Spring Cloud GCP**: PostgreSQL, Logging
16+
* **Logback + SLF4J**: Logging framework
17+
* **Thymeleaf** Java template engine
18+
* **Jib**: Container build tool
19+
* **googl-cloud-secretmanager**: Google Secret Manager client library
20+
* **firebase-admin**: Verifying JWT token
21+
* **okhttp + google-auth-library**: Access [compute metadata server](https://cloud.google.com/compute/docs/storing-retrieving-metadata) for project Id
22+
* **Lombok**: Generate getters and setters
23+
* **Firebase JavaScript SDK**: client-side library for authentication flow
24+
25+
## Environment Variables
26+
27+
Cloud Run services can be [configured with Environment Variables](https://cloud.google.com/run/docs/configuring/environment-variables).
28+
Required variables for this sample include:
29+
30+
* `SECRET_NAME`: the resource ID of the secret. See [postgres-secrets.json](postgres-secrets.json) for secret content.
31+
* `VERSION` (optional): the version ID of the secret.
32+
33+
OR
34+
35+
Uncomment variables in `application.properties` and set:
36+
* `CLOUD_SQL_CONNECTION_NAME`: Cloud SQL instance name, in format: `<MY-PROJECT>:<INSTANCE-REGION>:<MY-DATABASE>`
37+
* `DB_NAME`: Cloud SQL postgreSQL database name
38+
* `DB_USER`: database user
39+
* `DB_PASSWORD`: database password
40+
41+
## Production Considerations
42+
43+
* Both `postgres-secrets.json` and `static/config.js` should not be committed to
44+
a git repository and should be added to `.gitignore`.
45+
46+
* Saving credentials directly as environment variables is convenient for local testing,
47+
but not secure for production; therefore using `SECRET_NAME` and `VERSION`
48+
in combination with the Cloud Secrets Manager is recommended.
49+
50+
## Running Locally
51+
52+
```
53+
mvn spring-boot:run
54+
```

run/idp-sql/app.json

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"name": "idp-sql",
3+
"env": {
4+
"DB_PASSWORD": {
5+
"description": "postgreSQL password for root user"
6+
},
7+
"CLOUD_SQL_INSTANCE_NAME": {
8+
"description": "Cloud SQL instance name",
9+
"value": "idp-sql-instance"
10+
},
11+
"API_KEY": {
12+
"description": "Identity Platform API key from Application Setup Details"
13+
}
14+
},
15+
"hooks": {
16+
"precreate": {
17+
"commands": [
18+
"./setup.sh"
19+
]
20+
},
21+
"postcreate": {
22+
"commands": [
23+
"./postcreate.sh"
24+
]
25+
}
26+
}
27+
}

run/idp-sql/pom.xml

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
Copyright 2021 Google LLC
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
http://www.apache.org/licenses/LICENSE-2.0
8+
Unless required by applicable law or agreed to in writing, software
9+
distributed under the License is distributed on an "AS IS" BASIS,
10+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
See the License for the specific language governing permissions and
12+
limitations under the License.
13+
-->
14+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
15+
<modelVersion>4.0.0</modelVersion>
16+
<groupId>com.example.cloudrun</groupId>
17+
<artifactId>idp-sql</artifactId>
18+
<version>0.0.1-SNAPSHOT</version>
19+
<packaging>jar</packaging>
20+
21+
<!-- The parent pom defines common style checks and testing strategies for our samples.
22+
Removing or replacing it should not affect the execution of the samples in anyway. -->
23+
24+
<parent>
25+
<groupId>com.google.cloud.samples</groupId>
26+
<artifactId>shared-configuration</artifactId>
27+
<version>1.0.18</version>
28+
</parent>
29+
30+
<properties>
31+
<maven.compiler.target>11</maven.compiler.target>
32+
<maven.compiler.source>11</maven.compiler.source>
33+
</properties>
34+
35+
<dependencyManagement>
36+
<dependencies>
37+
<dependency>
38+
<!-- Import dependency management from Spring Boot -->
39+
<groupId>org.springframework.boot</groupId>
40+
<artifactId>spring-boot-dependencies</artifactId>
41+
<version>2.4.1</version>
42+
<type>pom</type>
43+
<scope>import</scope>
44+
</dependency>
45+
<dependency>
46+
<groupId>org.springframework.cloud</groupId>
47+
<artifactId>spring-cloud-dependencies</artifactId>
48+
<version>Hoxton.SR8</version>
49+
<type>pom</type>
50+
<scope>import</scope>
51+
</dependency>
52+
</dependencies>
53+
</dependencyManagement>
54+
55+
<dependencies>
56+
<dependency>
57+
<groupId>org.springframework.boot</groupId>
58+
<artifactId>spring-boot-starter-web</artifactId>
59+
</dependency>
60+
<dependency>
61+
<groupId>org.springframework.boot</groupId>
62+
<artifactId>spring-boot-starter-jdbc</artifactId>
63+
</dependency>
64+
<dependency>
65+
<groupId>org.springframework.boot</groupId>
66+
<artifactId>spring-boot-starter-thymeleaf</artifactId>
67+
</dependency>
68+
<dependency>
69+
<groupId>org.springframework.cloud</groupId>
70+
<artifactId>spring-cloud-gcp-starter</artifactId>
71+
</dependency>
72+
<dependency>
73+
<groupId>org.springframework.cloud</groupId>
74+
<artifactId>spring-cloud-gcp-starter-sql-postgresql</artifactId>
75+
</dependency>
76+
<dependency>
77+
<groupId>org.springframework.cloud</groupId>
78+
<artifactId>spring-cloud-gcp-starter-logging</artifactId>
79+
</dependency>
80+
<dependency>
81+
<groupId>net.logstash.logback</groupId>
82+
<artifactId>logstash-logback-encoder</artifactId>
83+
<version>6.5</version>
84+
</dependency>
85+
<dependency>
86+
<groupId>ch.qos.logback.contrib</groupId>
87+
<artifactId>logback-json-classic</artifactId>
88+
<version>0.1.5</version>
89+
</dependency>
90+
<dependency>
91+
<groupId>ch.qos.logback.contrib</groupId>
92+
<artifactId>logback-jackson</artifactId>
93+
<version>0.1.5</version>
94+
</dependency>
95+
<dependency>
96+
<groupId>com.google.firebase</groupId>
97+
<artifactId>firebase-admin</artifactId>
98+
<version>7.1.0</version>
99+
</dependency>
100+
<dependency>
101+
<groupId>com.google.cloud</groupId>
102+
<artifactId>google-cloud-secretmanager</artifactId>
103+
<version>1.2.6</version>
104+
</dependency>
105+
<dependency>
106+
<groupId>org.projectlombok</groupId>
107+
<artifactId>lombok</artifactId>
108+
<version>1.18.16</version>
109+
</dependency>
110+
<dependency>
111+
<groupId>com.squareup.okhttp3</groupId>
112+
<artifactId>okhttp</artifactId>
113+
<version>4.10.0-RC1</version>
114+
</dependency>
115+
<dependency>
116+
<groupId>com.google.gms</groupId>
117+
<artifactId>google-services</artifactId>
118+
<version>3.1.1</version>
119+
</dependency>
120+
<dependency>
121+
<groupId>org.springframework.boot</groupId>
122+
<artifactId>spring-boot-starter-test</artifactId>
123+
<scope>test</scope>
124+
</dependency>
125+
<dependency>
126+
<groupId>junit</groupId>
127+
<artifactId>junit</artifactId>
128+
<version>4.13</version>
129+
<scope>test</scope>
130+
</dependency>
131+
</dependencies>
132+
133+
<build>
134+
<plugins>
135+
<plugin>
136+
<groupId>org.springframework.boot</groupId>
137+
<artifactId>spring-boot-maven-plugin</artifactId>
138+
</plugin>
139+
<!-- [START cloudrun_user_auth_jib] -->
140+
<plugin>
141+
<groupId>com.google.cloud.tools</groupId>
142+
<artifactId>jib-maven-plugin</artifactId>
143+
<version>2.7.1</version>
144+
<configuration>
145+
<to>
146+
<image>gcr.io/PROJECT_ID/idp-sql</image>
147+
</to>
148+
</configuration>
149+
</plugin>
150+
<!-- [END cloudrun_user_auth_jib] -->
151+
</plugins>
152+
</build>
153+
154+
</project>

run/idp-sql/postcreate.sh

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#!/bin/bash
2+
# Copyright 2021 Google LLC
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
# Postcreate script for Cloud Run button
17+
18+
export SECRET_NAME="idp-sql-secrets"
19+
export SERVICE_ACCOUNT="idp-sql-identity"
20+
21+
# Update Cloud Run service to include Cloud SQL instance, Secret Manager secret,
22+
# and service account
23+
gcloud run services update ${K_SERVICE} \
24+
--platform managed \
25+
--region ${GOOGLE_CLOUD_REGION} \
26+
--service-account ${SERVICE_ACCOUNT}@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com \
27+
--add-cloudsql-instances ${GOOGLE_CLOUD_PROJECT}:${GOOGLE_CLOUD_REGION}:${CLOUD_SQL_INSTANCE_NAME} \
28+
--update-env-vars SECRET_NAME=${SECRET_NAME},VERSION=latest

run/idp-sql/postgres-secrets.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"spring.cloud.gcp.sql.instance-connection-name": "PROJECT_ID:REGION:INSTANCE",
3+
"spring.cloud.gcp.sql.database-name": "postgres",
4+
"spring.datasource.username": "postgres",
5+
"spring.datasource.password": "PASSWORD_SECRET"
6+
}

run/idp-sql/setup.sh

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#!/bin/bash
2+
# Copyright 2021 Google LLC
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
# Precreate script for Cloud Run button
17+
18+
export SECRET_NAME="idp-sql-secrets"
19+
export SERVICE_ACCOUNT="idp-sql-identity"
20+
21+
gcloud config set project $GOOGLE_CLOUD_PROJECT
22+
23+
# Add Identity Platform config
24+
sed -i "s/PROJECT_ID/$GOOGLE_CLOUD_PROJECT/" static/config.js
25+
sed -i "s/API_KEY/$API_KEY/" static/config.js
26+
27+
# Enable Cloud SQl and Secret Manager APIs
28+
gcloud services enable sqladmin.googleapis.com secretmanager.googleapis.com
29+
30+
# Create Cloud SQl instance
31+
gcloud sql instances describe ${CLOUD_SQL_INSTANCE_NAME}
32+
if [ $? -eq 1 ]; then
33+
echo "Create Cloud SQL instance with postgreSQL database (this might take a few minutes)..."
34+
gcloud sql instances create ${CLOUD_SQL_INSTANCE_NAME} \
35+
--database-version=POSTGRES_12 \
36+
--region=${GOOGLE_CLOUD_REGION} \
37+
--cpu=2 \
38+
--memory=7680MB \
39+
--root-password=${DB_PASSWORD}
40+
fi
41+
42+
# Add Cloud SQL config to secret file
43+
sed -i "s/PROJECT_ID/$GOOGLE_CLOUD_PROJECT/" postgres-secrets.json
44+
sed -i "s/REGION/$GOOGLE_CLOUD_REGION/" postgres-secrets.json
45+
sed -i "s/PASSWORD_SECRET/$DB_PASSWORD/" postgres-secrets.json
46+
sed -i "s/INSTANCE/$CLOUD_SQL_INSTANCE_NAME/" postgres-secrets.json
47+
48+
# Add secret file to Secret Manager
49+
gcloud secrets describe ${SECRET_NAME}
50+
if [ $? -eq 1 ]; then
51+
echo "Creating secret ..."
52+
gcloud secrets create ${SECRET_NAME} \
53+
--replication-policy="automatic"
54+
fi
55+
echo "Adding secret version ..."
56+
gcloud secrets versions add ${SECRET_NAME} --data-file=postgres-secrets.json
57+
58+
# Create service account
59+
gcloud iam service-accounts create ${SERVICE_ACCOUNT}
60+
# Allow service account to access secret
61+
gcloud secrets add-iam-policy-binding ${SECRET_NAME} \
62+
--member serviceAccount:${SERVICE_ACCOUNT}@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com \
63+
--role roles/secretmanager.secretAccessor
64+
# Allow service account to access Cloud SQL
65+
gcloud projects add-iam-policy-binding $GOOGLE_CLOUD_PROJECT \
66+
--member serviceAccount:${SERVICE_ACCOUNT}@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com \
67+
--role roles/cloudsql.client

0 commit comments

Comments
 (0)