CI/CD -Connect to GCP MySQL using Private IP from GCP Cloud Run / App Engine - Part 2

INTRODUCTION

In Part 1, we created a simple Spring Boot application and deployed it in Cloud Run and App Engine using Cloud Build. We also used secrets that were created in Secret Manager in the pipeline. In this article, we will create a MySQL database and will connect it with Cloud Run and App Engine. Database user, passwords, and the URL will be stored in the Secret Manager and will be passed during the build time.

STEPS

Create a VPC custom network

image.png

Create a Serverless VPC access connector

It is needed to access Google Cloud services on the GCP private network.

image.png

Create a MySQL Database with Private IP enabled and Public IP disabled

image.png

image.png

Update secrets jdbc.user, jdbc.password, jdbc.url and appprop in Secret Manager

It should match with the database you have created

Add CheckConnection.java in src folder

package com.example.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;

@RestController
public class CheckConnection {

    @Autowired
    Environment environment;

    @GetMapping("/checkConnection")
    public String checkConnection()   {
        String str =" ";
        try{
            Connection conn = getConnection();
            conn.close();
            str = "Connection Success!!";
        } catch (Exception e){
           str =  e.getMessage() +  " Connection failed!! " + environment.getProperty("jdbc.user") + " " + environment.getProperty("jdbc.password") +  " " + environment.getProperty("jdbc.url");
        }
        return str;

    }

    private Connection getConnection() throws SQLException {

        Connection conn = null;
        Properties connectionProps = new Properties();
        connectionProps.put("user", environment.getProperty("jdbc.user"));
        connectionProps.put("password", environment.getProperty("jdbc.password"));

        conn = DriverManager.getConnection(
                environment.getProperty("jdbc.url"),
                connectionProps);
        return  conn;
    }
}

CheckConnection.java class is created just to test the connection.

Update Cloud Run connections setting

image.png

Run the CloudBuild trigger we created for Cloud Run

Test the Cloud Run /checkConnection URL

For App Engine we need to add a VPC connector in the app.yaml

runtime: java17
entrypoint: java -jar app.jar
vpc_access_connector:
  name: projects/propane-cooler-354222/locations/us-central1/connectors/my-vpc-serverlessconnecto

Add Serverless VPC Access User and Computer Viewer role to cloudbuild service account.

image.png

Run CloudBuild trigger we created for App Engine

Test App Engine /checkConnection URL

CONCLUSION

We can use a proxy also to connect to MySQL but it will expose MySQL's public IP access. Serverless VPC adds an additional layer and increases the costs of the project. Service accounts roles should be looked at it before using this example in a production environment. Additionally, we can give Secret Accessor roles on the keys also instead of granting the full-service access to service accounts. I have posted a detailed youtube video of this article too. Also, the full source code is available on GitHub.