This post is an overview of another post and also my experience performing this migration.

https://medium.com/google-cloud/seamless-cloud-sql-migration-how-to-move-your-data-between-google-cloud-projects-with-ease-ee1592fd49c6

This process was performed around March/April of 2025. If you are reading this post well into 2025, you might want to check if GCP already has a direct way to do it, using Web UI or CLI, or they might have changed something since then.

For the past two years, I’ve been working with GCP and CloudSQL. I’ve had the experience of working with CloudSQL, more specifically with PostgreSQL, and it works pretty well.

I’ve had the task of migrating a CloudSQL database from one project to another and let me tell you, it seems crazy to think that Google Cloud doesn’t have a direct way to do it, using Web UI or CLI.

I searched online and found a post from another person that explained how to do it, and basically you need to make some API calls directly, meaning that it’s actually possible, but Google Cloud doesn’t have a direct way to do it, wich is even more crazy.

The migration process assumes that you already have a CloudSQL instance in the source project and also on the destination project. You need to have a backup of the database in the source project, because essentially you need a backup to restore to the destionation CloudSQL instance.

Migration steps#

  1. Get the ID of a backup from the source CloudSQL instance
curl -X GET -H "Authorization: Bearer $(gcloud auth print-access-token)" "https://sqladmin.googleapis.com/sql/v1beta4/projects/<SOURCE PROJECT ID>/instances/<SOURCE CLOUDSQL INSTANCE NAME>/backupRuns"

The output will be something like this:

{
  "kind": "sql#backupRunsList",
  "items": [
    {
      "kind": "sql#backupRun",
      "status": "SUCCESSFUL",
      "enqueuedTime": "2024-04-29T04:37:55.560Z",
      "id": "1714365475560",
      "startTime": "2024-04-29T04:37:55.580Z",
      "endTime": "2024-04-29T04:39:26.945Z",
      "type": "ON_DEMAND",
      "windowStartTime": "2024-04-29T04:37:55.560Z",
      "instance": "testprojecta",
      "selfLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/projecta-421511/instances/testprojecta/backupRuns/1714365475560",
      "location": "us",
      "backupKind": "SNAPSHOT"
    },
    {
      "kind": "sql#backupRun",
      "status": "SUCCESSFUL",
      "enqueuedTime": "2024-04-29T04:35:30.777Z",
      "id": "1714365330777", <- backup ID ( will be needed )
      "startTime": "2024-04-29T04:35:30.804Z",
      "endTime": "2024-04-29T04:37:02.218Z",
      "type": "AUTOMATED",
      "description": "Backup automatically created after creating an instance with PITR enabled",
      "windowStartTime": "2024-04-29T04:35:30.777Z",
      "instance": "testprojecta", <- instance NAME ( will be needed )
      "selfLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/projecta-421511/instances/testprojecta/backupRuns/1714365330777",
      "location": "us",
      "backupKind": "SNAPSHOT"
    }
  ]
}

Find the backup ID of the backup you want to use.

  1. Create a JSON file, called request.json, with the following content:
{
  "restoreBackupContext":
  {
    "backupRunId": 1736782123237,
    "project": "<SOURCE PROJECT ID>",
    "instanceId": "<SOURCE CLOUDSQL INSTANCE NAME>"
  }
}
  1. Execute the following command that will restore the database to the destination CloudSQL instance, using the backup ID you found on step 1.
curl -X POST -H "Authorization: Bearer $(gcloud auth print-access-token)" -H "Content-Type: application/json; charset=utf-8" -d @request.json  "https://sqladmin.googleapis.com/sql/v1beta4/projects/<DESTIONATION PROJECT ID>/instances/<DESTIONATION CLOUDSQL INSTANCE NAME>/restoreBackup"

This might take a few minutes to complete. This command runs asynchronously, so you can check the status of the operation using the Web UI.

Conclusion#

I hope this post was useful for you. I wish that GCP would have a more clear and direct way of perfoming this.

Migrating a CloudSQL database from one project to another is a common task, so I find hard to believe that Google Cloud doesn’t have a direct way to do it, using Web UI or CLI.