Hi,
I'm trying to connect BQ to a specific CloudSQL instance.
It works when adding the "roles/cloudsql.client" role to the BQ agent SA.
But I want to scope the permission down to a specific CloudSQL instance, and forbid access to other instances.
I tried to add the IAM condition resource.name == 'projects/zzzz-stg/instances/zzzz-staging' but BQ is throwing a:
Invalid table-valued function EXTERNAL_QUERY Failed to connect to MySQL database. Error: MysqlErrorCode(2013): Lost connection to MySQL server during query For more information, see https://cloud.google.com/bigquery/docs/cloud-sql-federated-queries#troubleshooting at [1:15]
I tried with the "startswith" function too.
Another funny issue: while parsing GCP audit logs I find multiple "cloudsql.instances.get" methodeName calls per query (all of them granted), but no "cloudsql.instances.connect" methodName call.
Is it possible to scope down BQ access to cloudSQL? Am I missing something?
Thank you 🙂
When you see the error "MysqlErrorCode(2013): Lost connection to MySQL server during query,"
it’s likely due to IAM permissions. You tried to restrict access with a condition like resource.name == 'projects/zzzz-stg/instances/zzzz-staging'
. However, IAM conditions can be complex:
cloudsql.instances.connect
permission. If not set up correctly, they can cause connection problems."cloudsql.instances.get"
calls, which check permissions and retrieve instance details. If "cloudsql.instances.connect"
isn’t showing up, the condition may not be evaluated correctly.To limit BigQuery’s access to a specific Cloud SQL instance, follow these steps:
Go to IAM & Admin in the Google Cloud Console.
Select the BigQuery Service Account (typically named something like bq-agent-XXXXXX@gcp-sa-bigquery.iam.gserviceaccount.com
).
Click “Add Another Role” and choose Cloud SQL Client
.
Add a Condition:
resource.name.startsWith('projects/zzzz-stg/instances/zzzz-staging')
resource.name == 'projects/zzzz-stg/instances/zzzz-staging'
Save and Apply the condition.
After setting up the IAM condition, test the connection from BigQuery to the Cloud SQL instance using the external query function. Ensure that the connection string and credentials are correct.
Alternative Approach: Use a Service Perimeter
For more robust access control, consider using a Service Perimeter:
Troubleshooting Tips
"cloudsql.instances.connect"
attempts in the Cloud SQL audit logs. Ensure logging is enabled.Additional Considerations
Example IAM Policy JSON
Here’s a sample IAM policy that restricts access to a specific Cloud SQL instance:
{
"bindings": [
{
"role": "roles/cloudsql.client",
"members": [
"serviceAccount:bq-agent-XXXXXX@gcp-sa-bigquery.iam.gserviceaccount.com"
],
"condition": {
"title": "Restrict to Specific Instance",
"description": "Allow access only to zzzz-staging instance.",
"expression": "resource.name == 'projects/zzzz-stg/instances/zzzz-staging'"
}
}
]
}
Thanks for the quick reply.
I have the exact same IAM condition and it is not working, and not logging any "cloudsql.instances.connect" entries in audit logs.
The only thing different from your example is that I don't have a Google provided SA named
serviceAccount:bq-agent-XXXXXX@gcp-sa-bigquery.iam.gserviceaccount.com
Instead I'm using the SA:
service-XXXXXXXX@gcp-sa-bigqueryconnection.iam.gserviceaccount.com
did you get solution for this issue ?
even I am facing the same issue.