0

There are several good answers available for both of these scenarios - but not combined.

1. I need to make a call to an external API via whitelisted static IP.
See: Associating Cloud Function egress with a static IP address
a) call the external API from the Cloud Function
b) route all egress from this Cloud Function through a VPC Connector on vpcnetwork-1 (IP address range = 10.8.10.0/28)
c) use a Cloud NAT that routes all traffic on vpcnetwork-1 through [STATIC IP] (whitelisted by external API)

2. Next, I need to take that API data and send it to a Cloud SQL instance (MySQL in this case).
See: Connecting to Cloud SQL from Cloud Functions
a) create a UNIX socketpath connection to [Cloud SQL Instance]

When I run with the VPC Connector (as shown above), I get:
1) SUCCESS! I've received the API data using my whitelisted IP address
2) CONNECTION REFUSED by [Cloud SQL Instance] - because I'm using a static external IP? Does socketpath use external, or connect within my Google Cloud Project?

If I remove the VPC Connector from my Cloud Function, then I get:
1) CONNECTION REFUSED - this IP is not whitelisted (because I'm no longer using the static IP)
2) SUCCESS! I'm now able to connect to [Cloud SQL Instance] (using UNIX socketpath, userid, password)

How can I get both of these to work from the same Cloud Function?

I see that I can "Route only requests to private IPs through the VPC connector" but I really want the opposite of that. I want to only route external requests to the VPC connector, to use my static IP, and then keep my private routing for connections within my GCP.

ADDED: I am using Javascript mysql to connect to Cloud SQL.

var pool = mysql.createPool({ socketPath: '/cloudsql/[instance_connection_name]',
                              user: uid,
                              password: pwd,
                              database: 'mysql_db' });
var result = pool.query(sql, {}, (err,result)=> {});

This works ok without using a VPC Connector. When I use a VPC Connector with a static external IP address, this connection is refused. Is it because the VPC Connector and Cloud SQL instance are not on the same VPC? I don't think Cloud SQL is linked to a VPC, is it?

Womprat
  • 133
  • 11
  • Can you post the code of connecting from cloud function to clodsql. I wrote an answer how this should be done in python [CONNECTING FROM GOOGLE CLOUD FUNCTIONS TO CLOUD SQL USING TCP AND UNIX DOMAIN SOCKETS 2020](https://stackoverflow.com/questions/43023107/how-to-connect-google-cloud-sql-from-cloud-functions) – marian.vladoi Mar 20 '20 at 08:44
  • You should be able to connect from your cloud function to cloud sql , using vpc connector and internal ip address of your cloud SQL instance (tcp). I have this is my post. – marian.vladoi Mar 20 '20 at 08:55
  • @marian.vladoi I am connecting using Javascript mysql `var pool = mysql.createPool({ socketPath: '/cloudsql/[instance_connection_name]', user: uid, password: pwd, database: 'mysql_db' }); var result = pool.query(sql, {}, (err,result)=> {});` How can I check if this is using a TCP connection? It works ok when I am not using the VPC connector. When I connect this function through the VPC connector, this connection gives "CONNECTION REFUSED". – Womprat Mar 20 '20 at 16:47
  • assuming you did step 9 on my previous answer, creating a service account and assign the right permission to your cloud function, you have to create a cloud sql instance only with internall ip and connect to the internal ip address of the instance, use `host:internall_ip_cloudsql` instead of `socketPath`, pay attention on my previous answer and check how i create the database, how I create the service accout, how I create the vpc connector and how I deploy the cloud function, I was able to connect using python – marian.vladoi Mar 20 '20 at 18:13
  • your connection string should look like this : `var pool = mysql.createPool({ host : '10.36.0.3(internal ip of cloud sql instance)', user : 'root', password : 'root', database : 'guess', port: 3306 }); ` – marian.vladoi Mar 20 '20 at 18:21
  • @marian.vladoi I got it to work - thanks. First, I got it working with the Public IP, then I went through your instructions and was able to get Private IP working - it's a little trickier. The Cloud Functions control panel has an option to "Route only requests to private IPs through the VPC connector". For this use, I needed the opposite of that, which doesn't exist. But your walk-through got me to the right place. – Womprat Mar 21 '20 at 03:54

1 Answers1

0

The Cloud SQL Instance Overview dashboard lists both [Public IP Address] and [Instance Connection Name]

For a standard Cloud Functions connection, I use:

socketpath:[Instance Connection Name]
user: uid
password: pwd
database: 'mysql_db'

When using a VPC Connector, I use

host:[Private (or Public) IP Address]
user: uid
password: pwd
database: 'mysql_db'

Summary:

[Cloud Function] -> socketpath:[Instance Connection Name] => **SUCCESS**
[Cloud Function] -> host:[Public IP Address] => **FAIL** (Timeout - IP Not Allowed)

Private VPC Connections:
[Cloud Function] -> [VPC Connector] -> socketpath:[Instance Connection Name] => **FAIL** (Connection Refused)
[Cloud Function] -> [VPC Connector] -> host:[Private IP Address] => **SUCCESS** (Set up Private IP in GCP->SQL->Connections)

Public VPC Connection:
[Cloud Function] -> [VPC Connector] -> host:[Public IP Address] => **SUCCESS** (Only after allowing/whitelisting IP of the VPC Connector routed through Cloud NAT)

Google Cloud CLI instructions for Private IP setup:
CONNECTING FROM GOOGLE CLOUD FUNCTIONS TO CLOUD SQL USING TCP AND UNIX DOMAIN SOCKETS 2020

Womprat
  • 133
  • 11
  • can you please describe this line:[Cloud Function] -> [VPC Connector] -> host:[Public IP Address] => **SUCCESS** (Only after allowing IP of the routed VPC Connector), how do you allow the internal ip of the Vpc connector. – marian.vladoi Mar 21 '20 at 19:41
  • @marian.vladoi I edited to clarify that is a Public connection. The reason I'm using the VPC Connector for this function is so I can route traffic through a Cloud NAT to a Static IP and make Public external API calls. I was using that method before I used your example to create a Private connection - which should be more secure. – Womprat Mar 21 '20 at 23:33