Cloud Functions rollbacks are surprisingly tricky because the system doesn’t actually "roll back" in the way you might expect; it deploys a new version that happens to match an old configuration.
Let’s see this in action. Imagine you have a function my-function that’s currently deployed with version v3.
gcloud functions list --filter="name:projects/my-project/functions/my-function" \
--format="value(name, versionId, status)"
Output:
projects/my-project/functions/my-function v3 ACTIVE
Now, you deploy a new version, v4, with some changes.
gcloud functions deploy my-function \
--region=us-central1 \
--source=. \
--entry-point=handler \
--runtime=nodejs18 \
--trigger-http
The output shows a new version, v4, is now active.
Deploying function (may take a while)...done.
available: PREPARING
available: ACTIVE
function: my-function
region: us-central1
runtime: nodejs18
entry point: handler
...
version: v4
If you check the function’s status again, you’ll see v4.
gcloud functions list --filter="name:projects/my-project/functions/my-function" \
--format="value(name, versionId, status)"
Output:
projects/my-project/functions/my-function v4 ACTIVE
To "rollback" to v3, you don’t go back to v3. Instead, you redeploy the source code and configuration that was active during v3. Cloud Functions doesn’t maintain historical snapshots of your code in a way that lets you pick them. It maintains historical deployments, each with its own immutable version ID.
Here’s how you trigger a rollback: you use the gcloud functions deploy command again, but you specify the exact source code and configuration that corresponds to the version you want to return to. This usually means pointing to the same source repository commit or local directory that was used for the desired previous version.
If your source code is in Cloud Source Repositories or a GitHub repository connected via Cloud Build, you can specify a tag or commit SHA. For example, to roll back to a version deployed from commit abcdef123456:
gcloud functions deploy my-function \
--region=us-central1 \
--source=https://source.developers.google.com/p/my-project/r/my-repo \
--source-revision=abcdef123456 \
--entry-point=handler \
--runtime=nodejs18 \
--trigger-http
If you’re deploying from a local directory, you’d simply run the deploy command again using that specific directory. The key is that the state of that directory at the time of the previous deployment is what you’re effectively re-deploying. Cloud Functions will then assign a new version ID (e.g., v5) to this redeployed configuration.
gcloud functions deploy my-function \
--region=us-central1 \
--source=/path/to/your/code/as/it/was/for/v3 \
--entry-point=handler \
--runtime=nodejs18 \
--trigger-http
After this redeployment, your function status will show the new version ID, but its behavior will be identical to the previous target version.
gcloud functions list --filter="name:projects/my-project/functions/my-function" \
--format="value(name, versionId, status)"
Output (example):
projects/my-project/functions/my-function v5 ACTIVE
The actual mechanism is that each deployment creates an immutable snapshot of your code, environment variables, and trigger configuration. When you "rollback," you’re initiating a new deployment that uses the same artifact as a previous deployment. The old version doesn’t become "un-deployed"; it remains in the history, but it’s no longer the active version. You can inspect these historical versions using gcloud functions describe my-function --region=us-central1 --format='json(status.latestVersion.versionId, status.latestVersion.createTime)' to see the currently active one, and then infer which historical deployment you want to mimic.
What often trips people up is looking for a "revert" button or a direct command to select a past version ID to reactivate. Instead, you must always use deploy with the desired historical configuration.
The next hurdle you’ll likely face is managing the historical artifacts: ensuring you have the exact source code or container image readily available for any potential rollback.