Search code examples
google-app-engine.net-coregoogle-cloud-platformgoogle-cloud-sqlapp-engine-flexible

Google App Engine .Net Core 2.0 app can't access Google Cloud SQL database


I have a dotnet core 2.0 application running in Google App Engine Flexible Environment. Within the same Google project I have a Cloud SQL - MySQL database. On the Cloud SQL Instance details page, under the Authorizations tab, it states

Apps in this project: All authorized.

However, I cannot access the database from my application unless I add the 0.0.0.0/0 route to the Authorized networks section.

What can I do to give my application db access without opening my database to the world?


Update 2018-05-21 from Jeffery Rennie (accepted answer)

App Engine now supports connecting to a Cloud SQL instance using a port number instead of a unix domain socket. So now, you can add something like this to your app.yaml:

beta_settings:
    cloud_sql_instances: "your-project-id:us-central1:instance-name=tcp:5432"

And specify Host=cloudsql in your connection string in your appsettings.json:

"ConnectionString": "Uid=aspnetuser;Pwd=;Host=cloudsql;Database=visitors"

In the sample above, the port is 5432, which is the default port for a PostgreSQL database. For a MySQL database, use port 3306.

A full example with instructions for deploying to App Engine can be found here:

https://github.com/GoogleCloudPlatform/dotnet-docs-samples/tree/master/appengine/flexible/CloudSql


Solution

  • The ideal solution is to use a unix domain socket to connect from your app engine instance to Cloud SQL. That's how other programming languages like Python and PHP do it. Unfortunately, the MySQL connector does not work with domain sockets. I see no reason why it can't, but it doesn't. I hope they fix that issue soon.

    As described in https://cloud.google.com/appengine/kb/#static-ip,

    Note that using static IP address filtering is not considered a safe and effective means of protection. For example, an attacker could set up a malicious App Engine app which could share the same IP address range as your application. Instead, we suggest that you take a defense in depth approach using OAuth and Certs.

    If certificates are not sufficient to protect your application, then the only remaining option I see today is to build a custom runtime that runs the Cloud SQL Proxy. The proxy can forward a local ip port number to a unix domain socket. If you have built a docker image or two, then it's not too bad.

    I will update this answer as the situation improves.


    Update 2018-05-21

    App Engine now supports connecting to a Cloud SQL instance using a port number instead of a unix domain socket. So now, you can add something like this to your app.yaml:

    beta_settings:
        cloud_sql_instances: "your-project-id:us-central1:instance-name=tcp:5432"
    

    And specify Host=cloudsql in your connection string in your appsettings.json:

    "ConnectionString": "Uid=aspnetuser;Pwd=;Host=cloudsql;Database=visitors"
    

    In the sample above, the port is 5432, which is the default port for a PostgreSQL database. For a MySQL database, use port 3306.

    A full example with instructions for deploying to App Engine can be found here:

    https://github.com/GoogleCloudPlatform/dotnet-docs-samples/tree/master/appengine/flexible/CloudSql