Can't connect to Postgres CloudSQL from Prisma in Cloudfunction - postgresql

I'm trying to connect to a public IP CloudSQL Postgres database from a cloud function with Prisma.
The database has SSL enforced. I assume I can use the Cloud Auth Proxy, and it works locally, but when I deploy it gives me an error.
I've tried both:
Option 1:
datasource db {
provider = "postgresql"
url = "postgresql://USER:PASSWORD#localhost:3307/DATABASE_NAME?host=CONNECTION_URL"
}
Got error:
Can't reach database server at `CONNECTION_URL`:`3307`
Option 2:
datasource db {
provider = "postgresql"
url = "postgresql://USER:PASSWORD#localhost/DATABASE_NAME?host=CONNECTION_URL"
}
Got error:
Can't reach database server at `IP_ADDRESS`:`5432`
Where IP_ADDRESS is the correct public IP address for the database that I can see in the console
CONNECTION_URL is /cloudsql/PROJ:REGION:INSTANCE

You application is trying to connect on "CONNECTION_URL" and "3307". To use public IP on Cloud Functions you should by connecting by unix socket: https://cloud.google.com/sql/docs/mysql/connect-functions#connect_to
Based on this issue, it looks like your URL should be something like:
postgresql://username#localhost/databasename?host=/cloudsql/CONNECTION_NAME
Where your instance connection name is PROJ:REGION:INSTANCE.

Figure out I had the vpc connector enabled to all traffic, so all traffic was trying to go through the private VPC instead of the public IP. Disabling it fixed it.

Related

Prisma DB Can't connect to AWS RDS

I have a nextjs project that's using prismaDB for the ORM. I'm able to connect just fine to my local postgres db but I'm getting this error when running npx prisma migrate.
Error: P1001: Can't reach database server at db-name.*.us-west-2.rds.amazonaws.com:5432.
schema.prisma:
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
//url = "postgresql://master_username:master_password#aws_host:5432/db_name"
}
The RDS db is currently public and I'm positive that I've copied over the RDS credentials correctly. There doesn't seem to be anything I should be including for the connection to work but I'm not getting any other info as to why I can't reach the db server.
Seems like you have to replace db-name.*.us-west-2.rds.amazonaws.com with the name of your actual database, unless you replaced it for the purpose of asking this question. Specifically the part where it says db-name.*.
Docs: https://www.prisma.io/docs/reference/api-reference/error-reference#common
P1001 indicates that it couldn't find the database given the connection string, NOT necessarily that the credentials you provided were wrong. Make sure you're specifying the correct database name/host and whatever else you need to make it work for AWS.
Somehow I was able to connect to RDS after deleting and creating a new DB for the third time. I confirmed connection through pgAdmin then tried it again my app deployed to vercel.

Connect to AWS RDS database via psycopg2

I am trying to connect to my RDS database from my computer with a python script using psycopg2.
python code:
import psycopg2
from db_credentials import *
import logging
def get_psql_conn():
conn = psycopg2.connect(dbname=DB_NAME, user=DB_USER, password=DB_PASS, host=DB_HOST)
logging.info("connected to DB!")
return conn
I get the following error:
psycopg2.OperationalError: could not connect to server: Operation timed out
Is the server running on host ********* and accepting
TCP/IP connections on port 5432?
My security groups assigned to the RDS database:
SG 1:
SG 2:
Now i tried to make a security group which allows my computer IP to access the DB.
SG 3:
I can connect to the DB from my ec2 instances, running the same python script as above. This seemingly has to do with the 2nd security group, as when i remove it, i can no longer connect from my ec2 instances either. It then throws the same error i get when trying to connect from my computer.
I have little understanding of RDS or security groups, i just followed internet tutorials, but seemingly couldnt make much sense out of it.
Any help is greatly appreciated! Thanks
When accessing an Amazon RDS database from the Internet, the database needs to be configured for Publicly Accessible = Yes.
This will assign a Public IP address to the database instance. The DNS Name of the instance will also resolve to the public IP address.
For good security on publicly-accessible databases, ensure that the Security Group only permits access from your personal IP address.

How can I connect to a Cloud PostgreSQL database from dart code?

