I feel that I'm going around in circles here, so, please, bear with me. I want to deploy my Spring Boot application to App Engine but unlike the simple sample Google provides, mine, requires a database and that means credentials. I'm running Java 11 on Standard on Google App Engine.
I managed to make my app successfully connect by having this in the application.properties
:
spring.datasource.url=jdbc:postgresql://google/recruiters_wtf?cloudSqlInstance=recruiters-wtf:europe-west2:recruiters-wtf&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=the_user&password=monkey123
The problem is that I don't want to commit any credentials to the repository, so, this is not acceptable. I could use an environment variable, but then I'll have to define them in the app.yaml
file. I either keep a non-committed app.yaml
file that is needed to deploy, which is cumbersome, or I commit it and I'm back at square one, committing credentials to the repository.
Since apparently Google App Engine cannot have environment variables defined in any other way (unlike Heroku), does this mean it's impossible to deploy a Spring Boot app to App Engine and have it connect to the database without using some unsafe/cumbersome practices? I feel I'm missing something here.
The traditional way of deployment is making the Spring Boot Application @SpringBootApplication class extend the SpringBootServletInitializer class. Spring Boot Servlet Initializer class file allows you to configure the application when it is launched by using Servlet Container.
On premises Because App Engine and Compute Engine use the same networking infrastructure, you can use the VPN connection to establish a connection between the App Engine app and your on-premises database using the database server's internal IP address.
Deploy your application to App Engine using the gcloud app deploy command. The deployment command automatically builds a container image by using the Cloud Build service and then deploys that image to the App Engine flexible environment.
Based on my understanding of what you have described, you would like to essentially connect your Spring boot application running on Google App Engine to a database without exposing the sensitive information. If that is the case, I was able to find out that Cloud KMS offers users the ability for secret management. Specifically, applications which require small pieces of sensitive data at build or runtime are referred to as secrets. These secrets can be encrypted and decrypted with a symmetric key. In your case you can store the database credentials as secrets. You may find further details of the process for encrypting / decrypting a secret here.
They are currently three ways to manage secrets:
- Storing secrets in code, encrypted with a key from Cloud KMS. This solution is implementing secrets at the application layer.
- Storing secrets in a storage bucket in Cloud Storage, encrypted at rest. You can use Cloud Storage: Bucket to store your database credentials and can also grant that bucket a specific Service Account. This solution allows for separation of systems. In the case that the code repository is breached, your secrets would themselves may still be protected.
- Using third-party secret management system.
In terms of storing secrets themselves, I found the follow steps outlined here quite useful for this. This guide walks users through setting up and storing secrets within a Cloud Storage bucket. The secret is encrypted at the application layer with an encryption key from Cloud KMS. Given your use case, this would be a great option as your secret would be stored within a bucket instead of your app.yaml file. Also, the secret being stored in a bucket would grant you the ability to restrict access to it with service account roles.
Essentially, your app will need to perform an API call to Google Cloud Storage in order to download the KMS encrypted file that contains the secret. It would then use the KMS generated key to decrypt the file so that it would be able to read out the password and use it to make a manual connection to the database. Adding these extra steps would be implementing more security layers, which is the entire idea noted in “'Note: Saving credentials in environment variables is convenient, but not secure - consider a more secure solution such as Cloud KMS to help keep secrets safe.'” in the Google example repository for Cloud SQL.
I hope this helps!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With