Unable to connect to Cloud SQL (through Auth Proxy) from Cloud Run - node.js

I am trying to access my Cloud SQL database (PostgreSQL) through a Cloud Run application (Node.js) that I am developing locally (using Cloud Code as part of the VS Code extension).
I am able to access the database through the Cloud SQL Auth Proxy in my terminal (using psql "host=127.0.0.1 port=5432 sslmode=disable dbname=*** user=***") but have never been able to successfully connect from my local Cloud Run.
The Cloud SQL database is set up as a connection in my Cloud Run project.
I have tried (and failed) with two ways to try and connect:
Using the instance connection name: When I do something like this:
const pg = require('knex')({
client: 'pg',
connection: {
user: '...',
password: '...',
database: '...',
host: '/cloudsql/...',
},
debug: true,
});
I get the following error:
connect ENOENT /cloudsql/.../.s.PGSQL.5432"
Using local host and port: When I do something like this:
const pg = require('knex')({
client: 'pg',
connection: {
user: '...',
password: '...',
database: '...',
host: '127.0.0.1',
port: 5432,
},
debug: true,
});
I get the following error:
Error: connect ECONNREFUSED 127.0.0.1:5432

Cloud Code local Cloud Run implementation doesn't support Cloud SQL at the moment. One way to add Cloud SQL Proxy running next to your Cloud Run application is to add it as a side car to the container that Cloud Code deploys during Cloud Run local development session. Try the following:
Start Cloud Code Cloud Run: Run Locally session
Wait for the application to build and start, and endpoints to be available
At this moment, your application is running in minikube as a container (in a separate namespace called cloud-run-dev-internal), and deployment name matches your Cloud Run service name.
Create a YAML patch file which will start Cloud SQL Proxy next to your application so it will be available locally (via localhost):
spec:
template:
spec:
containers:
- name: cloud-sql-proxy
image: gcr.io/cloudsql-docker/gce-proxy
command:
- "/cloud_sql_proxy"
# By default, the proxy will write all logs to stderr. In some
# environments, anything printed to stderr is consider an error. To
# disable this behavior and write all logs to stdout (except errors
# which will still go to stderr), use:
- "-log_debug_stdout"
# Replace DB_PORT with the port the proxy should listen on
# Defaults: MySQL: 3306, Postgres: 5432, SQLServer: 1433
- "-instances=my-project:my-region:my-instance=tcp:3306"
Save this as cloudsql-proxy-patch.yaml. Apply this patch file the following way:
kubectl patch deployment {your_cloud_run_service_name} --patch-file cloudsql-proxy-patch.yaml --context cloud-run-dev-internal
After some time Cloud SQL proxy should be running. To diagnose, you can use Kubernetes Explorer and look inside cloud-run-dev-internal namespace and see if your pod has both your application and Cloud SQL Proxy side car container.
The rest depends on how you configure your Cloud SQL proxy locally. Please see https://cloud.google.com/sql/docs/mysql/connect-kubernetes-engine#run_the_as_a_sidecar for more details on how to setup proxy as a sidecar.

Related

Kubernetes + consul: kv.get: connect ETIMEDOUT

I have deployed consul using hashicorp-consul-helm-chart
now, I want to connect to the consul from my Node.js project.
Therefore, I created an object like this : (using 'consul' npm package)
import consul from 'consul';
var consulObj = new consul({
host: 'xxx.xxx.xxx.xxx',
promisify: true
});
var watch = consulObj.watch({
method: consulObj.kv.get,
options: { key: 'config' },
backoffFactor: 1000,
});
I have got the host value from kubectl get endpoints
used the value opposite to consul-server
still, i get consul: kv.get: connect ETIMEDOUT when I run the code.
what could be the reason?
Thanks in advance!
You should be accessing the Consul client which is running on the node where your app is located instead of directly accessing the server.
Details can be found in the accepted answer for Hashicorp Consul, Agent/Client access.

Hide password by ignoring file in .gitignore, but unable to deploy to Heroku?

I was trying to deploy my Node JS application to Heroku. Heroku was connected to my Github account and deployed through Github. In my Node JS application, I created a SQL pool file awsPool.js using the following code:
const mysql = require('mysql');
const awsPool = mysql.createPool({
connectionLimit: 10,
host: "myDb.abcdefg.eu-west-2.rds.amazonaws.com",
user: "myUsername",
password: "myPassword",
port: 3306,
database: 'myDb',
debug: false
});
module.exports = awsPool;
And imported it in my Express application. The pool contains credentials such as my username and password, so I set them as ignored in .gitignore. However, when trying to deploy the application to Heroku, Heroku gave me this error:
Error: Cannot find module './awsPool'
I understand this is likely due to awsPool.js being not tracked in my Github, but how can I properly hide my credentials and deploy to Heroku?
You can use ponto .env files that will define your credentials. So when you are going to deploy your application on Heroku you will only need to define your environment variables

error: role "root" does not exist when accessing a Postgresql Server hosted on AWS RDS from local Nodejs

