Stay organized with collections Save and categorize content based on your preferences.
Firebase is beginning to support Terraform. If you're on a team that wants to automate and standardize creating Firebase projects with specific resources provisioned and services enabled, then using Terraform with Firebase can be a good fit for you.
The basic workflow for using Terraform with Firebase includes the following:
Creating and customizing a Terraform configuration file (a .tf file) which specifies the infrastructure you want to provision (that is, resources you want to provision and the services you want to enable).
Using gcloud CLI commands that interface with Terraform to provision the infrastructure specified in the .tf file.
Creating Cloud Storage buckets or database instances and deploying Firebase Security Rules for them.
You can use standard Terraform config files and commands to accomplish all these tasks. And to help you with this, we've provided sample Terraform config files for several common use cases.
Generalized workflow for using Terraform with Firebase
Prerequisites
This guide is an introduction to using Terraform with Firebase, so it assumes basic proficiency with Terraform. Make sure that you've completed the following prerequisites before starting this workflow.
Install Terraform and familiarize yourself with Terraform using their official tutorials.
View requirements for user accounts and service accounts
If using a user account, you must have accepted the Firebase Terms of Service (Firebase ToS). You have accepted the Firebase ToS if you can view a Firebase project in the Firebase console
For Terraform to take certain actions (for example, create projects), the following must be true:
The user or service account must have the applicable IAM access for those actions.
If the user or service account is part of a Google Cloud organization, then the org policies must allow the account to take those actions.
Step 1: Create and customize a Terraform config file
A Terraform config file needs two main sections (which are described in detail below):
A provider setup is required no matter which Firebase products or services are involved.
Create a Terraform config file (like main.tf file) in your local directory.
In this guide, you'll use this config file to specify both the provider setup and all the infrastructure that you want Terraform to create. Note, though, that you have options for how to include the provider setup.
View options for how to include the provider setup
You have the following options for how to include a provider setup to the rest of your Terraform configuration:
Option 1: Include it at the top of a single Terraform .tf config file (as shown in this guide).
Use this option if you're just getting started with Terraform or just trying out Terraform with Firebase.
Option 2: Include it in a separate .tf file (like a provider.tf file), apart from the .tf file where you specify infrastructure to create (like a main.tf file).
Use this option if you're part of a larger team that needs to standardize setup.
When running Terraform commands, both the provider.tf file and the main.tf file must be in the same directory.
Include the following provider setup at the top of the main.tf file.
You must use the google-beta provider because this is a beta release of using Firebase with Terraform. Exercise caution when using in production.
# Terraform configuration to set up providers by version.terraform{required_providers{google-beta={source="hashicorp/google-beta"version="~> 6.0"}}}# Configures the provider to use the resource block's specified project for quota checks.provider"google-beta"{user_project_override=true}# Configures the provider to not use the resource block's specified project for quota checks.# This provider should only be used during project creation and initializing services.provider"google-beta"{alias="no_user_project_override"user_project_override=false}
Continue to the next section to complete your config file and specify what infrastructure to create.
Specify what infrastructure to create using resource blocks
In your Terraform config file (for this guide, your main.tf file), you need to specify all the infrastructure you want Terraform to create (meaning all the resources you want to provision and all the services you want to enable). In this guide, find a full list of all Firebase resources that support Terraform.
Open your main.tf file.
Under the provider setup, include the following config of resource blocks.
This basic example creates a new Firebase project and then creates a Firebase Android App within that project.
# Terraform configuration to set up providers by version....# Configures the provider to use the resource block's specified project for quota checks....# Configures the provider to not use the resource block's specified project for quota checks....# Creates a new Google Cloud project.resource"google_project""default"{provider=google-beta.no_user_project_overridename="Project Display Name"project_id="project-id-for-new-project" # Required for any service that requires the Blaze pricing plan # (like Firebase Authentication with GCIP)billing_account="000000-000000-000000" # Required for the project to display in any list of Firebase projects.labels={"firebase"="enabled"}}# Enables required APIs.resource"google_project_service""default"{provider=google-beta.no_user_project_overrideproject=google_project.default.project_idfor_each=toset(["cloudbilling.googleapis.com","cloudresourcemanager.googleapis.com","firebase.googleapis.com", # Enabling the ServiceUsage API allows the new project to be quota checked from now on."serviceusage.googleapis.com",])service=each.key # Don't disable the service if the resource block is removed by accident.disable_on_destroy=false}# Enables Firebase services for the new project created above.resource"google_firebase_project""default"{provider=google-betaproject=google_project.default.project_id # Waits for the required APIs to be enabled.depends_on=[google_project_service.default]}# Creates a Firebase Android App in the new project created above.resource"google_firebase_android_app""default"{provider=google-betaproject=google_project.default.project_iddisplay_name="My Awesome Android app"package_name="awesome.package.name" # Wait for Firebase to be enabled in the Google Cloud project before creating this App.depends_on=[google_firebase_project.default,]}
View a highly annotated version of this example config file
If you're not familiar with the infrastructure of projects and apps as resources, review the following documentation:
# Terraform configuration to set up providers by version....# Configures the provider to use the resource block's specified project for quota checks....# Configures the provider to not use the resource block's specified project for quota checks....# Creates a new Google Cloud project.resource"google_project""default"{ # Use the provider that enables the setup of quota checks for a new projectprovider=google-beta.no_user_project_overridename="Project Display Name" // learn more about the project nameproject_id="project-id-for-new-project" // learn more about the project ID # Required for any service that requires the Blaze pricing plan # (like Firebase Authentication with GCIP)billing_account="000000-000000-000000" # Required for the project to display in any list of Firebase projects.labels={"firebase"="enabled" // learn more about the Firebase-enabled label}}# Enables required APIs.resource"google_project_service""default"{ # Use the provider without quota checks for enabling APISprovider=google-beta.no_user_project_overrideproject=google_project.default.project_idfor_each=toset(["cloudbilling.googleapis.com","cloudresourcemanager.googleapis.com","firebase.googleapis.com", # Enabling the ServiceUsage API allows the new project to be quota checked from now on."serviceusage.googleapis.com",])service=each.key # Don't disable the service if the resource block is removed by accident.disable_on_destroy=false}# Enables Firebase services for the new project created above.# This action essentially "creates a Firebase project" and allows the project to use# Firebase services (like Firebase Authentication) and# Firebase tooling (like the Firebase console).# Learn more about the relationship between Firebase projects and Google Cloud.resource"google_firebase_project""default"{ # Use the provider that performs quota checks from now onprovider=google-betaproject=google_project.default.project_id # Waits for the required APIs to be enabled.depends_on=[google_project_service.default]}# Creates a Firebase Android App in the new project created above.# Learn more about the relationship between Firebase Apps and Firebase projects.resource"google_firebase_android_app""default"{provider=google-betaproject=google_project.default.project_iddisplay_name="My Awesome Android app" # learn more about an app's display namepackage_name="awesome.package.name" # learn more about an app's package name # Wait for Firebase to be enabled in the Google Cloud project before creating this App.depends_on=[google_firebase_project.default,]}
Step 2: Run Terraform commands to create the specified infrastructure
To provision the resources and enable the services specified in your main.tf file, run the following commands from the same directory as your main.tf file. For detailed information about these commands, see the Terraform documentation.
If this is the first time that you're running Terraform commands in the directory, you need to initialize the configuration directory and install the Google Terraform provider. Do this by running the following command:
terraform init
Create the infrastructure specified in your main.tf file by running the following command:
terraform apply
Confirm that everything was provisioned or enabled as expected:
Option 1: See the configuration printed in your terminal by running the following command:
The following Firebase and Google resources have Terraform support. And we're adding more resources all the time! So if you don't see the resource that you want to manage with Terraform, then check back soon to see if it's available or request it by filing an issue in the repo.
google_identity_platform_config — enable Google Cloud Identity Platform (GCIP) (which is the backend for Firebase Authentication) and provide project-level authentication settings
The project in which Terraform will enable GCIP and/or Firebase Authentication must be on the Blaze pricing plan (that is, the project must have an associated Cloud Billing account). You can do this programmatically by setting the billing_account attribute in the google_project resource.
This resource also enables more configurations, like local sign-in methods, such as anonymous, email/password, and phone authentication, as well as blocking functions and authorized domains.
Deploying Firebase Realtime Database Security Rules via Terraform (learn how to deploy these Rules using other tooling, including programmatic options)
Sample Terraform config files for common use cases
Set up Firebase Authentication with GCIP
This config creates a new Google Cloud project, associates the project with a Cloud Billing account (the Blaze pricing plan is required for Firebase Authentication with GCIP), enables Firebase services for the project, sets up Firebase Authentication with GCIP, and registers three different app types with the project.
Note that enabling GCIP is required to set up Firebase Authentication via Terraform.
# Creates a new Google Cloud project.resource"google_project""auth"{provider=google-beta.no_user_project_overridefolder_id="folder-id-for-new-project"name="Project Display Name"project_id="project-id-for-new-project" # Associates the project with a Cloud Billing account # (required for Firebase Authentication with GCIP).billing_account="000000-000000-000000"}# Enables required APIs.resource"google_project_service""auth"{provider=google-beta.no_user_project_overrideproject=google_project.auth.project_idfor_each=toset(["cloudbilling.googleapis.com","cloudresourcemanager.googleapis.com","serviceusage.googleapis.com","identitytoolkit.googleapis.com",])service=each.key # Don't disable the service if the resource block is removed by accident.disable_on_destroy=false}# Enables Firebase services for the new project created above.resource"google_firebase_project""auth"{provider=google-betaproject=google_project.auth.project_iddepends_on=[google_project_service.auth,]}# Creates an Identity Platform config.# Also enables Firebase Authentication with Identity Platform in the project if not.resource"google_identity_platform_config""auth"{provider=google-betaproject=google_firebase_project.auth.project # Auto-deletes anonymous usersautodelete_anonymous_users=true # Configures local sign-in methods, like anonymous, email/password, and phone authentication.sign_in{allow_duplicate_emails=trueanonymous{enabled=true}email{enabled=truepassword_required=false}phone_number{enabled=truetest_phone_numbers={"+11231231234"="000000"}}} # Sets an SMS region policy.sms_region_config{allowlist_only{allowed_regions=["US","CA",]}} # Configures blocking functions.blocking_functions{triggers{event_type="beforeSignIn"function_uri="https://us-east1-${google_project.auth.project_id}.cloudfunctions.net/before-sign-in"}forward_inbound_credentials{refresh_token=trueaccess_token=trueid_token=true}} # Configures a temporary quota for new signups for anonymous, email/password, and phone number.quota{sign_up_quota_config{quota=1000start_time=""quota_duration="7200s"}} # Configures authorized domains.authorized_domains=["localhost","${google_project.auth.project_id}.firebaseapp.com","${google_project.auth.project_id}.web.app",]}# Creates a Firebase Android App in the new project created above.resource"google_firebase_android_app""auth"{provider=google-betaproject=google_firebase_project.auth.projectdisplay_name="My Android app"package_name="android.package.name"}# Creates a Firebase Apple-platforms App in the new project created above.resource"google_firebase_apple_app""auth"{provider=google-betaproject=google_firebase_project.auth.projectdisplay_name="My Apple app"bundle_id="apple.app.12345"}# Creates a Firebase Web App in the new project created above.resource"google_firebase_web_app""auth"{provider=google-betaproject=google_firebase_project.auth.projectdisplay_name="My Web app"}
Provision a Firebase Data Connect service
This config creates a new Google Cloud project, enables Firebase services for the project, and provisions a Data Connect service.
# Creates a new Google Cloud project.resource"google_project""dataconnect"{provider=google-beta.no_user_project_overridefolder_id="folder-id-for-new-project"name="Project Display Name"project_id="project-id-for-new-project" # Associates the project with a Cloud Billing account # (required to use Firebase Data Connect).billing_account="000000-000000-000000" # Required for the project to display in a list of Firebase projects.labels={"firebase"="enabled"}}# Enables required APIs.resource"google_project_service""services"{provider=google-beta.no_user_project_overrideproject=google_project.dataconnect.project_idfor_each=toset(["serviceusage.googleapis.com","cloudresourcemanager.googleapis.com","firebasedataconnect.googleapis.com",])service=each.key # Don't disable the service if the resource block is removed by accident.disable_on_destroy=false}# Enables Firebase services for the new project created earlier.resource"google_firebase_project""dataconnect"{provider=google-betaproject=google_project.dataconnect.project_iddepends_on=[google_project_service.services]}# Create a Firebase Data Connect serviceresource"google_firebase_data_connect_service""dataconnect-default"{project=google_firebase_project.dataconnect.projectlocation="name-of-region-for-service"service_id="${google_firebase_project.dataconnect.project}-default-fdc"deletion_policy="DEFAULT"}
Provision the default Firebase Realtime Database instance
This config creates a new Google Cloud project, enables Firebase services for the project, provisions the project's default Realtime Database instance, and registers three different app types with the project.
# Creates a new Google Cloud project.resource"google_project""rtdb"{provider=google-beta.no_user_project_overridefolder_id="folder-id-for-new-project"name="Project Display Name"project_id="project-id-for-new-project"}# Enables required APIs.resource"google_project_service""rtdb"{provider=google-beta.no_user_project_overrideproject=google_project.rtdb.project_idfor_each=toset(["serviceusage.googleapis.com","cloudresourcemanager.googleapis.com","firebasedatabase.googleapis.com",])service=each.key # Don't disable the service if the resource block is removed by accident.disable_on_destroy=false}# Enables Firebase services for the new project created above.resource"google_firebase_project""rtdb"{provider=google-betaproject=google_project.rtdb.project_iddepends_on=[google_project_service.rtdb]}# Provisions the default Realtime Database default instance.resource"google_firebase_database_instance""database"{provider=google-betaproject=google_firebase_project.rtdb.project # See available locations: https://firebase.google.com/docs/database/locationsregion="name-of-region" # This value will become the first segment of the database's URL.instance_id="${google_project.rtdb.project_id}-default-rtdb"type="DEFAULT_DATABASE"}# Creates a Firebase Android App in the new project created above.resource"google_firebase_android_app""rtdb"{provider=google-betaproject=google_firebase_project.rtdb.projectdisplay_name="My Android app"package_name="android.package.name"}# Creates a Firebase Apple-platforms App in the new project created above.resource"google_firebase_apple_app""rtdb"{provider=google-betaproject=google_firebase_project.rtdb.projectdisplay_name="My Apple app"bundle_id="apple.app.12345"}# Creates a Firebase Web App in the new project created above.resource"google_firebase_web_app""rtdb"{provider=google-betaproject=google_firebase_project.rtdb.projectdisplay_name="My Web app"}
This config creates a new Google Cloud project, associates the project with a Cloud Billing account (the Blaze pricing plan is required for multiple Realtime Database instances), enables Firebase services for the project, provisions multiple Realtime Database instances (including the project's default Realtime Database instance), and registers three different app types with the project.
# Creates a new Google Cloud project.resource"google_project""rtdb-multi"{provider=google-beta.no_user_project_overridefolder_id="folder-id-for-new-project"name="Project Display Name"project_id="project-id-for-new-project" # Associate the project with a Cloud Billing account # (required for multiple Realtime Database instances).billing_account="000000-000000-000000"}# Enables required APIs.resource"google_project_service""rtdb-multi"{provider=google-beta.no_user_project_overrideproject=google_project.rtdb-multi.project_idfor_each=toset(["cloudbilling.googleapis.com","serviceusage.googleapis.com","cloudresourcemanager.googleapis.com","firebasedatabase.googleapis.com",])service=each.key # Don't disable the service if the resource block is removed by accident.disable_on_destroy=false}# Enables Firebase services for the new project created above.resource"google_firebase_project""rtdb-multi"{provider=google-betaproject=google_project.rtdb-multi.project_iddepends_on=[google_project_service.rtdb-multi]}# Provisions the default Realtime Database default instance.resource"google_firebase_database_instance""database-default"{provider=google-betaproject=google_firebase_project.rtdb-multi.project # See available locations: https://firebase.google.com/docs/database/locationsregion="name-of-region" # This value will become the first segment of the database's URL.instance_id="${google_project.rtdb-multi.project_id}-default-rtdb"type="DEFAULT_DATABASE"}# Provisions an additional Realtime Database instance.resource"google_firebase_database_instance""database-additional"{provider=google-betaproject=google_firebase_project.rtdb-multi.project # See available locations: https://firebase.google.com/docs/projects/locations#rtdb-locations # This location doesn't need to be the same as the default database instance.region="name-of-region" # This value will become the first segment of the database's URL.instance_id="name-of-additional-database-instance"type="USER_DATABASE"}# Creates a Firebase Android App in the new project created above.resource"google_firebase_android_app""rtdb-multi"{provider=google-betaproject=google_firebase_project.rtdb-multi.projectdisplay_name="My Android app"package_name="android.package.name"}# Creates a Firebase Apple-platforms App in the new project created above.resource"google_firebase_apple_app""rtdb-multi"{provider=google-betaproject=google_firebase_project.rtdb-multi.projectdisplay_name="My Apple app"bundle_id="apple.app.12345"}# Creates a Firebase Web App in the new project created above.resource"google_firebase_web_app""rtdb-multi"{provider=google-betaproject=google_firebase_project.rtdb-multi.projectdisplay_name="My Web app"}
Provision the default Cloud Firestore instance
This config creates a new Google Cloud project, enables Firebase services for the project, provisions the project's default Cloud Firestore instance, and registers three different app types with the project.
It also provisions Firebase Security Rules for the default Cloud Firestore instance, creates a Cloud Firestore index, and adds a Cloud Firestore document with seed data.
# Creates a new Google Cloud project.resource"google_project""firestore"{provider=google-beta.no_user_project_overridefolder_id="folder-id-for-new-project"name="Project Display Name"project_id="project-id-for-new-project"}# Enables required APIs.resource"google_project_service""firestore"{provider=google-beta.no_user_project_overrideproject=google_project.firestore.project_idfor_each=toset(["cloudresourcemanager.googleapis.com","serviceusage.googleapis.com","firestore.googleapis.com","firebaserules.googleapis.com",])service=each.key # Don't disable the service if the resource block is removed by accident.disable_on_destroy=false}# Enables Firebase services for the new project created above.resource"google_firebase_project""firestore"{provider=google-betaproject=google_project.firestore.project_iddepends_on=[google_project_service.firestore]}# Provisions the Firestore database instance.resource"google_firestore_database""firestore"{provider=google-betaproject=google_firebase_project.firestore.projectname="(default)" # See available locations: https://firebase.google.com/docs/firestore/locationslocation_id="name-of-region" # "FIRESTORE_NATIVE" is required to use Firestore with Firebase SDKs, authentication, and Firebase Security Rules.type="FIRESTORE_NATIVE"concurrency_mode="OPTIMISTIC"}# Creates a ruleset of Firestore Security Rules from a local file.resource"google_firebaserules_ruleset""firestore"{provider=google-betaproject=google_firestore_database.firestore.projectsource{files{name="firestore.rules" # Write security rules in a local file named "firestore.rules". # Learn more: https://firebase.google.com/docs/firestore/security/get-startedcontent=file("firestore.rules")}}}# Releases the ruleset for the Firestore instance.resource"google_firebaserules_release""firestore"{provider=google-betaname="cloud.firestore" # must be cloud.firestoreruleset_name=google_firebaserules_ruleset.firestore.nameproject=google_firestore_database.firestore.project}# Adds a new Firestore index.resource"google_firestore_index""indexes"{provider=google-betaproject=google_firestore_database.firestore.projectcollection="quiz"query_scope="COLLECTION"fields{field_path="question"order="ASCENDING"}fields{field_path="answer"order="ASCENDING"}}# Adds a new Firestore document with seed data.# Don't use real end-user or production data in this seed document.resource"google_firestore_document""doc"{provider=google-betaproject=google_firestore_database.firestore.projectcollection="quiz"document_id="question-1"fields="{\"question\":{\"stringValue\":\"Favorite Database\"},\"answer\":{\"stringValue\":\"Firestore\"}}"}# Creates a Firebase Android App in the new project created above.resource"google_firebase_android_app""firestore"{provider=google-betaproject=google_firebase_project.firestore.projectdisplay_name="My Android app"package_name="android.package.name"}# Creates a Firebase Apple-platforms App in the new project created above.resource"google_firebase_apple_app""firestore"{provider=google-betaproject=google_firebase_project.firestore.projectdisplay_name="My Apple app"bundle_id="apple.app.12345"}# Creates a Firebase Web App in the new project created above.resource"google_firebase_web_app""firestore"{provider=google-betaproject=google_firebase_project.firestore.projectdisplay_name="My Web app"}
This is the ruleset of Cloud Firestore Security Rules that should be in a local file named firestore.rules.
This config creates a new Google Cloud project, associates the project with a Cloud Billing account (the Blaze pricing plan is required for additional buckets), enables Firebase services for the project, provisions additional, non-default Cloud Storage buckets, and registers three different app types with the project.
It also provisions Firebase Security Rules for each Cloud Storage bucket, and uploads a file to one of the Cloud Storage buckets.
# Creates a new Google Cloud project.resource"google_project""storage-multi"{provider=google-beta.no_user_project_overridefolder_id="folder-id-for-new-project"name="Project Display Name"project_id="project-id-for-new-project" # Associates the project with a Cloud Billing account # (required for multiple Cloud Storage buckets).billing_account="000000-000000-000000"}# Enables required APIs.resource"google_project_service""storage-multi"{provider=google-beta.no_user_project_overrideproject=google_project.storage-multi.project_idfor_each=toset(["cloudbilling.googleapis.com","serviceusage.googleapis.com","cloudresourcemanager.googleapis.com","firebaserules.googleapis.com","firebasestorage.googleapis.com","storage.googleapis.com",])service=each.key # Don't disable the service if the resource block is removed by accident.disable_on_destroy=false}# Enables Firebase services for the new project created above.resource"google_firebase_project""storage-multi"{provider=google-betaproject=google_project.storage-multi.project_iddepends_on=[google_project_service.storage-multi]}# Provisions a Cloud Storage bucket.resource"google_storage_bucket""bucket-1"{provider=google-betaproject=google_firebase_project.storage-multi.projectname="name-of-storage-bucket" # See available locations: https://cloud.google.com/storage/docs/locations#available-locationslocation="name-of-region-for-bucket"}# Provisions an additional Cloud Storage bucket.resource"google_storage_bucket""bucket-2"{provider=google-betaproject=google_firebase_project.storage-multi.projectname="name-of-additional-storage-bucket" # See available locations: https://cloud.google.com/storage/docs/locations#available-locations # This location does not need to be the same as the existing Storage bucket.location="name-of-region-for-additional-bucket"}# Makes the first Storage bucket accessible for Firebase SDKs, authentication, and Firebase Security Rules.resource"google_firebase_storage_bucket""bucket-1"{provider=google-betaproject=google_firebase_project.storage-multi.projectbucket_id=google_storage_bucket.bucket-1.name}# Makes the additional Storage bucket accessible for Firebase SDKs, authentication, and Firebase Security Rules.resource"google_firebase_storage_bucket""bucket-2"{provider=google-betaproject=google_firebase_project.storage-multi.projectbucket_id=google_storage_bucket.bucket-2.name}# Creates a ruleset of Firebase Security Rules from a local file.resource"google_firebaserules_ruleset""storage-multi"{provider=google-betaproject=google_firebase_project.storage-multi.projectsource{files{ # Write security rules in a local file named "storage.rules" # Learn more: https://firebase.google.com/docs/storage/security/get-startedname="storage.rules"content=file("storage.rules")}}}# Releases the ruleset to the first Storage bucket.resource"google_firebaserules_release""bucket-1"{provider=google-betaname="firebase.storage/${google_storage_bucket.bucket-1.name}"ruleset_name="projects/${google_project.storage-multi.project_id}/rulesets/${google_firebaserules_ruleset.storage-multi.name}"project=google_firebase_project.storage-multi.project}# Releases the ruleset to the additional Storage bucket.resource"google_firebaserules_release""bucket-2"{provider=google-betaname="firebase.storage/${google_storage_bucket.bucket-2.name}"ruleset_name="projects/${google_project.storage-multi.project_id}/rulesets/${google_firebaserules_ruleset.storage-multi.name}"project=google_firebase_project.storage-multi.project}# Uploads a new file to the first Storage bucket.# Do not use real end-user or production data in this file.resource"google_storage_bucket_object""cat-picture-multi"{provider=google-betaname="cat.png"source="path/to/cat.png"bucket=google_storage_bucket.bucket-1.name}# Creates a Firebase Android App in the new project created above.resource"google_firebase_android_app""storage-multi"{provider=google-betaproject=google_firebase_project.storage-multi.projectdisplay_name="My Android app"package_name="android.package.name"}# Creates a Firebase Apple-platforms App in the new project created above.resource"google_firebase_apple_app""storage-multi"{provider=google-betaproject=google_firebase_project.storage-multi.projectdisplay_name="My Apple app"bundle_id="apple.app.12345"}# Creates a Firebase Web App in the new project created above.resource"google_firebase_web_app""storage-multi"{provider=google-betaproject=google_firebase_project.storage-multi.projectdisplay_name="My Web app"}
This is the ruleset of Cloud Storage Security Rules that should be in a local file named storage.rules.
This config creates a new Google Cloud project, enables Firebase services for the project, and sets up and enables enforcement of Firebase App Check for Cloud Firestore so that it can only be accessed from your Android app.
# Creates a new Google Cloud project.resource"google_project""appcheck"{provider=google-beta.no_user_project_overridefolder_id="folder-id-for-new-project"name="Project Display Name"project_id="project-id-for-new-project"}# Enables required APIs.resource"google_project_service""services"{provider=google-beta.no_user_project_overrideproject=google_project.appcheck.project_idfor_each=toset(["cloudresourcemanager.googleapis.com","firebase.googleapis.com","firebaseappcheck.googleapis.com","firestore.googleapis.com","serviceusage.googleapis.com",])service=each.key # Don't disable the service if the resource block is removed by accident.disable_on_destroy=false}# Enables Firebase services for the new project created earlier.resource"google_firebase_project""appcheck"{provider=google-betaproject=google_project.appcheck.project_iddepends_on=[google_project_service.services]}# Provisions the Firestore database instance.resource"google_firestore_database""database"{provider=google-betaproject=google_firebase_project.appcheck.projectname="(default)" # See available locations: https://firebase.google.com/docs/projects/locations#default-cloud-locationlocation_id="name-of-region" # "FIRESTORE_NATIVE" is required to use Firestore with Firebase SDKs, authentication, and Firebase Security Rules.type="FIRESTORE_NATIVE"concurrency_mode="OPTIMISTIC"}# Creates a Firebase Android App in the new project created earlier.resource"google_firebase_android_app""appcheck"{provider=google-betaproject=google_firebase_project.appcheck.projectdisplay_name="Play Integrity app"package_name="package.name.playintegrity"sha256_hashes=[ # TODO: insert your Android app's SHA256 certificate]}# Register the Android app with the Play Integrity providerresource"google_firebase_app_check_play_integrity_config""appcheck"{provider=google-betaproject=google_firebase_project.appcheck.projectapp_id=google_firebase_android_app.appcheck.app_iddepends_on=[google_firestore_database.database]lifecycle{precondition{condition=length(google_firebase_android_app.appcheck.sha256_hashes)>0error_message="Provide a SHA-256 certificate on the Android App to use App Check"}}}# Enable enforcement of App Check for Firestoreresource"google_firebase_app_check_service_config""firestore"{provider=google-betaproject=google_firebase_project.appcheck.projectservice_id="firestore.googleapis.com"depends_on=[google_project_service.services]}
Install an instance of a Firebase Extension
This config creates a new Google Cloud project, enables Firebase services for the project, and installs a new instance of a Firebase Extension in the project. If the instance already exists, its parameters are updated based on the values provided in the config.
# Creates a new Google Cloud project.resource"google_project""extensions"{provider=google-beta.no_user_project_overridefolder_id="folder-id-for-new-project"name="Project Display Name"project_id="project-id-for-new-project" # Associates the project with a Cloud Billing account # (required to use Firebase Extensions).billing_account="000000-000000-000000"}# Enables required APIs.resource"google_project_service""extensions"{provider=google-beta.no_user_project_overrideproject=google_project.extensions.project_idfor_each=toset(["cloudbilling.googleapis.com","cloudresourcemanager.googleapis.com","serviceusage.googleapis.com","firebase.googleapis.com","firebaseextensions.googleapis.com",])service=each.key # Don't disable the service if the resource block is removed by accident.disable_on_destroy=false}# Enables Firebase services for the new project created above.resource"google_firebase_project""extensions"{provider=google-betaproject=google_project.extensions.project_iddepends_on=[google_project_service.extensions,]}# Installs an instance of the "Translate Text in Firestore" extension.# Or updates the extension if the specified instance already exists.resource"google_firebase_extensions_instance""translation"{provider=google-betaproject=google_firebase_project.extensions.projectinstance_id="translate-text-in-firestore"config{extension_ref="firebase/firestore-translate-text"params={COLLECTION_PATH="posts/comments/translations"DO_BACKFILL=trueLANGUAGES="ar,en,es,de,fr"INPUT_FIELD_NAME="input"LANGUAGES_FIELD_NAME="languages"OUTPUT_FIELD_NAME="translated"}system_params={"firebaseextensions.v1beta.function/location"="us-central1""firebaseextensions.v1beta.function/memory"="256""firebaseextensions.v1beta.function/minInstances"="0""firebaseextensions.v1beta.function/vpcConnectorEgressSettings"="VPC_CONNECTOR_EGRESS_SETTINGS_UNSPECIFIED"}}}
Enable and protect Vertex AI in Firebase
This config creates a new Google Cloud project, enables Firebase services for the project, including Vertex AI in Firebase, and sets up and enables enforcement of Firebase App Check for Vertex AI in Firebase so that it can only be accessed from your apps.
# Creates a new Google Cloud project.resource"google_project""vertex"{provider=google-beta.no_user_project_overridefolder_id="folder-id-for-new-project"name="Project Display Name"project_id="project-id-for-new-project" # Associate the project with a Cloud Billing account # (required for Vertex AI in Firebase).billing_account="000000-000000-000000"}# Enables required APIs.resource"google_project_service""services"{provider=google-beta.no_user_project_overrideproject=google_project.vertex.project_idfor_each=toset(["cloudresourcemanager.googleapis.com","firebase.googleapis.com","serviceusage.googleapis.com", # Required APIs for Vertex AI in Firebase"aiplatform.googleapis.com","firebasevertexai.googleapis.com", # App Check is recommended to protect Vertex AI in Firebase from abuse"firebaseappcheck.googleapis.com",])service=each.key # Don't disable the service if the resource block is removed by accident.disable_on_destroy=false}# Enables Firebase services for the new project created earlier.resource"google_firebase_project""vertex"{provider=google-betaproject=google_project.vertex.project_iddepends_on=[google_project_service.services]}# Creates a Firebase Web App in the new project created earlier.resource"google_firebase_web_app""app"{provider=google-betaproject=google_firebase_project.vertex.projectdisplay_name="My Web App"}# Creates a Firebase Android App in the new project created earlier.resource"google_firebase_android_app""app"{provider=google-betaproject=google_firebase_project.vertex.projectdisplay_name="My Android App"package_name="package.name.playintegrity"sha256_hashes=[ # TODO: insert your Android app's SHA256 certificate]}# Creates a Firebase Apple App in the new project created earlier.resource"google_firebase_apple_app""app"{provider=google-betaproject=google_firebase_project.vertex.projectdisplay_name="My Apple App"bundle_id="bundle.id"team_id="1234567890"}### Protects Vertex AI in Firebase with App Check.# Turns on enforcement for Vertex AI in Firebaseresource"google_firebase_app_check_service_config""vertex"{provider=google-betaproject=google_firebase_project.vertex.projectservice_id="firebaseml.googleapis.com"enforcement_mode="ENFORCED"}# Enables the reCAPTCHA Enterprise APIresource"google_project_service""recaptcha_enterprise"{provider=google-betaproject=google_firebase_project.vertex.projectservice="recaptchaenterprise.googleapis.com" # Don't disable the service if the resource block is removed by accident.disable_on_destroy=false}# Enables the Play Integrity APIresource"google_project_service""play_integrity"{provider=google-betaproject=google_firebase_project.vertex.projectservice="playintegrity.googleapis.com" # Don't disable the service if the resource block is removed by accident.disable_on_destroy=false}# Allows the web app to use reCAPTCHA Enterprise with App Checkresource"google_firebase_app_check_recaptcha_enterprise_config""appcheck"{provider=google-betaproject=google_firebase_project.vertex.projectapp_id=google_firebase_web_app.app.app_idsite_key="your site key"token_ttl="7200s" # Optionaldepends_on=[google_project_service.recaptcha_enterprise]}# Registers the Android app with the Play Integrity providerresource"google_firebase_app_check_play_integrity_config""appcheck"{provider=google-betaproject=google_firebase_project.vertex.projectapp_id=google_firebase_android_app.app.app_idtoken_ttl="7200s" # Optionallifecycle{precondition{condition=length(google_firebase_android_app.app.sha256_hashes)>0error_message="Provide a SHA-256 certificate on the Android App to use App Check"}}depends_on=[google_project_service.play_integrity]}# Registers the Apple app with the AppAttest providerresource"google_firebase_app_check_app_attest_config""appcheck"{provider=google-betaproject=google_firebase_project.vertex.projectapp_id=google_firebase_apple_app.app.app_idtoken_ttl="7200s" # Optionallifecycle{precondition{condition=google_firebase_apple_app.app.team_id!=""error_message="Provide a Team ID on the Apple App to use App Check"}}}
Troubleshooting and FAQ
You want to learn more about all the different project-related attributes (like project and user_project_override)
This guide uses the following Terraform attributes when working with "projects".
project within a resource block
Recommended: whenever possible, include the project attribute within each resource block
By including a project attribute, Terraform will create the infrastructure specified in the resource block within the specified project. This guide and our sample config files all use this practice.
See the official Terraform documentation about project.
user_project_override within the provider block
For provisioning most resources, you should use user_project_override = true, which means to check quota against your own Firebase project. However, to set up your new project so that it can accept quota checks, you first need to use user_project_override = false.
You get this error: generic::permission_denied: Firebase Tos Not Accepted.
Make sure that the user account that you're using to run gcloud CLI commands has accepted the Firebase Terms of Service (Firebase ToS).
You can do this check by using a browser signed into the user account and trying to view an existing Firebase project in the Firebase console. If you can view an existing Firebase project, then the user account has accepted the Firebase ToS.
If you can't view any existing Firebase project, then the user account probably hasn't accepted the Firebase ToS. To fix this, create a new Firebase project via the Firebase console and accept the Firebase ToS as part of project creation. You can immediately delete this project via Project Settings in the console.
After running terraform apply, you get this error: generic::permission_denied: IAM authority does not have the permission.
Wait a few minutes, and then try running terraform apply again.
The creation of a resource failed, but when you run terraform apply again, it says ALREADY_EXISTS.
This could be due to a propagation delay in various systems. Try to resolve this issue by importing the resource into the Terraform state by running terraform import. Then try running terraform apply again.
When working with Cloud Firestore, you get this error: Error creating Index: googleapi: Error 409;...Concurrent access -- try again
As the error suggests, Terraform may be trying to provision multiple indices and/or creating a document at the same time and ran into a concurrency error. Try running terraform apply again.
You get this error: "you may need to specify 'X-Goog-User-Project' HTTP header for quota and billing purposes".
This error means that Terraform doesn't know which project to check quota against. To troubleshoot, check the following in the resource block:
Make sure that you have specified a value for the project attribute.
Make sure that you're using the provider with user_project_override = true (no alias), which in the Firebase samples is google-beta.
When creating a new Google Cloud project, you get the error that the project ID specified for the new project already exists.
Here are the possible reasons the project ID may already exist:
The project associated with that ID belongs to someone else.
To resolve: Choose another project ID.
The project associated with that ID was recently deleted (in soft-delete state).
To resolve: If you think that the project associated with the ID belongs to you, then check the state of the project using the projects.get REST API.
The project associated with that ID exists correctly under the current user. A possible cause for the error could be that a previous terraform apply got interrupted.
To resolve: Run the following commands: terraform import google_project.default PROJECT_ID and then terraform import google_firebase_project.default PROJECT_ID
Why do you need to provision the default Cloud Firestore instance before the default Cloud Storage bucket?
If you provisioned your default Cloud Storage bucket (via google_app_engine_application) before you try to provision your default Cloud Firestore instance, then you'll find that your default Cloud Firestore instance has already been provisioned. Note that the provisioned database instance is in Datastore mode, which means that it's not accessible to Firebase SDKs, authentication, or Firebase Security Rules. If you want to use Cloud Firestore with these Firebase services, then you'll need to empty the database and then change its database type in the Google Cloud console.
When trying to provision Cloud Storage (via google_app_engine_application) and then your default Cloud Firestore instance, you get this error: Error: Error creating Database: googleapi: Error 409: Database already exists. Please use another database_id.
When you provision a project's default Cloud Storage bucket (via google_app_engine_application) and the project doesn't yet have its default Cloud Firestore instance, then google_app_engine_application automatically provisions the project's default Cloud Firestore instance.
So, since your project's default Cloud Firestore instance is already provisioned, google_firestore_database will error if you try to explicitly provision that default instance again.
Once the project's default Cloud Firestore instance is provisioned, you cannot "re-provision" it or change its location. Note that the provisioned database instance is in Datastore mode, which means that it's not accessible to Firebase SDKs, authentication, or Firebase Security Rules. If you want to use Cloud Firestore with these Firebase services, then you'll need to empty the database and then change its database type in the Google Cloud console.
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2025-05-07 UTC."],[],[]]