Search code examples
javascriptgoogle-cloud-functionsgoogle-cloud-sql

Connect to Cloud SQL from Google Functions using Private IP


I have a Google Cloud SQL Instance and plan to access it from a Google Function using NodeJS. The code is as given in the documentation

// mysql
const mysql = require('mysql');
const connectionName = process.env.INSTANCE_CONNECTION_NAME || 'project:region:sql-instance';
const dbUser = process.env.SQL_USER || 'root';
const dbPassword = process.env.SQL_PASSWORD || 'password';
const dbName = process.env.SQL_NAME || 'database';

const mysqlConfig = {
  connectionLimit: 1,
  user: dbUser,
  password: dbPassword,
  database: dbName,
};
//if (process.env.NODE_ENV === 'production') {
  mysqlConfig.socketPath = `/cloudsql/${connectionName}`;
//}

// Connection pools reuse connections between invocations,
// and handle dropped or expired connections automatically.
let mysqlPool;

function searchDB() {
  if (!mysqlPool) {
    mysqlPool = mysql.createPool(mysqlConfig);
    console.log(mysqlPool);
  }
  return new Promise( function( resolve, reject ) {
    mysqlPool.query('SELECT * FROM table', (err, results) => {
      if (err) {
        console.error('error in retrieving data:', err);
        resolve(''); // sending blank response
      } else {
        console.log('success in getting data', JSON.stringify(results));
        resolve(JSON.stringify(results));
      }
    });
  });
}

I am able to access the database when I set it with public IP. However, when I set it to Private IP I get an ECON refused error.

Question is: what changes I need to do in the Google Functions code to access it using Private IP? Thanks


Solution

  • Private IP's are only accessible by other services on the same Virtual Private Cloud (VPC). Since your Function runs on a managed network, it is currently outside your VPC and doesn't have access to your Cloud SQL instance.

    Google Cloud Functions does provide a unix domain socket to interface with Cloud SQL instances, but it requires the instance to have a public IP. As long as mysqlConfig.socketPath = cloudsql/${connectionName}; uses the correct connection name (in the format project:region:instance), you should be able to connect. If you are using a cross product or cross regional setup, there are more instructions here.

    Update: Since originally posting this, a new product called the Serverless VPC connector has become available that can allow access to a VPC resource. You can follow the instructions to configure it, and then connect to the instance with it's private IP (instead of the /cloudsql/ socket mentioned above).