I have a PostgreSQL database deployed in Google Cloud that I am trying to connect to from a Cloud Run instance. I have tried the following two packages, both of them eventually leading to the same exception:
https://pub.dev/packages/postgres
https://pub.dev/packages/database_adapter_postgre
The exception I am getting is:
SocketException: Failed host lookup: '/cloudsql/{INSTANCE_CONNECTION_NAME}' (OS Error: Name or service not known, errno = -2)
I get here both times when trying to establish the connection, so in the case of the first package:
connection = new PostgreSQLConnection(
'/cloudsql/{INSTANCE_CONNECTION_NAME}',
5432,
'postgres',
username: 'username',
password: 'password');
await connection.open(); // <-- exception thrown here
I have tried changing the host string to /cloudsql/INSTANCE_CONNECTION_NAME}/.s.PGSQL.5432, but that did not work. My first thought were permissions, the service account the Cloud Run instance is using (xxx-compute#developer.gserviceaccount.com) has the Cloud SQL Editor role (tried Client and Admin too).
Running the same database code locally from a dart console app, I can connect to my database via its public IP address as the host with both packages, so the database itself is up and running.
Can someone point me in the right direction with this exception/have an example code for any of the packages above to show how to connect it to a Cloud SQL instance from a Cloud Run?
Edit:
I tried setting up a proxy locally to test out if the connection is wrong like so:
.\cloud_sql_proxy.exe -instances={INSTANCE_CONNECTION_NAME}=tcp:5433 psql
Then changing the connection host value in the code to localhost, and the port to 5433.
To my surprise it works - so from locally I am seemingly able to connect to the DB using that connection string. It still doesn't work when I use it from a Cloud Run instance though. Any help is appreciated!
It seems dart doesn't support connection through unix socket, you need to configure a IP (public or private, as you need).
Alternatively you can use pg which support unix socket connection
Hope this helps.
Just for those who come across this question in the future:
as it stands right now, I had to resort to the suggestion posted by Daniele Ricci and use the public IP for the database. The one thing to point out here was that since Cloud Runs don't have a static IPv4 address to run from, the DB had to be set to allow connections from anywhere (had to add an authorized connection from 0.0.0.0/0), which is unsafe. Until the kind development team of dart figures out how to use UNIX sockets, this seems to be the only way of getting it to work.
Not having actually tested this myself, according to the source code of the postgres package, you have to specify that you want a Unix socket:
connection = PostgreSQLConnection(
...
isUnixSocket: true, // <-- here
);
The default is false.
The host you pass is must also be valid. The docs say:
[host] must be a hostname, e.g. "foobar.com" or IP address. Do not include scheme or port.
I was struggling with the same issue.
The solution is to create a connection as follows:
PostgreSQLConnection getProdConnection() {
final String connectionName = Platform.environment['CLOUD_SQL_CONNECTION_NAME']!;
final String databaseName = Platform.environment['DB_NAME']!;
final String user = Platform.environment['DB_USER']!;
final String password = Platform.environment['DB_PASS']!;
final String socketPath = '/cloudsql/$connectionName/.s.PGSQL.5432';
return PostgreSQLConnection(
socketPath,
5432,
databaseName,
username: user,
password: password,
isUnixSocket: true,
);
}
Then when you create a Cloud Run service, you need to define 'Enviroment variables' as follows.
You also need to select your sql instance in the 'connections' tab.
Then the last thing needed is to configure a Cloud Run service account.
Then the connection to instance should be successful and there should no longer be a need for a 0.0.0.0/0 connection.
However, if you try to run this connection locally on a Windows device during development the connection will not be allowed and you will be presented with this error message: 'Unix domain sockets are not available on this operating system.'
Therefore, I recommend that you open Google SQL networking to your public address and define a local environment using the 'Public IP address' of your SQL instance.
For more information on this topic, I can recommend these resources that have guided me to the right solution:
https://cloud.google.com/sql/docs/postgres/connect-instance-cloud-run#console_5
https://github.com/dart-lang/sdk/issues/47899

pgadmin4 connect to postgres in Google Cloud SQL

I am not able to connect through pgAdmin4 to Google Cloud SQL.
Following are the credentials I am providing and getting the error messege:
If you are configuring access for public IP connections, follow the next steps to connect with PgAdmin:
1) Create your PostgreSQL instance in Google Cloud Platform.
2) While creating the instance,
In Instance ID tab, write a name for your instance
In Default user password tab, write a password.
Choose the region.
Click on configuration options, go to Connectivity, enable Public IP, under Authorized networks, add network and their write the IP address of your PC. You can check the IP address in the link .
Click on create.
Then in PgAdmin:
1) In Host name/address put Public IP address of the instance.
To connect with Google Cloud SQL using pgadmin client, you can use cloud_sql_proxy
These steps need to follow:
Establish connection to Postgres.
cloud_sql_proxy -instances=<connection string>=tcp:5433
You will get connection string from GCP here
After executing cloud_sql_proxy, you will see something like this
Now create a new server connection using pgadmin client.
If you followed those steps properly it will connect and can use like local pgadmin.
Nibrass H has perfectly answered this question.
But I would like to add that if you have already created the Instance, then you can click on 'Edit Instance' and Add your IP in 'Connections'.
Adding some Images to help you.

Connecting to Google Cloud SQL with MySQL Workbench

I can't seem to connect to Cloud SQL with Workbench. I keep getting this error.
Failed to Connect to MySQL at CLOUD-SQL-IPv4:3306 with user root
Access denied for use 'root'#'WHITE-LISTED-IP-ADDRESS' (using password: YES)
I have white listed my IP.
I have set an IP for the SQL instance.
I have checked the username and Password several times.
Any idea why this is happening?
It seems you have to create a new user in the Google Cloud Console with the host name set to %(any host). You can't seem to connect using the root user.
Is it possible to connect with the #root user but after you finish the setup you have to restart the sql server.
What is important to set up an SSL certificate if you connect to you production database, but if you only try it out you can allow unsecured connection. Another important thing is to add your IP to the Authorised Networks in the Connection tab.