Deploying Firebase Resources with Cloud Build


Objective

When managing Firebase products, one important consideration is the management of infrastructure resources such as rules and indexes.

Before release, manually updating rules via CLI is not a big issue, but after launch, deploying incorrect settings to production can cause significant damage. Therefore, it is safer to deploy via CI/CD.

In this article, I will show how to use Cloud Build to automatically deploy these infrastructure resources triggered by a push to the main branch on GitHub.

Creating a Cloud Build Trigger

Since there are both development and production environments, I use Terraform to create Cloud Build Triggers to avoid environment discrepancies. I referenced the following document:

https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/cloudbuild_trigger

Due to Cloud Build updates, behavior may differ depending on when the project was created, so I also created a new service account.

To operate Firebase resources, I grant the roles/firebase.admin permission to the account used by the trigger.

resource "google_project_iam_member" "firebase_admin" {
  project = var.project_id
  role    = "roles/firebase.admin"
  member  = "serviceAccount:${google_service_account.cloudbuild_service_account.email}"
}

Preparing to Run Firebase CLI in Cloud Build

To operate the Firebase CLI tool in Cloud Build, you need to push the Firebase CLI as a Docker image to Artifact Registry.

https://cloud.google.com/build/docs/deploying-builds/deploy-firebase

Basically, follow the flow in this document, but there are a few pitfalls.

First, if you run git clone on Windows, the line endings may change from LF to CRLF, which can prevent sh files from running.

Windows users should disable autocrlf to avoid rewriting line endings. This is not mentioned in the official documentation, but there is a note on GitHub.

git clone https://github.com/GoogleCloudPlatform/cloud-builders-community.git --config core.autocrlf=false

Next is the process of running Cloud Build and pushing to Artifact Registry. According to the command, the image is pushed to the US region by default.

steps:
- name: 'gcr.io/cloud-builders/docker'
  args: ['build', '-t', 'gcr.io/$PROJECT_ID/firebase', '.']
images:
- 'gcr.io/$PROJECT_ID/firebase'
tags: ['cloud-builders-community']

If you usually use the US region, this is fine, but if you use other regions like Asia or Europe for resources, cross-region communication may incur additional costs.

In this project, resources are placed outside the US region for GDPR compliance, so I manually push to Artifact Registry instead of using cloudbuild.yaml.

First, create a repository in Artifact Registry:

gcloud artifacts repositories create firebase \
  --repository-format=docker \
  --location=asia-northeast1 \
  --description="Firebase CLI Docker image"

Next, build the Firebase Docker image locally. Move to the cloned cloud build repository:

cd cloud-builders-community/firebase

Run the Docker build command:

docker build -t asia-northeast1-docker.pkg.dev/{your_project_id}/firebase/firebase .

After creating the image locally, you need to configure Docker authentication for the registry before pushing manually. Run the following command:

https://stackoverflow.com/questions/72251787/permission-artifactregistry-repositories-downloadartifacts-denied-on-resource

gcloud auth configure-docker asia-northeast1-docker.pkg.dev

This command adds the following settings to ~/.docker/config.json:

{
  "credHelpers": {
    "asia-northeast1-docker.pkg.dev": "gcloud"
  }
}

Now you are authenticated and can push to Artifact Registry:

docker push asia-northeast1-docker.pkg.dev/{your_project_id}/firebase/firebase:latest

If the push succeeds, you are ready. Finally, modify the yaml used by Cloud Build to update the name part from the sample code in the documentation:

steps:
  - name: asia-northeast1-docker.pkg.dev/$PROJECT_ID/firebase/firebase
    args: 
      - 'deploy'
      - '--project=$PROJECT_ID'
      - '--only=firestore:rules'

timeout: 540s
options:
  logging: CLOUD_LOGGING_ONLY

Now, by combining this with the Cloud Build trigger mentioned earlier, deployments will be automated whenever you merge to the main branch.

Of course, you can also test Cloud Build locally before deploying. Note that the option to specify the same service account as the trigger is a bit special:

gcloud builds submit \
  --region=asia-northeast1 \
  --service-account projects/{your_project_id}/serviceAccounts/cloud-build-common-sa@{your_project_id}.iam.gserviceaccount.com \
  --config cloudbuild__firebase.yaml \
  .

This can also be achieved with GitHub Actions, but using Cloud Build is simpler since you don't need to issue authentication keys.

Finally, be sure to check out Tanuki's information as well!

0
Subscribe to my newsletter

Read articles from Tanuki Developers directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Tanuki Developers
Tanuki Developers

Tanuki - Smart Shopping List Create a shopping list with images. Shop smart and more convenient. Android App iOS App