Stay organized with collectionsSave and categorize content based on your preferences.
Firebase is beginning to supportTerraform.
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.tffile) which
specifies the infrastructure you want to provision (that is, resources you
want to provision and the services you want to enable).
Usinggcloud CLIcommands that interface with Terraform to
provision the infrastructure specified in the.tffile.
Delete and modify existing infrastructure using Terraform.
Manage product-specific configuration and tasks using Terraform, like:
EnablingFirebase Authenticationsign-in providers.
CreatingCloud Storagebuckets or database instances and deployingFirebase Security Rulesfor them.
CreatingFirebase App Hostingbackends, builds, and other
related resources.
You can use standard Terraform config files and commands to accomplish all these
tasks. And to help you with this, we've providedsample Terraform config filesfor 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 Terraformand 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 theFirebaseconsole
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 aGoogle Cloudorganization,
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):
Aprovidersetup is required no matter which Firebase products or services are
involved.
Create a Terraform config file (likemain.tffile) in your local
directory.
In this guide, you'll use this config file to specify both theprovidersetup 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 theprovidersetup
You have the following options for how to include aprovidersetup to
the rest of your Terraform configuration:
Option 1:Include it at the top of a single Terraform.tfconfig
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.tffile (like aprovider.tffile), apart from the.tffile where you specify infrastructure to
create (like amain.tffile).
Use this option if you're part of a larger team that needs to
standardize setup.
When running Terraform commands, both theprovider.tffile and themain.tffile must be in the same directory.
Include the followingprovidersetup at the top of themain.tffile.
You must use thegoogle-betaprovider 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 usingresourceblocks
In your Terraform config file (for this guide, yourmain.tffile), 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 allFirebase resources that support Terraform.
Open yourmain.tffile.
Under theprovidersetup, include the following config ofresourceblocks.
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 theproject nameproject_id="project-id-for-new-project"// learn more about theproject 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 theFirebase-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 therelationship 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 therelationship 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 anapp's display namepackage_name="awesome.package.name"# learn more about anapp'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 yourmain.tffile, run the following commands from the same directory as yourmain.tffile.
For detailed information about these commands, see theTerraform 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 yourmain.tffile 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 byfiling an issue in the GitHub repo.
google_identity_platform_config—
enableGoogle Cloud Identity Platform(GCIP) (which is the backend forFirebase Authentication)
and provide project-level authentication settings
The project in which Terraform will enable GCIP and/orFirebase Authenticationmust be on the Blaze pricing plan (that is, the project must have an
associatedCloud Billingaccount). You can do this programmatically by
setting thebilling_accountattribute in thegoogle_projectresource.
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.
Configuring multi-factor authentication (MFA) via Terraform
Firebase App Hosting
google_firebase_app_hosting_backend— create and manage aFirebase App Hostingbackend, including its GitHub
repository connection and live branch for continuous deployment.
Sample Terraform config files for common use cases
Set upFirebase Authenticationwith
GCIP
This config creates a newGoogle Cloudproject,
associates the project with aCloud Billingaccount (the Blaze pricing plan
is required forFirebase Authenticationwith GCIP),
enables Firebase services for the project,
sets upFirebase Authenticationwith GCIP,
and registers three different app types with the project.
Note that enabling GCIP is required to set upFirebase Authenticationvia 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 aFirebase Data Connectservice
This config creates a newGoogle Cloudproject,
enables Firebase services for the project, and
provisions aData Connectservice.
# 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
defaultFirebase Realtime Databaseinstance
This config creates a newGoogle Cloudproject,
enables Firebase services for the project,
provisions the project's defaultRealtime Databaseinstance,
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 newGoogle Cloudproject,
associates the project with aCloud Billingaccount (the Blaze pricing plan
is required for multipleRealtime Databaseinstances),
enables Firebase services for the project,
provisions multipleRealtime Databaseinstances
(including the project's defaultRealtime Databaseinstance),
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 defaultCloud Firestoreinstance
This config creates a newGoogle Cloudproject,
enables Firebase services for the project,
provisions the project's defaultCloud Firestoreinstance,
and registers three different app types with the project.
It also provisionsFirebase Security Rulesfor the defaultCloud Firestoreinstance,
creates aCloud Firestoreindex,
and adds aCloud Firestoredocument 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 ofCloud FirestoreSecurity Rulesthat should be in a local file
namedfirestore.rules.
This config creates a newGoogle Cloudproject,
associates the project with aCloud Billingaccount (the Blaze pricing plan
is required for additional buckets),
enables Firebase services for the project,
provisions additional, non-defaultCloud Storagebuckets,
and registers three different app types with the project.
It also provisionsFirebase Security Rulesfor eachCloud Storagebucket,
and uploads a file to one of theCloud Storagebuckets.
# 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 ofCloud StorageSecurity Rulesthat should be in a local file
namedstorage.rules.
This config creates a newGoogle Cloudproject,
enables Firebase services for the project, and
sets up and enables enforcement ofFirebase App CheckforCloud Firestoreso 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 aFirebase Extension
This config creates a newGoogle Cloudproject,
enables Firebase services for the project, and
installs a new instance of aFirebase Extensionin 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 protectFirebase AI Logic
This config creates a newGoogle Cloudproject,
enables Firebase services for the project, includingFirebase AI Logic, and
sets up and enables enforcement ofFirebase App CheckforFirebase AI Logicso 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"}}}
Manually provision anApp Hostingbackend
This configuration demonstrates how to manually provision anApp Hostingbackend using Terraform. This approach gives you fine-grained control over the
resources created, but requires you to define each resource individually. This
is useful when you need to customize the backend beyond the default options.
# Creates a new Google Cloud project.resource"google_project""apphosting"{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 App Hosting).billing_account="000000-000000-000000"}# Enables required APIs.resource"google_project_service""services"{provider=google-beta.no_user_project_overrideproject=google_project.apphosting.project_idfor_each=toset(["cloudresourcemanager.googleapis.com","firebase.googleapis.com","firebaseapphosting.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""apphosting"{provider=google-betaproject=google_project.apphosting.project_iddepends_on=[google_project_service.services]}# Creates a Firebase Web App in the new project created earlier.resource"google_firebase_web_app""apphosting"{provider=google-betaproject=google_firebase_project.apphosting.projectdisplay_name="My web app"}# Creates a Firebase App Hosting Backendresource"google_firebase_app_hosting_backend""example"{provider=google-betaproject=google_firebase_project.apphosting.project# Choose the region closest to your userslocation="name-of-region-for-service"backend_id="name-of-backend-for-service"app_id=google_firebase_web_app.apphosting.app_iddisplay_name="My Backend"serving_locality="GLOBAL_ACCESS" # or "REGIONAL_STRICT"service_account=google_service_account.service_account.email}# Creates the service account for Firebase App Hostingresource"google_service_account""service_account"{provider=google-betaproject=google_firebase_project.apphosting.project# Must be firebase-app-hosting-computeaccount_id="firebase-app-hosting-compute"display_name="Firebase App Hosting compute service account"# Do not throw if already existscreate_ignore_already_exists=true}# Adds permission to the App Hosting service accountresource"google_project_iam_member""app_hosting_sa"{provider=google-betaproject=google_firebase_project.apphosting.projectfor_each=toset(["roles/firebase.sdkAdminServiceAgent","roles/firebaseapphosting.computeRunner"])role=each.keymember=google_service_account.service_account.member}# Creates a Buildresource"google_firebase_app_hosting_build""example"{provider=google-betaproject=google_firebase_app_hosting_backend.example.projectlocation=google_firebase_app_hosting_backend.example.locationbackend=google_firebase_app_hosting_backend.example.backend_idbuild_id="my-build"source{container{# TODO: use your own imageimage="us-docker.pkg.dev/cloudrun/container/hello"}}}# Rolls out the Buildresource"google_firebase_app_hosting_traffic""example"{provider=google-betaproject=google_firebase_app_hosting_backend.example.projectlocation=google_firebase_app_hosting_backend.example.locationbackend=google_firebase_app_hosting_backend.example.backend_idtarget{splits{build=google_firebase_app_hosting_build.example.namepercent=100}}}
Provision anApp Hostingbackend using GitHub
This configuration demonstrates how to provision anApp Hostingbackend
using application code stored in a GitHub repository. This approach allows you
to manage and update your infrastructure through GitHub pull requests and CI/CD
pipelines according to the typical model forApp Hostingdeployments.
# Creates a new Google Cloud project.resource"google_project""apphosting"{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 App Hosting).billing_account="000000-000000-000000"}# Enables required APIs.resource"google_project_service""services"{provider=google-beta.no_user_project_overrideproject=google_project.apphosting.project_idfor_each=toset(["cloudresourcemanager.googleapis.com","firebase.googleapis.com","firebaseapphosting.googleapis.com","serviceusage.googleapis.com","developerconnect.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""apphosting"{provider=google-betaproject=google_project.apphosting.project_iddepends_on=[google_project_service.services]}# Creates a Firebase Web App in the new project created earlier.resource"google_firebase_web_app""apphosting"{provider=google-betaproject=google_firebase_project.apphosting.projectdisplay_name="My web app"}### Setting up Firebase App Hosting #### Creates a Firebase App Hosting Backendresource"google_firebase_app_hosting_backend""example"{provider=google-betaproject=google_firebase_project.apphosting.project# Choose the region closest to your userslocation="name-of-region-for-service"backend_id="name-of-backend-for-service"app_id=google_firebase_web_app.apphosting.app_iddisplay_name="My Backend"serving_locality="GLOBAL_ACCESS" # or "REGIONAL_STRICT"service_account=google_service_account.service_account.emailcodebase{repository=google_developer_connect_git_repository_link.my-repository.nameroot_directory="/"}}# Creates the service account for Firebase App Hostingresource"google_service_account""service_account"{provider=google-betaproject=google_firebase_project.apphosting.project# Must be firebase-app-hosting-computeaccount_id="firebase-app-hosting-compute"display_name="Firebase App Hosting compute service account"# Do not throw if already existscreate_ignore_already_exists=true}# Adds permission to the App Hosting service accountresource"google_project_iam_member""app_hosting_sa"{provider=google-betaproject=google_firebase_project.apphosting.projectfor_each=toset(["roles/developerconnect.readTokenAccessor","roles/firebase.sdkAdminServiceAgent","roles/firebaseapphosting.computeRunner"])role=each.keymember=google_service_account.service_account.member}# Configures auto rollout from GitHubresource"google_firebase_app_hosting_traffic""example"{provider=google-betaproject=google_firebase_app_hosting_backend.example.projectlocation=google_firebase_app_hosting_backend.example.locationbackend=google_firebase_app_hosting_backend.example.backend_idrollout_policy{codebase_branch="main"# Or another branch}}###### Setting up a connection to GitHub #### Provisions Service Agent for Developer Connectresource"google_project_service_identity""devconnect-p4sa"{provider=google-betaproject=google_firebase_project.apphosting.projectservice="developerconnect.googleapis.com"}# Adds permission to Developer Connect Service Agent to manager GitHub tokensresource"google_project_iam_member""devconnect-secret"{provider=google-betaproject=google_firebase_project.apphosting.projectrole="roles/secretmanager.admin"member=google_project_service_identity.devconnect-p4sa.member}# Connects to a GitHub accountresource"google_developer_connect_connection""my-connection"{provider=google-betaproject=google_firebase_project.apphosting.project# Must match the google_firebase_app_hosting_backend's locationlocation="name-of-region-for-service"# Must be `firebase-app-hosting-github-oauth`connection_id="firebase-app-hosting-github-oauth"github_config{github_app="FIREBASE"}depends_on=[google_project_iam_member.devconnect-secret]}# Follow the next steps to set up the GitHub connection# Tip: Run terraform refresh to obtain the outputoutput"next_steps"{description="Follow the action_uri if present to continue setup"value=google_developer_connect_connection.my-connection.installation_state}# Links a GitHub repo to the projectresource"google_developer_connect_git_repository_link""my-repository"{provider=google-betaproject=google_firebase_project.apphosting.projectlocation=google_developer_connect_connection.my-connection.locationgit_repository_link_id="my-repo-id"parent_connection=google_developer_connect_connection.my-connection.connection_idclone_uri="https://github.com/myuser/myrepo.git"}###
Troubleshooting and FAQ
You want
to learn more about all the different project-related attributes (likeprojectanduser_project_override)
This guide uses the following Terraform attributes when working with "projects".
projectwithin aresourceblock
Recommended: whenever possible, include theprojectattribute within eachresourceblock
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 aboutproject.
user_project_overridewithin theproviderblock
For provisioning most resources, you should useuser_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 useuser_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 rungcloud CLIcommands 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 theFirebaseconsole. 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 theFirebaseconsoleand accept the
Firebase ToS as part of project creation. You can immediately delete this
project viaProject Settingsin the console.
After runningterraform apply, you get this error:generic::permission_denied: IAM authority does not have the
permission.
Wait a few minutes, and then try runningterraform applyagain.
The
creation of a resource failed, but when you runterraform applyagain, it saysALREADY_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 runningterraform import. Then try runningterraform applyagain.
When working withCloud 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 runningterraform applyagain.
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 theresourceblock:
Make sure that you have specified a value for theprojectattribute.
Make sure that you're using the provider withuser_project_override = true(no alias), which in the Firebase samples isgoogle-beta.
When creating a
newGoogle Cloudproject, 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 theprojects.getREST API.
The project associated with that ID exists correctly under the current user. A
possible cause for the error could be that a previousterraform applygot
interrupted.
To resolve:Run the following commands: terraform import google_project.defaultPROJECT_IDand then terraform import google_firebase_project.defaultPROJECT_ID
Why do you
need to provision the defaultCloud Firestoreinstance before the defaultCloud Storagebucket?
If you provisioned your defaultCloud Storagebucket (viagoogle_app_engine_application)beforeyou try to provision your
defaultCloud Firestoreinstance, then you'll find that your
defaultCloud Firestoreinstance has already been provisioned. Note that the
provisioned database instance is in Datastore mode, which means that it'snotaccessible to Firebase SDKs, authentication, orFirebase Security Rules. If you want to useCloud Firestorewith these Firebase services, then you'll need to empty the
database and then change its database type in theGoogle Cloudconsole.
When
trying to provisionCloud Storage(viagoogle_app_engine_application) and then your defaultCloud Firestoreinstance, 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 defaultCloud Storagebucket (viagoogle_app_engine_application) and the project doesn't yet have its defaultCloud Firestoreinstance, thengoogle_app_engine_applicationautomatically
provisions the project's defaultCloud Firestoreinstance.
So, since your project's defaultCloud Firestoreinstance isalreadyprovisioned,google_firestore_databasewill error if you try to explicitly
provision that default instance again.
Once the project's defaultCloud Firestoreinstance 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'snotaccessible to
Firebase SDKs, authentication, orFirebase Security Rules. If you want to useCloud Firestorewith these Firebase services, then you'll need to empty the database and then
change its database type in theGoogle Cloudconsole.
[[["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-09-05 UTC."],[],[],null,[]]