Terraform wird in Firebase nach und nach unterstützt.
Wenn Sie in einem Team arbeiten, das das Erstellen von Firebase-Projekten mit bestimmten bereitgestellten Ressourcen und aktivierten Diensten automatisieren und standardisieren möchte, ist die Verwendung von Terraform mit Firebase eine gute Lösung.
Der grundlegende Workflow für die Verwendung von Terraform mit Firebase umfasst Folgendes:
Erstellen und Anpassen einer Terraform-Konfigurationsdatei (.tf-Datei), in der die zu bereitstellende Infrastruktur angegeben ist (d. h. die zu bereitstellenden Ressourcen und die zu aktivierenden Dienste).
Mit gcloud CLI-Befehlen, die mit Terraform interagieren, um die in der .tf-Datei angegebene Infrastruktur bereitzustellen.
Vorhandene Infrastruktur mit Terraform löschen und ändern
Produktspezifische Konfiguration und Aufgaben mit Terraform verwalten, z. B.:
Anbieter für Anmeldungen bei Firebase Authentication aktivieren
Cloud Storage-Buckets oder Datenbankinstanzen erstellen und Firebase Security Rules für sie bereitstellen
Sie können Standard-Terraform-Konfigurationsdateien und ‑Befehle verwenden, um alle diese Aufgaben auszuführen. Wir haben Beispiel-Terraform-Konfigurationsdateien für einige gängige Anwendungsfälle zusammengestellt.
Allgemeiner Ablauf für die Verwendung von Terraform mit Firebase
Voraussetzungen
Dieser Leitfaden ist eine Einführung in die Verwendung von Terraform mit Firebase. Daher wird ein grundlegendes Terraform-Wissen vorausgesetzt. Bevor du mit diesem Workflow beginnst, musst du die folgenden Voraussetzungen erfüllen.
Anforderungen an Nutzerkonten und Dienstkonten ansehen
Wenn Sie ein Nutzerkonto verwenden, müssen Sie die Firebase-Nutzungsbedingungen akzeptiert haben. Sie haben die Firebase-Nutzungsbedingungen akzeptiert, wenn Sie ein Firebase-Projekt in der Firebase Console aufrufen können.
Damit Terraform bestimmte Aktionen ausführen kann (z. B. Projekte erstellen), müssen folgende Voraussetzungen erfüllt sein:
Das Nutzer- oder Dienstkonto muss für diese Aktionen den entsprechenden IAM-Zugriff haben.
Wenn das Nutzer- oder Dienstkonto zu einer Google Cloud-Organisation gehört, müssen die Organisationsrichtlinien dem Konto erlauben, diese Aktionen auszuführen.
Schritt 1:Terraform-Konfigurationsdatei erstellen und anpassen
Eine Terraform-Konfigurationsdatei benötigt zwei Hauptabschnitte, die unten ausführlich beschrieben werden:
Die Einrichtung von provider ist unabhängig von den verwendeten Firebase-Produkten oder ‑Diensten erforderlich.
Erstellen Sie eine Terraform-Konfigurationsdatei (z. B. eine main.tf-Datei) in Ihrem lokalen Verzeichnis.
In dieser Anleitung verwenden Sie diese Konfigurationsdatei, um sowohl die provider-Einrichtung als auch die gesamte Infrastruktur anzugeben, die Terraform erstellen soll. Sie haben jedoch verschiedene Möglichkeiten, die Anbietereinrichtung einzubinden.
Optionen zum Einbeziehen der provider-Einrichtung ansehen
Sie haben folgende Möglichkeiten, eine provider-Einrichtung in die restliche Terraform-Konfiguration aufzunehmen:
Option 1:Fügen Sie sie oben in einer einzelnen Terraform-.tf-Konfigurationsdatei ein (wie in diesem Leitfaden gezeigt).
Verwenden Sie diese Option, wenn Sie gerade erst mit Terraform beginnen oder Terraform mit Firebase ausprobieren.
Option 2:Fügen Sie die Definition in einer separaten .tf-Datei (z. B. einer provider.tf-Datei) ein, die nicht mit der .tf-Datei identisch ist, in der Sie die zu erstellende Infrastruktur angeben (z. B. eine main.tf-Datei).
Verwenden Sie diese Option, wenn Sie Teil eines größeren Teams sind, das die Einrichtung standardisieren muss.
Wenn Sie Terraform-Befehle ausführen, müssen sich sowohl die Datei provider.tf als auch die Datei main.tf im selben Verzeichnis befinden.
Fügen Sie die folgende provider-Einrichtung oben in die Datei main.tf ein.
Sie müssen den Anbieter google-beta verwenden, da dies ein Betarelease der Verwendung von Firebase mit Terraform ist. Seien Sie bei der Verwendung in der Produktion vorsichtig.
# Terraform configuration to set up providers by version.
terraform {
required_providers {
google-beta = {
source = "hashicorp/google-beta"
version = "~> 5.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
}
Weitere Informationen zu den verschiedenen Arten von projektbezogenen Attributen (einschließlich des in diesem Leitfaden als „Quota-Check-Projekt“ bezeichneten Projekts) bei der Verwendung von Terraform mit Firebase
Fahren Sie mit dem nächsten Abschnitt fort, um die Konfigurationsdatei fertigzustellen und anzugeben, welche Infrastruktur erstellt werden soll.
Mit resource-Blöcken angeben, welche Infrastruktur erstellt werden soll
In Ihrer Terraform-Konfigurationsdatei (in diesem Leitfaden die main.tf-Datei) müssen Sie die gesamte Infrastruktur angeben, die Terraform erstellen soll. Das sind alle Ressourcen, die Sie bereitstellen möchten, und alle Dienste, die Sie aktivieren möchten. In diesem Leitfaden finden Sie eine vollständige Liste aller Firebase-Ressourcen, die Terraform unterstützen.
Öffnen Sie Ihre main.tf-Datei.
Fügen Sie in der provider-Einrichtung die folgende Konfiguration von resource-Blöcken ein.
In diesem einfachen Beispiel wird ein neues Firebase-Projekt erstellt und dann eine Firebase-Android-App in diesem Projekt.
# 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_override
name = "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_override
project = google_project.default.project_id
for_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-beta
project = 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-beta
project = google_project.default.project_id
display_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,
]
}
Eine ausführlich kommentierte Version dieser Beispielkonfigurationsdatei ansehen
Wenn Sie mit der Infrastruktur von Projekten und Apps als Ressourcen nicht vertraut sind, lesen Sie die folgende Dokumentation:
# 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 project
provider = google-beta.no_user_project_override
name = "Project Display Name" // learn more about the project name
project_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 APIS
provider = google-beta.no_user_project_override
project = google_project.default.project_id
for_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 on
provider = google-beta
project = 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-beta
project = google_project.default.project_id
display_name = "My Awesome Android app" # learn more about an app's display name
package_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,
]
}
Schritt 2:Terraform-Befehle ausführen, um die angegebene Infrastruktur zu erstellen
Führen Sie die folgenden Befehle im selben Verzeichnis wie die Datei main.tf aus, um die in der Datei main.tf angegebenen Ressourcen bereitzustellen und die Dienste zu aktivieren.
Ausführliche Informationen zu diesen Befehlen finden Sie in der Terraform-Dokumentation.
Wenn Sie zum ersten Mal Terraform-Befehle in diesem Verzeichnis ausführen, müssen Sie das Konfigurationsverzeichnis initialisieren und den Google Terraform-Anbieter installieren. Führen Sie dazu den folgenden Befehl aus:
terraform init
Erstellen Sie die in der main.tf-Datei angegebene Infrastruktur mit dem folgenden Befehl:
terraform apply
Prüfen Sie, ob alles wie erwartet bereitgestellt oder aktiviert wurde:
Option 1:Führen Sie den folgenden Befehl aus, um die Konfiguration im Terminal zu sehen:
terraform show
Option 2:Rufen Sie Ihr Firebase-Projekt in der Firebase Console auf.
Firebase-Ressourcen mit Terraform-Unterstützung
Die folgenden Firebase- und Google-Ressourcen werden von Terraform unterstützt. Und wir fügen laufend weitere Ressourcen hinzu. Wenn Sie die Ressource, die Sie mit Terraform verwalten möchten, nicht sehen, sehen Sie bald noch einmal nach, ob sie verfügbar ist, oder erstellen Sie ein Problem im GitHub-Repository, um sie anzufordern.
Firebase-Projekt- und App-Verwaltung
google_firebase_project: Firebase-Dienste in einem vorhandenen Google Cloud-Projekt aktivieren
google_identity_platform_config: Aktivieren Sie Google Cloud Identity Platform (GCIP), das Backend für Firebase Authentication, und geben Sie Authentifizierungseinstellungen auf Projektebene an.
Wenn Sie Firebase Authentication über Terraform konfigurieren möchten, müssen Sie GCIP aktivieren. In der Beispieldatei .tf finden Sie Informationen zum Einrichten von Firebase Authentication.
Für das Projekt, in dem Terraform GCIP und/oder Firebase Authentication aktiviert, muss der Blaze-Preisplan verwendet werden. Das bedeutet, dass dem Projekt ein Cloud Billing-Konto zugewiesen sein muss. Das geht programmatisch, indem du das Attribut billing_account in der google_project-Ressource festlegst.
Diese Ressource ermöglicht auch mehr Konfigurationen, z. B. lokale Anmeldemethoden wie anonyme, E-Mail-/Passwort- und Telefonauthentifizierung sowie Blockierfunktionen und autorisierte Domains.
Firebase Realtime Database Security Rules über Terraform bereitstellen (Informationen zum Bereitstellen dieser Rules mit anderen Tools, einschließlich programmatischer Optionen)
google_firestore_document: Cloud Firestore-Instanz mit einem bestimmten Dokument in einer Sammlung initialisieren
Wichtig:Verwenden Sie in diesem Seed-Dokument keine echten Endnutzer- oder Produktionsdaten.
Cloud Storage for Firebase
google_firebase_storage_bucket: Mit diesem Befehl können Sie einen vorhandenen Cloud Storage-Bucket für Firebase SDKs, Authentifizierung und Firebase Security Rules zugänglich machen.
Beispiel-Terraform-Konfigurationsdateien für gängige Anwendungsfälle
Firebase Authentication mit GCIP einrichten
Mit dieser Konfiguration wird ein neues Google Cloud-Projekt erstellt, das Projekt mit einem Cloud Billing-Konto verknüpft (der Blaze-Preisplan ist für Firebase Authentication mit GCIP erforderlich), Firebase-Dienste für das Projekt aktiviert, Firebase Authentication mit GCIP eingerichtet und drei verschiedene App-Typen beim Projekt registriert.
Beachten Sie, dass die GCIP aktiviert sein muss, um Firebase Authentication über Terraform einzurichten.
# Creates a new Google Cloud project.
resource "google_project" "auth" {
provider = google-beta.no_user_project_override
folder_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"
# Required for the project to display in a list of Firebase projects.
labels = {
"firebase" = "enabled"
}
}
# Enables required APIs.
resource "google_project_service" "auth" {
provider = google-beta.no_user_project_override
project = google_project.auth.project_id
for_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-beta
project = google_project.auth.project_id
depends_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-beta
project = google_project.auth.project_id
# Auto-deletes anonymous users
autodelete_anonymous_users = true
# Configures local sign-in methods, like anonymous, email/password, and phone authentication.
sign_in {
allow_duplicate_emails = true
anonymous {
enabled = true
}
email {
enabled = true
password_required = false
}
phone_number {
enabled = true
test_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 = true
access_token = true
id_token = true
}
}
# Configures a temporary quota for new signups for anonymous, email/password, and phone number.
quota {
sign_up_quota_config {
quota = 1000
start_time = ""
quota_duration = "7200s"
}
}
# Configures authorized domains.
authorized_domains = [
"localhost",
"${google_project.auth.project_id}.firebaseapp.com",
"${google_project.auth.project_id}.web.app",
]
# Wait for identitytoolkit.googleapis.com to be enabled before initializing Authentication.
depends_on = [
google_project_service.auth,
]
}
# Creates a Firebase Android App in the new project created above.
resource "google_firebase_android_app" "auth" {
provider = google-beta
project = google_project.auth.project_id
display_name = "My Android app"
package_name = "android.package.name"
# Wait for Firebase to be enabled in the Google Cloud project before creating this App.
depends_on = [
google_firebase_project.auth,
]
}
# Creates a Firebase Apple-platforms App in the new project created above.
resource "google_firebase_apple_app" "auth" {
provider = google-beta
project = google_project.auth.project_id
display_name = "My Apple app"
bundle_id = "apple.app.12345"
# Wait for Firebase to be enabled in the Google Cloud project before creating this App.
depends_on = [
google_firebase_project.auth,
]
}
# Creates a Firebase Web App in the new project created above.
resource "google_firebase_web_app" "auth" {
provider = google-beta
project = google_project.auth.project_id
display_name = "My Web app"
# The other App types (Android and Apple) use "DELETE" by default.
# Web apps don't use "DELETE" by default due to backward-compatibility.
deletion_policy = "DELETE"
# Wait for Firebase to be enabled in the Google Cloud project before creating this App.
depends_on = [
google_firebase_project.auth,
]
}
Mit dieser Konfiguration wird ein neues Google Cloud-Projekt erstellt, Firebase-Dienste für das Projekt aktiviert, die Standard-Realtime Database-Instanz des Projekts bereitgestellt und drei verschiedene App-Typen beim Projekt registriert.
# Creates a new Google Cloud project.
resource "google_project" "rtdb" {
provider = google-beta.no_user_project_override
folder_id = "folder-id-for-new-project"
name = "Project Display Name"
project_id = "project-id-for-new-project"
# Required for the project to display in a list of Firebase projects.
labels = {
"firebase" = "enabled"
}
}
# Enables required APIs.
resource "google_project_service" "rtdb" {
provider = google-beta.no_user_project_override
project = google_project.rtdb.project_id
for_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-beta
project = google_project.rtdb.project_id
}
# Provisions the default Realtime Database default instance.
resource "google_firebase_database_instance" "database" {
provider = google-beta
project = google_project.rtdb.project_id
# See available locations: https://firebase.google.com/docs/database/locations
region = "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"
# Wait for Firebase to be enabled in the Google Cloud project before initializing Realtime Database.
depends_on = [
google_firebase_project.rtdb,
]
}
# Creates a Firebase Android App in the new project created above.
resource "google_firebase_android_app" "rtdb" {
provider = google-beta
project = google_project.rtdb.project_id
display_name = "My Android app"
package_name = "android.package.name"
# Wait for Firebase to be enabled in the Google Cloud project before creating this App.
depends_on = [
google_firebase_project.rtdb,
]
}
# Creates a Firebase Apple-platforms App in the new project created above.
resource "google_firebase_apple_app" "rtdb" {
provider = google-beta
project = google_project.rtdb.project_id
display_name = "My Apple app"
bundle_id = "apple.app.12345"
# Wait for Firebase to be enabled in the Google Cloud project before creating this App.
depends_on = [
google_firebase_project.rtdb,
]
}
# Creates a Firebase Web App in the new project created above.
resource "google_firebase_web_app" "rtdb" {
provider = google-beta
project = google_project.rtdb.project_id
display_name = "My Web app"
# The other App types (Android and Apple) use "DELETE" by default.
# Web apps don't use "DELETE" by default due to backward-compatibility.
deletion_policy = "DELETE"
# Wait for Firebase to be enabled in the Google Cloud project before creating this App.
depends_on = [
google_firebase_project.rtdb,
]
}
Mehrere Firebase Realtime Database-Instanzen bereitstellen
Mit dieser Konfiguration wird ein neues Google Cloud-Projekt erstellt, das Projekt mit einem Cloud Billing-Konto verknüpft (der Blaze-Tarif ist für mehrere Realtime Database-Instanzen erforderlich), Firebase-Dienste für das Projekt aktiviert, mehrere Realtime Database-Instanzen bereitgestellt (einschließlich der Standard-Realtime Database-Instanz des Projekts) und drei verschiedene App-Typen beim Projekt registriert.
# Creates a new Google Cloud project.
resource "google_project" "rtdb-multi" {
provider = google-beta.no_user_project_override
folder_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"
# Required for the project to display in a list of Firebase projects.
labels = {
"firebase" = "enabled"
}
}
# Enables required APIs.
resource "google_project_service" "rtdb-multi" {
provider = google-beta.no_user_project_override
project = google_project.rtdb-multi.project_id
for_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-beta
project = google_project.rtdb-multi.project_id
}
# Provisions the default Realtime Database default instance.
resource "google_firebase_database_instance" "database-default" {
provider = google-beta
project = google_project.rtdb-multi.project_id
# See available locations: https://firebase.google.com/docs/database/locations
region = "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"
# Wait for Firebase to be enabled in the Google Cloud project before initializing Realtime Database.
depends_on = [
google_firebase_project.rtdb-multi,
]
}
# Provisions an additional Realtime Database instance.
resource "google_firebase_database_instance" "database-additional" {
provider = google-beta
project = google_project.rtdb-multi.project_id
# 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"
# Wait for Firebase to be enabled in the Google Cloud project before initializing Realtime Database.
depends_on = [
google_firebase_project.rtdb-multi,
]
}
# Creates a Firebase Android App in the new project created above.
resource "google_firebase_android_app" "rtdb-multi" {
provider = google-beta
project = google_project.rtdb-multi.project_id
display_name = "My Android app"
package_name = "android.package.name"
# Wait for Firebase to be enabled in the Google Cloud project before creating this App.
depends_on = [
google_firebase_project.rtdb-multi,
]
}
# Creates a Firebase Apple-platforms App in the new project created above.
resource "google_firebase_apple_app" "rtdb-multi" {
provider = google-beta
project = google_project.rtdb-multi.project_id
display_name = "My Apple app"
bundle_id = "apple.app.12345"
# Wait for Firebase to be enabled in the Google Cloud project before creating this App.
depends_on = [
google_firebase_project.rtdb-multi,
]
}
# Creates a Firebase Web App in the new project created above.
resource "google_firebase_web_app" "rtdb-multi" {
provider = google-beta
project = google_project.rtdb-multi.project_id
display_name = "My Web app"
# The other App types (Android and Apple) use "DELETE" by default.
# Web apps don't use "DELETE" by default due to backward-compatibility.
deletion_policy = "DELETE"
# Wait for Firebase to be enabled in the Google Cloud project before creating this App.
depends_on = [
google_firebase_project.rtdb-multi,
]
}
Standard-Cloud Firestore-Instanz bereitstellen
Mit dieser Konfiguration wird ein neues Google Cloud-Projekt erstellt, Firebase-Dienste für das Projekt aktiviert, die Standard-Cloud Firestore-Instanz des Projekts bereitgestellt und drei verschiedene App-Typen beim Projekt registriert.
Außerdem wird Firebase Security Rules für die Standardinstanz von Cloud Firestore bereitgestellt, ein Cloud Firestore-Index erstellt und ein Cloud Firestore-Dokument mit Startdaten hinzugefügt.
# Creates a new Google Cloud project.
resource "google_project" "firestore" {
provider = google-beta.no_user_project_override
folder_id = "folder-id-for-new-project"
name = "Project Display Name"
project_id = "project-id-for-new-project"
# Required for the project to display in a list of Firebase projects.
labels = {
"firebase" = "enabled"
}
}
# Enables required APIs.
resource "google_project_service" "firestore" {
provider = google-beta.no_user_project_override
project = google_project.firestore.project_id
for_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-beta
project = google_project.firestore.project_id
}
# Provisions the Firestore database instance.
resource "google_firestore_database" "firestore" {
provider = google-beta
project = google_project.firestore.project_id
name = "(default)"
# See available locations: https://firebase.google.com/docs/firestore/locations
location_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"
# Wait for Firebase to be enabled in the Google Cloud project before initializing Firestore.
depends_on = [
google_firebase_project.firestore,
]
}
# Creates a ruleset of Firestore Security Rules from a local file.
resource "google_firebaserules_ruleset" "firestore" {
provider = google-beta
project = google_project.firestore.project_id
source {
files {
name = "firestore.rules"
# Write security rules in a local file named "firestore.rules".
# Learn more: https://firebase.google.com/docs/firestore/security/get-started
content = file("firestore.rules")
}
}
# Wait for Firestore to be provisioned before creating this ruleset.
depends_on = [
google_firestore_database.firestore,
]
}
# Releases the ruleset for the Firestore instance.
resource "google_firebaserules_release" "firestore" {
provider = google-beta
name = "cloud.firestore" # must be cloud.firestore
ruleset_name = google_firebaserules_ruleset.firestore.name
project = google_project.firestore.project_id
# Wait for Firestore to be provisioned before releasing the ruleset.
depends_on = [
google_firestore_database.firestore,
]
}
# Adds a new Firestore index.
resource "google_firestore_index" "indexes" {
provider = google-beta
project = google_project.firestore.project_id
collection = "quiz"
query_scope = "COLLECTION"
fields {
field_path = "question"
order = "ASCENDING"
}
fields {
field_path = "answer"
order = "ASCENDING"
}
# Wait for Firestore to be provisioned before adding this index.
depends_on = [
google_firestore_database.firestore,
]
}
# 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-beta
project = google_project.firestore.project_id
collection = "quiz"
document_id = "question-1"
fields = "{\"question\":{\"stringValue\":\"Favorite Database\"},\"answer\":{\"stringValue\":\"Firestore\"}}"
# Wait for Firestore to be provisioned before adding this document.
depends_on = [
google_firestore_database.firestore,
]
}
# Creates a Firebase Android App in the new project created above.
resource "google_firebase_android_app" "firestore" {
provider = google-beta
project = google_project.firestore.project_id
display_name = "My Android app"
package_name = "android.package.name"
# Wait for Firebase to be enabled in the Google Cloud project before creating this App.
depends_on = [
google_firebase_project.firestore,
]
}
# Creates a Firebase Apple-platforms App in the new project created above.
resource "google_firebase_apple_app" "firestore" {
provider = google-beta
project = google_project.firestore.project_id
display_name = "My Apple app"
bundle_id = "apple.app.12345"
# Wait for Firebase to be enabled in the Google Cloud project before creating this App.
depends_on = [
google_firebase_project.firestore,
]
}
# Creates a Firebase Web App in the new project created above.
resource "google_firebase_web_app" "firestore" {
provider = google-beta
project = google_project.firestore.project_id
display_name = "My Web app"
# The other App types (Android and Apple) use "DELETE" by default.
# Web apps don't use "DELETE" by default due to backward-compatibility.
deletion_policy = "DELETE"
# Wait for Firebase to be enabled in the Google Cloud project before creating this App.
depends_on = [
google_firebase_project.firestore,
]
}
Dies ist die Regelsammlung von Cloud Firestore Security Rules, die sich in einer lokalen Datei namens firestore.rules befinden sollte.
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
allow read: if request.auth != null;
allow create: if request.auth != null;
allow update: if request.auth != null;
}
}
Standard-Cloud Storage-Bucket bereitstellen
Zusätzliche Cloud Storage-Buckets bereitstellen
Mit dieser Konfiguration wird ein neues Google Cloud-Projekt erstellt, das Projekt mit einem Cloud Billing-Konto verknüpft (der Blaze-Tarif ist für zusätzliche Buckets erforderlich), Firebase-Dienste für das Projekt aktiviert, zusätzliche, nicht standardmäßige Cloud Storage-Buckets bereitgestellt und drei verschiedene App-Typen beim Projekt registriert.
Außerdem wird Firebase Security Rules für jeden Cloud Storage-Bucket bereitgestellt und eine Datei in einen der Cloud Storage-Buckets hochgeladen.
# Creates a new Google Cloud project.
resource "google_project" "storage-multi" {
provider = google-beta.no_user_project_override
folder_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"
# Required for the project to display in a list of Firebase projects.
labels = {
"firebase" = "enabled"
}
}
# Enables required APIs.
resource "google_project_service" "storage-multi" {
provider = google-beta.no_user_project_override
project = google_project.storage-multi.project_id
for_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-beta
project = google_project.storage-multi.project_id
}
# Provisions a Cloud Storage bucket.
resource "google_storage_bucket" "bucket-1" {
provider = google-beta
project = google_project.storage-multi.project_id
name = "name-of-storage-bucket"
# See available locations: https://cloud.google.com/storage/docs/locations#available-locations
location = "name-of-region-for-bucket"
}
# Provisions an additional Cloud Storage bucket.
resource "google_storage_bucket" "bucket-2" {
provider = google-beta
project = google_project.storage-multi.project_id
name = "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-beta
project = google_project.storage-multi.project_id
bucket_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-beta
project = google_project.storage-multi.project_id
bucket_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-beta
project = google_project.storage-multi.project_id
source {
files {
# Write security rules in a local file named "storage.rules"
# Learn more: https://firebase.google.com/docs/storage/security/get-started
name = "storage.rules"
content = file("storage.rules")
}
}
# Wait for the Storage buckets to be provisioned before creating this ruleset.
depends_on = [
google_firebase_project.storage-multi,
]
}
# Releases the ruleset to the first Storage bucket.
resource "google_firebaserules_release" "bucket-1" {
provider = google-beta
name = "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_project.storage-multi.project_id
}
# Releases the ruleset to the additional Storage bucket.
resource "google_firebaserules_release" "bucket-2" {
provider = google-beta
name = "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_project.storage-multi.project_id
}
# 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-beta
name = "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-beta
project = google_project.storage-multi.project_id
display_name = "My Android app"
package_name = "android.package.name"
# Wait for Firebase to be enabled in the Google Cloud project before creating this App.
depends_on = [
google_firebase_project.storage-multi,
]
}
# Creates a Firebase Apple-platforms App in the new project created above.
resource "google_firebase_apple_app" "storage-multi" {
provider = google-beta
project = google_project.storage-multi.project_id
display_name = "My Apple app"
bundle_id = "apple.app.12345"
# Wait for Firebase to be enabled in the Google Cloud project before creating this App.
depends_on = [
google_firebase_project.storage-multi,
]
}
# Creates a Firebase Web App in the new project created above.
resource "google_firebase_web_app" "storage-multi" {
provider = google-beta
project = google_project.storage-multi.project_id
display_name = "My Web app"
# Wait for Firebase to be enabled in the Google Cloud project before creating this App.
depends_on = [
google_firebase_project.storage-multi,
]
}
Dies ist die Regelsammlung von Cloud Storage Security Rules, die sich in einer lokalen Datei namens storage.rules befinden sollte.
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
}
}
API-Ressource mit Firebase App Check schützen
Mit dieser Konfiguration wird ein neues Google Cloud-Projekt erstellt, Firebase-Dienste für das Projekt aktiviert und Firebase App Check für Cloud Firestore eingerichtet und erzwungen, sodass nur über Ihre Android-App darauf zugegriffen werden kann.
# Creates a new Google Cloud project.
resource "google_project" "appcheck" {
provider = google-beta.no_user_project_override
folder_id = "folder-id-for-new-project"
name = "Project Display Name"
project_id = "project-id-for-new-project"
# 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_override
project = google_project.appcheck.project_id
for_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-beta
project = google_project.appcheck.project_id
depends_on = [google_project_service.services]
}
# Provisions the Firestore database instance.
resource "google_firestore_database" "database" {
provider = google-beta
project = google_firebase_project.appcheck.project
name = "(default)"
# See available locations: https://firebase.google.com/docs/projects/locations#default-cloud-location
location_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"
# Wait for Firebase to be enabled in the Google Cloud project before initializing Firestore.
depends_on = [
google_firebase_project.appcheck,
]
}
# Creates a Firebase Android App in the new project created earlier.
resource "google_firebase_android_app" "appcheck" {
provider = google-beta
project = google_firebase_project.appcheck.project
display_name = "Play Integrity app"
package_name = "package.name.playintegrity"
sha256_hashes = [
# TODO: insert your Android app's SHA256 certificate
]
}
# It takes a while for App Check to recognize the new app
# If your app already exists, you don't have to wait 30 seconds.
resource "time_sleep" "wait_30s" {
depends_on = [google_firebase_android_app.appcheck]
create_duration = "30s"
}
# Register the Android app with the Play Integrity provider
resource "google_firebase_app_check_play_integrity_config" "appcheck" {
provider = google-beta
project = google_firebase_project.appcheck.project
app_id = google_firebase_android_app.appcheck.app_id
depends_on = [time_sleep.wait_30s, google_firestore_database.database]
lifecycle {
precondition {
condition = length(google_firebase_android_app.appcheck.sha256_hashes) > 0
error_message = "Provide a SHA-256 certificate on the Android App to use App Check"
}
}
}
# Enable enforcement of App Check for Firestore
resource "google_firebase_app_check_service_config" "firestore" {
provider = google-beta
project = google_firebase_project.appcheck.project
service_id = "firestore.googleapis.com"
depends_on = [google_project_service.services]
}
Instanz einer Firebase Extension installieren
Mit dieser Konfiguration wird ein neues Google Cloud-Projekt erstellt, Firebase-Dienste für das Projekt aktiviert und eine neue Instanz eines Firebase Extension im Projekt installiert. Wenn die Instanz bereits vorhanden ist, werden ihre Parameter anhand der in der Konfiguration angegebenen Werte aktualisiert.
# Creates a new Google Cloud project.
resource "google_project" "extensions" {
provider = google-beta.no_user_project_override
folder_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"
# Required for the project to display in a list of Firebase projects.
labels = {
"firebase" = "enabled"
}
}
# Enables required APIs.
resource "google_project_service" "extensions" {
provider = google-beta.no_user_project_override
project = google_project.extensions.project_id
for_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-beta
project = google_project.extensions.project_id
depends_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-beta
project = google_project.extensions.project_id
instance_id = "translate-text-in-firestore"
config {
extension_ref = "firebase/firestore-translate-text"
params = {
COLLECTION_PATH = "posts/comments/translations"
DO_BACKFILL = true
LANGUAGES = "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"
}
}
}
Fehlerbehebung und häufig gestellte Fragen
Sie möchten mehr über die verschiedenen projektbezogenen Attribute (z. B. project und user_project_override) erfahren.
In dieser Anleitung werden die folgenden Terraform-Attribute für die Arbeit mit „projects“ verwendet.
project in einem resource-Block
Empfohlen: Fügen Sie nach Möglichkeit das project-Attribut in jeden resource-Block ein.
Wenn Sie ein Projektattribut angeben, erstellt Terraform die im Ressourcenblock angegebene Infrastruktur im angegebenen Projekt. In diesem Leitfaden und in unseren Beispielkonfigurationsdateien wird diese Vorgehensweise verwendet.
Weitere Informationen finden Sie in der offiziellen Terraform-Dokumentation zu project.
user_project_override im Block provider
Für die Bereitstellung der meisten Ressourcen sollten Sie user_project_override = true verwenden, d. h. das Kontingent anhand Ihres eigenen Firebase-Projekts prüfen. Wenn Sie Ihr neues Projekt jedoch so einrichten möchten, dass es Kontingentprüfungen akzeptieren kann, müssen Sie zuerst user_project_override = false verwenden.
Weitere Informationen finden Sie in der offiziellen Terraform-Dokumentation zu user_project_override.
Sie erhalten folgende Fehlermeldung:
generic::permission_denied: Firebase Tos Not Accepted.
Das Nutzerkonto, mit dem Sie gcloud CLI-Befehle ausführen, muss die Firebase-Nutzungsbedingungen akzeptiert haben.
Sie können diese Prüfung durchführen, indem Sie in einem Browser, in dem Sie im Nutzerkonto angemeldet sind, versuchen, ein vorhandenes Firebase-Projekt in der Firebase Console aufzurufen. Wenn Sie ein vorhandenes Firebase-Projekt sehen können, hat das Nutzerkonto die Firebase-Nutzungsbedingungen akzeptiert.
Wenn Sie keine vorhandenen Firebase-Projekte sehen können, hat das Nutzerkonto wahrscheinlich die Firebase-Nutzungsbedingungen nicht akzeptiert. Erstellen Sie dazu über die Firebase Console ein neues Firebase-Projekt und akzeptieren Sie die Firebase-Nutzungsbedingungen im Rahmen der Projekterstellung. Sie können dieses Projekt sofort über die Projekteinstellungen in der Console löschen.
Nach dem Ausführen von terraform apply wird der Fehler generic::permission_denied: IAM authority does not have the
permission angezeigt.
Warten Sie einige Minuten und versuchen Sie es dann noch einmal.terraform apply
Das Erstellen einer Ressource ist fehlgeschlagen, aber wenn Sie terraform apply noch einmal ausführen, wird ALREADY_EXISTS angezeigt.
Das kann an einer Verzögerung bei der Übertragung in verschiedenen Systemen liegen. Versuchen Sie, das Problem zu beheben, indem Sie die Ressource mit terraform import in den Terraform-Zustand importieren. Versuchen Sie dann noch einmal, terraform apply auszuführen.
Bei der Arbeit mit Cloud Firestore wird dieser Fehler angezeigt: Error creating Index: googleapi:
Error 409;...Concurrent access -- try again
Wie der Fehler vermuten lässt, versucht Terraform möglicherweise, mehrere Indexe bereitzustellen und/oder gleichzeitig ein Dokument zu erstellen, und es ist ein Fehler bei der Gleichzeitigkeit aufgetreten.
Versuchen Sie, terraform apply noch einmal auszuführen.
Sie erhalten folgende Fehlermeldung:
"you may need to specify 'X-Goog-User-Project' HTTP header for quota and
billing purposes".
Dieser Fehler bedeutet, dass Terraform nicht weiß, für welches Projekt das Kontingent geprüft werden soll. Prüfen Sie zur Fehlerbehebung Folgendes im Block resource:
Achten Sie darauf, dass Sie einen Wert für das Attribut project angegeben haben.
Achten Sie darauf, dass Sie den Anbieter mit user_project_override = true (kein Alias) verwenden, was in den Firebase-Beispielen google-beta ist.
Beim Erstellen eines neuen Google Cloud-Projekts wird die Fehlermeldung angezeigt, dass die für das neue Projekt angegebene Projekt-ID bereits vorhanden ist.
Mögliche Gründe dafür, dass die Projekt-ID bereits vorhanden ist:
Das mit dieser ID verknüpfte Projekt gehört einer anderen Person.
Problemlösung:Wählen Sie eine andere Projekt-ID aus.
Das mit dieser ID verknüpfte Projekt wurde vor Kurzem gelöscht (im Status „Weich gelöscht“).
Problemlösung:Wenn Sie der Meinung sind, dass das mit der ID verknüpfte Projekt Ihnen gehört, prüfen Sie den Status des Projekts mit der projects.get REST API.
Das mit dieser ID verknüpfte Projekt ist für den aktuellen Nutzer korrekt vorhanden. Eine mögliche Ursache für den Fehler könnte sein, dass ein vorheriger terraform apply unterbrochen wurde.
Problemlösung:Führen Sie die folgenden Befehle aus: terraform import google_project.default PROJECT_ID
und dann terraform import google_firebase_project.default PROJECT_ID.
Warum müssen Sie die Standardinstanz von Cloud Firestore vor dem Standard-Cloud Storage-Bucket bereitstellen?
Wenn Sie Ihren Standard-Cloud Storage-Bucket (über google_app_engine_application) vor dem Versuch bereitgestellt haben, Ihre Standard-Cloud Firestore-Instanz bereitzustellen, wird festgestellt, dass Ihre Standard-Cloud Firestore-Instanz bereits bereitgestellt wurde. Die bereitgestellte Datenbankinstanz befindet sich im Datastore-Modus. Das bedeutet, dass Firebase SDKs, die Authentifizierung oder Firebase Security Rulesnicht darauf zugreifen können. Wenn Sie Cloud Firestore mit diesen Firebase-Diensten verwenden möchten, müssen Sie die Datenbank leeren und dann den Datenbanktyp in der Google Cloud Console ändern.
Wenn Sie versuchen, Cloud Storage (über google_app_engine_application) und dann Ihre Standardinstanz Cloud Firestore bereitzustellen, erhalten Sie diese Fehlermeldung: Error: Error creating Database: googleapi: Error 409: Database already
exists. Please use another database_id.
Wenn Sie den Standard-Cloud Storage-Bucket eines Projekts über google_app_engine_application bereitstellen und das Projekt noch keine Standard-Cloud Firestore-Instanz hat, wird die Standard-Cloud Firestore-Instanz des Projekts automatisch über google_app_engine_application bereitgestellt.
Da die Standard-Cloud Firestore-Instanz Ihres Projekts bereits bereitgestellt ist, gibt google_firestore_database einen Fehler zurück, wenn Sie versuchen, diese Standardinstanz noch einmal explizit bereitzustellen.
Nachdem die standardmäßige Cloud Firestore-Instanz des Projekts bereitgestellt wurde, können Sie sie nicht noch einmal bereitstellen oder ihren Standort ändern. Die bereitgestellte Datenbankinstanz befindet sich im Datastore-Modus. Das bedeutet, dass Firebase SDKs, die Authentifizierung oder Firebase Security Rulesnicht darauf zugreifen können. Wenn Sie Cloud Firestore mit diesen Firebase-Diensten verwenden möchten, müssen Sie die Datenbank leeren und dann den Datenbanktyp in der Google Cloud-Konsole ändern.