Search code examples
google-app-enginegcloudgoogle-cloud-sql

GCP App Engine instance cannot connect to GCP Cloud SQL instance


App engine config:

instance_class: F1
automatic_scaling:
  min_idle_instances: automatic
  max_idle_instances: automatic
  min_pending_latency: automatic
  max_pending_latency: automatic

NodeJs application running: (i) Apollo server, (ii) Express, (iii) Knex

Steps:

  1. Get the Public IP Address of Cloud SQL Instance
  2. Get the Connection Name of Cloud SQL Instance
  3. Set the Connection Name of the Cloud SQL Instance in app.yaml
  4. Set the Public IP Address of the Cloud SQL Instance in index.ts of client

index.ts

// @note Using Knex
const db = await initDatabase({
    client: 'pg',
    connection: {
      host: args['blockchain-db-host'],
      port: args['blockchain-db-port'],
      database: args['blockchain-db-database'],
      user: args['blockchain-db-user'],
      password: args['blockchain-db-pass'],
    },
  })

N.B. Also get Username, Password, and set them in index.ts, also Port in index.ts used as 5432 as Cloud SQL Instance is a Postgres database.

app.yaml

beta_settings:
  cloud_sql_instances: <project>:<region>:<sql-instance>=tcp:5432

N.B. The beta_settings once deployed via gcloud app deploy is not reflected in config file on Google App Engine. Also, I am not familiar with the Unix socket methodology, I am assuming that 5432 should also be used as the PORT when setting up the App engine's cloud proxy connection.


Solution

  • Even though the Application is a flex environment, App Engine is allowed to connect to Cloud SQL via: (i) TCP, and (ii) Unix Socket

    N.B. In my case, I would advise to use the Unix Socket in conjunction with Connection Instance, otherwise, use of IP Addresses typically require whitelisting and other configuration.

    If you are using the Connection Instance Name provided by the Cloud SQL Instance, you should be using the Unix Socket methodology to establish the connection.

    In this case, app.yaml must have:

    beta_settings:
      cloud_sql_instances: <project>:<region>:<sql-instance>=tcp:5432
    

    And index.ts must resemble:

    const db = await initDatabase({
        client: 'pg',
        connection: {
          host: `/cloudsql/${args['blockchain-sql-connection-name']}`,
          port: args['blockchain-db-port'],
          database: args['blockchain-db-database'],
          user: args['blockchain-db-user'],
          password: args['blockchain-db-pass'],
        },
      })