This tutorial is an attempt to run Ganesh Radhakrishnan (@ganrad) Spring Purchase-order application that was designed to run off Azure, in a Google Cloud Environment.
As @ganrad has done, we will equally attempt to leverage GCP features to simplify this deployment.
Our goal here is to:
- Define a Build Pipeline in Google Cloud Build. Execute the build pipeline to create Springboot Java Microservice Application jar (po-service 1.0) and push it to App Engine. This task focuses on the Continuous Integration aspect of the DevOps process.
- Leverage on Cloud Sql as a replacement of the mysql service container.
- Leverage on Secret Manager to manage application secrets.
This Springboot application demonstrates how to build and deploy a Purchase Order microservice (po-service
) as an application on GCP App Engine Service on GCP. The deployed microservice supports all CRUD operations on purchase orders.
Prerequisites:
- Create a project in the Google Cloud Platform Console.
- Enable billing for your project.
- Install the Google Cloud SDK.
- Install Maven
- Create a GitHub account
We have forked this project from https://github.com/ganrad/k8s-springboot-data-rest.git
Adjustments
-
Pom.xml
We need to update thepom.xml
file to addspring-cloud-gcp-starter
,spring-cloud-gcp-starter-sql-mysql
andspring-cloud-gcp-starter-secretmanager
k8s-springboot-data-rest/pom.xml
Lines 65 to 76 in 4e5869b
We will also add the App engine plugin.
k8s-springboot-data-rest/pom.xml
Lines 89 to 97 in 4e5869b
-
application.properties
We update to include Cloud Sql configs -
src/main/java/ocp/s2i/springboot/rest/config/PropertiesConfiguration.java
We'll comment out the@Configuration
properties
Additional Files
src/main/appengine/app.yaml
This is a deployment config file for App engine.env: flex runtime: java runtime_config: jdk: openjdk8 resources: cpu: 1 memory_gb: 1 disk_size_gb: 10 volumes: - name: ramdisk1 volume_type: tmpfs size_gb: 0.5 automatic_scaling: min_num_instances: 1 max_num_instances: 3 handlers: - url: /.* script: this field is required, but ignored
cloudbuild.yaml
This is a cloud build config file for executing the build pipeline.steps: - name: maven:3-jdk-8 entrypoint: mvn args: ["test"] - name: maven:3-jdk-8 entrypoint: mvn args: ["package", "-Dmaven.test.skip=true","appengine:deploy"] # - name: gcr.io/cloud-builders/docker # args: ["build", "-t", "gcr.io/$PROJECT_ID/k8s-springboot-data-rest", "--build-arg=JAR_FILE=target/po-rest-service-1.0.jar", "."] #images: ["gcr.io/$PROJECT_ID/k8s-springboot-data-rest"]
###How To
-
Initialize the Cloud SDK, create an App Engine application, and authorize the Cloud SDK to use GCP APIs in your local environment:
gcloud init gcloud app create gcloud auth application-default login
-
Enable the Cloud SQL API.
-
Create a Cloud SQL (MySQL) instance and set the root user password following these instructions.
gcloud sql instances create test-instance --tier=db-n1-standard-1 --region=us-central1
-
Set the password for the
root@%
MySQL usergcloud sql users set-password root --host=% --instance test-instance --password [PASSWORD]
Make sure you replace
[PASSWORD]
with your own password -
Setup
orders
database.gcloud sql databases create orders --instance=test-instance
-
Get the
connectionName
of the instance in the formatproject-id:zone-id:instance-id
:gcloud sql instances describe test-instance | grep connectionName
Now you can test out your Cloud Sql Database and see if you are able to use this database.
-
Update your
application-mysql.properties
file by replacing the instance-connection-name, database-name, username and password.Note: The values you will find when you first open this file have been designed for a secret manager connection which I will discuss about shortly
-
Enable the Secret Manager API
You will also need to grant the application access
- Go to IAM & Admin page
- Click the
Project selector
drop-down list at the top of the page. - On the
Select from
dialog that appears, select the organization for which you want to enable Secret Manager. - On the
IAM
page, next to theapp engine service account
, clickEdit
. - On the
Edit permissions
panel that appears, add the necessary roles. - Click
Add another role
. SelectSecret Manager Admin
. - Click
Save
-
Create new secrets for our datasource configuration file.
echo -n “gcp-migration-project-278408:us-central1:test-instance” | gcloud secrets create spring_cloud_gcp_sql_instance_connection_name — replication-policy=”automatic” — data-file=- echo -n “orders” | gcloud secrets create spring_cloud_gcp_sql_database_name — replication-policy=”automatic” — data-file=- echo -n “root” | gcloud secrets create spring_datasource_username — replication-policy=”automatic” — data-file=- echo -n “test123” | gcloud secrets create spring_datasource_password — replication-policy=”automatic” — data-file=-
Note: Remember to use your own credentials here for
spring_cloud_gcp_sql_instance_connection_name
andspring_datasource_password
Confirm your secrets have been created by running
gcloud secrets list
which should return a list of secrets. -
Replace the values in the
application-mysql.properties
file with the secrets url. For this step, you will need the fully-qualified name of the secret as defined on GCP.gcloud secrets describe spring_cloud_gcp_sql_instance_connection_name | grep name gcloud secrets describe spring_cloud_gcp_sql_database_name | grep name gcloud secrets describe spring_datasource_username | grep name gcloud secrets describe spring_datasource_password | grep name
You will now use this names to create a secret manager url. The url will use the format
${sm://FULLY-QUALIFIED-NAME}
whereFULLY-QUALIFIED-NAME
is as retrieved above. -
Update
src/main/resources/application-mysql.properties:
#CLOUD-SQL-CONFIGURATIONS spring.cloud.appId=gcp-migration-project-278408 spring.cloud.gcp.sql.instance-connection-name=${sm://projects/.../secrets/spring_cloud_gcp_sql_instance_connection_name} spring.cloud.gcp.sql.database-name=${sm://projects/.../secrets/spring_cloud_gcp_sql_database_name} ##SQL DB USERNAME/PASSWORD spring.datasource.username=${sm://projects/.../secrets/spring_datasource_username} spring.datasource.password=${sm://projects/.../secrets/spring_datasource_password}
-
Create a GitHub account if you don’t have one already.
-
Enable the Cloud Build API in the target Cloud project.
-
Install the Google Cloud Build App on Github. You can follow this instructions here.
I can recommend forking this repository, to make your integration easier, or you can create your own fresh repo and push your source files to initialize your repo. Either way, make sure you select your new repo as the repository you are connecting to, otherwise this build will not work.
-
In the Google Cloud Console, open the Cloud Build Build triggers page.
Make sure to delete all triggers created, that may be related to this project before moving to the next step. We are doing this to make sure that no other builds are running other than the single build we have configured.
-
Select your Google Cloud project and click
Open
. -
Click
Create Trigger
. -
Fill out the options
- Required. In the
Name
field, enter a name - Optional. In the
Description
field, enter a brief description of how the trigger will work - Under
Event
, selectPush to a branch
- In the
Source
drop-down list, selectkioie/k8s-springboot-data-rest
repository
Note: If this repository does not appear, click the
Connect New Repository
button and connect your repo on GitHub, then return to step5.- Under
Branch
, enter^master$
- Under
Build Configuration
selectCloud Build configuration file (YAML or JSON)
For theCloud Build configuration file location
entercloudbuild.yaml
Note: Do not add an extra/
- Click
Create
- Required. In the
Under your active triggers, you should now be able to see your newly created trigger.
-
The
pom.xml
file already contains configuration forprojectId
andversion
. Change this to reflect the current project ID.<deploy.projectId>gcp-migration-project-278408</deploy.projectId>
-
Enable App Engine Admin API
-
Enable App Engine Flexible API
-
Give more permission to the cloud build service account
Grant cloudbuild service account, admin access to Secret Manager, App Engine and Cloud Sql.
-
Go to IAM & Admin page
-
Click the
Project selector
drop-down list at the top of the page and select the current project organization. -
On the
IAM
page, next to thecloud build service account
, (not to be confused with thecloud build service agent
)clickEdit
(or the pencil button). -
On the
Edit permissions panel
that appears, add the necessary roles. -
Click
Add another role
and add these three roles:
— App Engine Admin
— Cloud SQL Admin
— Secret Manager Admin -
Click
Save
.
The final permission list should look something like this
The final step that triggers a cloud build will require pushing your updated code-base to GitHub.
-
-
Add your remote GitHub fork repo as your upstream repo
git remote add upstream [https://github.com/<YOUR_ACCOUNT_NAME>/k8s-springboot-data-rest](https://github.com/YOUR_ACCOUNT_NAME/k8s-springboot-data-rest) git remote -vv
-
Commit your changes
git add . git commit
-
Push upstream
git push upstream master
-
This should automatically trigger your build on GCP cloud build. You can check the status of your build using the below command
gcloud builds list
A successful build!
-
You can fetch the url of the app with the command
gcloud app browse
-
Now test out your endpoints
curl [https://gcp-migration-project-278408.uc.r.appspot.com/orders](https://gcp-migration-project-278408.uc.r.appspot.com/orders) curl [https://gcp-migration-project-278408.uc.r.appspot.com/orders/1](https://gcp-migration-project-278408.uc.r.appspot.com/orders/1) curl [https://gcp-migration-project-278408.uc.r.appspot.com/orders/2](https://gcp-migration-project-278408.uc.r.appspot.com/orders/2)