I created an Elastic Beanstalk with a Nodejs app on it. Then from the environments' configurations I created a postgres RDS.
I can connect to the postgres server from a console:
psql --host=aa1682linxrnijl.c09xht5iw0ld.us-east-1.rds.amazonaws.com --port=5432 --username=monolithDB --password --dbname=postgres
And I also have an existing table in it.
result of \dt
But when I try to connect from my Nodejs localhost, using node-postgres:
const { Client } = require("pg");
const client = new Client({
host: 'aa1682linxrnijl.c09xht5iw0ld.us-east-1.rds.amazonaws.com',
password: 'XXX',
port: 5432,
database: 'postgres',
user: 'monolithDB'
});
client.connect()
I get an error:
error: role "root" does not exist
It seems to me that the node-postgres doesn't recognize the 'monolithDB' as a user. How can I properly connect to the Postgres server?

Node.JS on Google App Enging with Cloud SQLError: connect ENOENT /cloudsql/

I've successfully deployed my app to Google App Engine. My database is up and running on Cloud SQL. I'm able to connect to the database no problems from my local machine by whitelisitng my dev machine's IP on the authorised networks in cloud SQL. However when I deploy to Production, I'm getting:
Error: connect ENOENT /cloudsql/<my project id>:asia-south1:<my database instance name>
My app.yaml file looks like this:
runtime: nodejs
env: flex
manual_scaling:
instances: 1
resources:
cpu: 1
memory_gb: 0.5
disk_size_gb: 10
env_variables:
ST_ENV: 'Production' //Used to set the app listening on the below port
ST_PORT: '8080'
SQL_USER: '<username>'
SQL_PASSWORD: '<password>'
SQL_DATABASE: '<databasename>'
INSTANCE_CONNECTION_NAME: '/cloudsql/<my project id>:asia-south1:<my database instance name>'
beta_settings:
cloud_sql_instances: '<my project id>:asia-south1:<my database instance name>'
My config file looks like this:
database: {
connectionLimit: 10,
// host : process.env.INSTANCE_CONNECTION_NAME,
socketPath: process.env.INSTANCE_CONNECTION_NAME,
user : process.env.SQL_USER,
password : process.env.SQL_PASSWORD,
database : process.env.SQL_DATABASE,
multipleStatements : true
}
And I'm creating a connection pool (I've simplified the code for this example):
var db = config.production.database;
var pool = mysql.createPool(db);
I've been able to successfully connect from my local machine through the local cloud_sql_proxy.
I've tried using the IP of the Cloud SQL instance as the host, but that gave me the below error:
Error: connect ECONNREFUSED 127.0.0.1:3306'
I also tried specifying the host as 0.0.0.0 and port 3306 and got:
Error: connect ECONNREFUSED 0.0.0.0:3306'
Edit: both the Cloud SQL and the Cloud SQL Admin APIs are enabled:
It's like when pushing to production the app engine is trying to use a non existent proxy. Can anyone help?
Take a look at the specific instructions for connecting from the Node.js runtime on App Engine Flexible. You can configure the connection using the instance connection name and some other environmental variables. It's not necessary to provide a host name or install the SQL proxy on your instance. Attempting to connect to the public IP of the Cloud SQL instance won't work from App Engine.

Right way to connect to Google Cloud SQL from Node.JS

I followed the example on how to set up Node.JS to work with Cloud SQL, and generally got it to work, but with some workarounds on how to connect to the SQL server. I am unable to connect in the proper way passing the INSTANCE_CONNECTION_NAME to the socketPath option of the options variable for the createConnection() method. Instead, as a temporary workaround, I currently specify the server's IP address and put my VM IP address into the server's firewall settings to let it through.
This all works, but I'm now trying put it together properly before publishing to AppEngine.
How can I get it to work?
The following code works fine:
function getConnection ()
{
const options =
{
host: "111.11.11.11", //IP address of my Cloud SQL Server
user: 'root',
password: 'somePassword',
database: 'DatabaseName'
};
return mysql.createConnection(options);
}
But the following code, which I am combining from the Tutorial and from the Github page, which is referred to in the Tutorial, is giving errors:
function getConnection ()
{
const options =
{
user: 'root',
password: 'somePassword',
database: 'DatabaseName',
socketPath: '/cloudsql/project-name-123456:europe-west1:sql-instance-name'
};
return mysql.createConnection(options);
}
Here's the error that I'm getting:
{ [Error: connect ENOENT /cloudsql/project-name-123456:europe-west1:sql-instance-name]
code: 'ENOENT',
errno: 'ENOENT',
syscall: 'connect',
address: 'cloudsql/project-name-123456:europe-west1:sql-instance-name',
fatal: true }
What am I doing wrong? I am concerned that if I publish the app to AppEngine with the IP address, I won't be able to allow the incoming traffic into the SQL server?
I met similar error while testing 'coud sql'.
error message : Error: connect ENOENT /cloudsql/xxx-proj:us-central1:xxx-instance
solution :
+----------------------------------------------------------+ wget https://dl.google.com/cloudsql/cloud_sql_proxy.linux.amd64 -O
cloud_sql_proxy chmod +x cloud_sql_proxy sudo mkdir /cloudsql;
sudo chmod 777 /cloudsql ./cloud_sql_proxy -dir=/cloudsql &
=> now node js server can connect to mysql
refer to guide : https://cloud.google.com/appengine/docs/flexible/nodejs/using-cloud-sql
Are you deploying your AppEngine app to the same region as the SQL database? (europe-west1)
The documentation at https://cloud.google.com/sql/docs/mysql/connect-app-engine states "Your application must be in the same region as your Cloud SQL instance."

Resources