Erste Schritte mit Terraform und Firebase

Firebase bietet jetzt Unterstützung für Terraform. Wenn Sie in einem Team arbeiten, das die Erstellung von Firebase-Projekten mit bestimmten bereitgestellten Ressourcen und aktivierten Diensten automatisieren und standardisieren möchte, ist die Verwendung von Terraform mit Firebase möglicherweise das Richtige für Sie.

Der grundlegende Workflow für die Verwendung von Terraform mit Firebase umfasst Folgendes:

  • Erstellen und Anpassen einer Terraform-Konfigurationsdatei (einer .tf-Datei), in der die Infrastruktur angegeben wird, die Sie bereitstellen möchten (d. h. Ressourcen, die Sie bereitstellen möchten, und Dienste, die Sie aktivieren möchten).

  • gcloud CLI-Befehle verwenden, die mit Terraform interagieren, um die in der Datei .tf angegebene Infrastruktur bereitzustellen.

Was kann ich mit Terraform und Firebase tun?

Im allgemeinen Beispiel-Workflow in diesem Leitfaden wird ein neues Firebase-Projekt mit einer Android-App erstellt. Mit Terraform können Sie aber noch viel mehr tun, z. B.:

  • Vorhandene Infrastruktur mit Terraform löschen und ändern.

  • Mit Terraform können Sie produktspezifische Konfigurationen und Aufgaben verwalten, z. B.:

    • Firebase Authentication-Anbieter für Anmeldungen aktivieren
    • Cloud Storage-Buckets oder Datenbankinstanzen erstellen und Firebase Security Rules für sie bereitstellen.
    • Firebase App Hosting-Back-Ends, Builds und andere zugehörige Ressourcen erstellen.

Sie können für alle diese Aufgaben Standard-Terraform-Konfigurationsdateien und -Befehle verwenden. Dazu haben wir Terraform-Konfigurationsdateien für mehrere häufige Anwendungsfälle bereitgestellt.



Allgemeiner Workflow für die Verwendung von Terraform mit Firebase

Voraussetzungen

Dieser Leitfaden ist eine Einführung in die Verwendung von Terraform mit Firebase. Es wird daher davon ausgegangen, dass Sie grundlegende Kenntnisse in Terraform haben. Achten Sie darauf, dass Sie die folgenden Voraussetzungen erfüllen, bevor Sie mit diesem Workflow beginnen.


Schritt 1:Terraform-Konfigurationsdatei erstellen und anpassen

Eine Terraform-Konfigurationsdatei benötigt zwei Hauptabschnitte, die unten ausführlich beschrieben werden:

provider einrichten

Eine provider-Einrichtung ist unabhängig davon erforderlich, welche Firebase-Produkte oder ‑Dienste beteiligt sind.

  1. Erstellen Sie in Ihrem lokalen Verzeichnis eine Terraform-Konfigurationsdatei (z. B. main.tf).

    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 Einrichtung des Anbieters einzubinden.

    Sie haben folgende Möglichkeiten, eine provider-Einrichtung in den Rest Ihrer Terraform-Konfiguration einzubinden:

    • Option 1:Fügen Sie sie oben in eine einzelne Terraform-Konfigurationsdatei (.tf) ein, wie in diesem Leitfaden beschrieben.

      • Verwenden Sie diese Option, wenn Sie gerade erst mit Terraform beginnen oder Terraform mit Firebase ausprobieren möchten.
    • Option 2:Fügen Sie sie in eine separate .tf-Datei ein (z. B. eine provider.tf-Datei), getrennt von der .tf-Datei, 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.
      • Beim Ausführen von Terraform-Befehlen müssen sich sowohl die Datei provider.tf als auch die Datei main.tf im selben Verzeichnis befinden.

  2. Fügen Sie oben in der Datei main.tf die folgende provider-Einrichtung ein.

    Sie müssen den google-beta-Anbieter verwenden, da dies ein Betarelease der Verwendung von Firebase mit Terraform ist. Seien Sie vorsichtig, wenn Sie sie in der Produktion verwenden.

    # 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
    }

    Weitere Informationen zu den verschiedenen Arten von projektbezogenen Attributen (einschließlich des Projekts, das in dieser Anleitung als „Projekt für die Kontingentprüfung“ bezeichnet wird) bei der Verwendung von Terraform mit Firebase

  3. Fahren Sie mit dem nächsten Abschnitt fort, um die Konfigurationsdatei fertigzustellen und anzugeben, welche Infrastruktur erstellt werden soll.

Mit resource-Blöcken festlegen, welche Infrastruktur erstellt werden soll

In Ihrer Terraform-Konfigurationsdatei (in dieser Anleitung die Datei main.tf) müssen Sie die gesamte Infrastruktur angeben, die Terraform erstellen soll. Das bedeutet, dass Sie alle Ressourcen, die Sie bereitstellen möchten, und alle Dienste, die Sie aktivieren möchten, angeben müssen. Hier finden Sie eine vollständige Liste aller Firebase-Ressourcen, die Terraform unterstützen.

  1. Öffnen Sie Ihre main.tf-Datei.

  2. Fügen Sie unter der Einrichtung von provider die folgende Konfiguration von resource-Blöcken ein.

    In diesem einfachen Beispiel wird ein neues Firebase-Projekt und dann eine Firebase Android-App in diesem Projekt erstellt.

    # 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,
      ]
    }

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 Ihre main.tf-Datei 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.

  1. Wenn Sie zum ersten Mal Terraform-Befehle im 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
  2. Erstellen Sie die in der Datei main.tf angegebene Infrastruktur, indem Sie den folgenden Befehl ausführen:

    terraform apply
  3. Prüfen Sie, ob alles wie erwartet bereitgestellt oder aktiviert wurde:

    • Option 1:Führen Sie den folgenden Befehl aus, um die Konfiguration in Ihrem Terminal ausgeben zu lassen:

      terraform show
    • Option 2:Firebase-Projekt in der Firebase-Konsole ansehen



Firebase-Ressourcen mit Terraform-Unterstützung

Die folgenden Firebase- und Google-Ressourcen werden von Terraform unterstützt. Wir fügen ständig weitere Ressourcen hinzu. Wenn Sie die Ressource, die Sie mit Terraform verwalten möchten, nicht sehen, schauen Sie bald wieder nach, ob sie verfügbar ist, oder erstellen Sie eine Anfrage im GitHub-Repository.


Firebase-Projekte und ‑Apps verwalten

  • google_firebase_project: Firebase-Dienste in einem vorhandenen Google Cloud-Projekt aktivieren

  • Firebase-Apps


Firebase Authentication

  • 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. Sehen Sie sich die .tf-Beispieldatei an, um zu erfahren, wie Sie Firebase Authentication einrichten.

    • Für das Projekt, in dem Terraform GCIP und/oder Firebase Authentication aktiviert, muss der Blaze-Tarif gelten. Das Projekt muss also mit einem Cloud Billing-Konto verknüpft sein. Sie können dies programmatisch tun, indem Sie das Attribut billing_account in der google_project-Ressource festlegen.

    • Diese Ressource ermöglicht auch weitere Konfigurationen, z. B. lokale Anmeldemethoden wie anonyme, E-Mail-/Passwort- und Telefonauthentifizierung sowie Blockierfunktionen und autorisierte Domains.

  • google_identity_platform_default_supported_idp_config: Konfigurieren Sie gängige föderierte Identitätsanbieter wie Google, Facebook oder Apple.

  • identity_platform_oauth_idp_config: Beliebige OAuth-Identitätsanbieterquellen (IdP) konfigurieren

  • google_identity_platform_inbound_saml_config – SAML-Integrationen konfigurieren

Noch nicht unterstützt:

  • Multi-Faktor-Authentifizierung (MFA) über Terraform konfigurieren

Firebase App Hosting


Firebase Data Connect


Firebase Realtime Database

Noch nicht unterstützt:


Cloud Firestore

  • google_firestore_database – Cloud Firestore-Instanz erstellen

  • google_firestore_index: Ermöglicht effiziente Abfragen für Cloud Firestore

  • google_firestore_document: Eine 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: Einen vorhandenen Cloud Storage-Bucket für Firebase-SDKs, die Authentifizierung und Firebase Security Rules zugänglich machen

  • google_storage_bucket_object – ein Objekt einem Cloud Storage-Bucket hinzufügen

    Wichtig:Verwenden Sie in dieser Datei keine echten Endnutzer- oder Produktionsdaten.


Firebase Security Rules (für Cloud Firestore und Cloud Storage)

Firebase Realtime Database verwendet ein anderes Bereitstellungssystem für seine Firebase Security Rules.

  • google_firebaserules_ruleset: Definiert Firebase Security Rules, die für eine Cloud Firestore-Instanz oder einen Cloud Storage-Bucket gelten.

  • google_firebaserules_release: Bestimmte Regelsätze für eine Cloud Firestore-Instanz oder einen Cloud Storage-Bucket bereitstellen


Firebase App Check


Firebase Extensions



Beispielhafte Terraform-Konfigurationsdateien für häufige Anwendungsfälle

Mit dieser Konfiguration wird ein neues Google Cloud-Projekt erstellt, das Projekt wird einem Cloud Billing-Konto zugeordnet (für Firebase Authentication mit GCIP ist der Blaze-Tarif erforderlich), Firebase-Dienste werden für das Projekt aktiviert, Firebase Authentication mit GCIP wird eingerichtet und drei verschiedene App-Typen werden für das Projekt registriert.

Das Aktivieren von GCIP ist erforderlich, 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"
}

# 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_firebase_project.auth.project

  # 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",
  ]
}

# Creates a Firebase Android App in the new project created above.
resource "google_firebase_android_app" "auth" {
  provider     = google-beta
  project      = google_firebase_project.auth.project
  display_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-beta
  project      = google_firebase_project.auth.project
  display_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-beta
  project      = google_firebase_project.auth.project
  display_name = "My Web app"
}

Mit dieser Konfiguration wird ein neues Google Cloud-Projekt erstellt, Firebase-Dienste für das Projekt werden aktiviert und ein Data Connect-Dienst wird bereitgestellt.

# Creates a new Google Cloud project.
resource "google_project" "dataconnect" {
  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 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_override
  project  = google_project.dataconnect.project_id
  for_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-beta
  project  = google_project.dataconnect.project_id

  depends_on = [google_project_service.services]
}

# Create a Firebase Data Connect service
resource "google_firebase_data_connect_service" "dataconnect-default" {
  project         = google_firebase_project.dataconnect.project
  location        = "name-of-region-for-service"
  service_id      = "${google_firebase_project.dataconnect.project}-default-fdc"
  deletion_policy = "DEFAULT"
}

Mit dieser Konfiguration wird ein neues Google Cloud-Projekt erstellt, Firebase-Dienste für das Projekt werden aktiviert, die Standard-Realtime Database-Instanz des Projekts wird bereitgestellt und drei verschiedene App-Typen werden für das 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"
}

# 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

  depends_on = [google_project_service.rtdb]
}

# Provisions the default Realtime Database default instance.
resource "google_firebase_database_instance" "database" {
  provider    = google-beta
  project     = google_firebase_project.rtdb.project
  # 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"
}

# Creates a Firebase Android App in the new project created above.
resource "google_firebase_android_app" "rtdb" {
  provider     = google-beta
  project      = google_firebase_project.rtdb.project
  display_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-beta
  project      = google_firebase_project.rtdb.project
  display_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-beta
  project      = google_firebase_project.rtdb.project
  display_name = "My Web app"
}

Mit dieser Konfiguration wird ein neues Google Cloud-Projekt erstellt, das Projekt wird einem Cloud Billing-Konto zugeordnet (für mehrere Realtime Database-Instanzen ist der Blaze-Tarif erforderlich), Firebase-Dienste werden für das Projekt aktiviert, mehrere Realtime Database-Instanzen werden bereitgestellt (einschließlich der Standard-Realtime Database-Instanz des Projekts) und drei verschiedene App-Typen werden für das 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"
}

# 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

  depends_on = [google_project_service.rtdb-multi]
}

# Provisions the default Realtime Database default instance.
resource "google_firebase_database_instance" "database-default" {
  provider    = google-beta
  project     = google_firebase_project.rtdb-multi.project
  # 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"
}

# Provisions an additional Realtime Database instance.
resource "google_firebase_database_instance" "database-additional" {
  provider    = google-beta
  project     = 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-beta
  project      = google_firebase_project.rtdb-multi.project
  display_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-beta
  project      = google_firebase_project.rtdb-multi.project
  display_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-beta
  project      = google_firebase_project.rtdb-multi.project
  display_name = "My Web app"
}

Mit dieser Konfiguration wird ein neues Google Cloud-Projekt erstellt, Firebase-Dienste für das Projekt werden aktiviert, die Standard-Cloud Firestore-Instanz des Projekts wird bereitgestellt und drei verschiedene App-Typen werden für das Projekt registriert.

Außerdem wird Firebase Security Rules für die Standardinstanz Cloud Firestore bereitgestellt, ein Cloud Firestore-Index erstellt und ein Cloud Firestore-Dokument mit Seed-Daten 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"
}

# 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

  depends_on = [google_project_service.firestore]
}

# Provisions the Firestore database instance.
resource "google_firestore_database" "firestore" {
  provider                    = google-beta
  project                     = google_firebase_project.firestore.project
  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"
}

# Creates a ruleset of Firestore Security Rules from a local file.
resource "google_firebaserules_ruleset" "firestore" {
  provider = google-beta
  project  = google_firestore_database.firestore.project
  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")
    }
  }
}

# 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_firestore_database.firestore.project
}

# Adds a new Firestore index.
resource "google_firestore_index" "indexes" {
  provider = google-beta
  project  = google_firestore_database.firestore.project

  collection  = "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-beta
  project     = google_firestore_database.firestore.project
  collection  = "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-beta
  project      = google_firebase_project.firestore.project
  display_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-beta
  project      = google_firebase_project.firestore.project
  display_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-beta
  project      = google_firebase_project.firestore.project
  display_name = "My Web app"
}

Dies ist das Regelset von Cloud Firestore Security Rules, das sich in einer lokalen Datei namens firestore.rules befinden sollte.

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /some_collection/{document} {
      allow read, create, update: if request.auth != null;
    }
  }
}

Durch diese Konfiguration wird ein neues Google Cloud-Projekt erstellt, das Projekt wird einem Cloud Billing-Konto zugewiesen (für zusätzliche Buckets ist der Blaze-Tarif erforderlich), Firebase-Dienste werden für das Projekt aktiviert, zusätzliche, nicht standardmäßige Cloud Storage-Buckets werden bereitgestellt und drei verschiedene App-Typen werden für das 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"
}

# 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

  depends_on = [google_project_service.storage-multi]
}

# Provisions a Cloud Storage bucket.
resource "google_storage_bucket" "bucket-1" {
  provider = google-beta
  project  = google_firebase_project.storage-multi.project
  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_firebase_project.storage-multi.project
  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_firebase_project.storage-multi.project
  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_firebase_project.storage-multi.project
  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_firebase_project.storage-multi.project
  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")
    }
  }
}

# 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_firebase_project.storage-multi.project
}

# 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_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-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_firebase_project.storage-multi.project
  display_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-beta
  project      = google_firebase_project.storage-multi.project
  display_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-beta
  project      = google_firebase_project.storage-multi.project
  display_name = "My Web app"
}

Dies ist das Regelset von Cloud Storage Security Rules, das sich in einer lokalen Datei namens storage.rules befinden sollte.

rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    match /some_folder/{fileName} {
      allow read, write: if request.auth != null;
    }
  }
}

Mit dieser Konfiguration wird ein neues Google Cloud-Projekt erstellt, Firebase-Dienste für das Projekt werden aktiviert und die Durchsetzung von Firebase App Check für Cloud Firestore wird eingerichtet und aktiviert, 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"
}

# 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"
}

# 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
  ]
}

# 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 = [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]
}

Durch diese Konfiguration wird ein neues Google Cloud-Projekt erstellt, Firebase-Dienste für das Projekt werden aktiviert und eine neue Instanz von Firebase Extension wird 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"
}

# 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_firebase_project.extensions.project

  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"
    }
  }
}

Mit dieser Konfiguration wird ein neues Google Cloud-Projekt erstellt, Firebase-Dienste für das Projekt aktiviert, einschließlich Firebase AI Logic, und die Erzwingung von Firebase App Check für Firebase AI Logic eingerichtet und aktiviert, sodass nur über Ihre Apps darauf zugegriffen werden kann.

# Creates a new Google Cloud project.
resource "google_project" "vertex" {
  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 Vertex AI in Firebase).
  billing_account = "000000-000000-000000"
}

# Enables required APIs.
resource "google_project_service" "services" {
  provider   = google-beta.no_user_project_override

  project  = google_project.vertex.project_id
  for_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-beta
  project  = google_project.vertex.project_id

  depends_on = [google_project_service.services]
}

# Creates a Firebase Web App in the new project created earlier.
resource "google_firebase_web_app" "app" {
  provider = google-beta
  project  = google_firebase_project.vertex.project

  display_name = "My Web App"
}

# Creates a Firebase Android App in the new project created earlier.
resource "google_firebase_android_app" "app" {
  provider     = google-beta
  project      = google_firebase_project.vertex.project
  display_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-beta
  project      = google_firebase_project.vertex.project
  display_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 Firebase
resource "google_firebase_app_check_service_config" "vertex" {
  provider = google-beta

  project          = google_firebase_project.vertex.project
  service_id       = "firebaseml.googleapis.com"
  enforcement_mode = "ENFORCED"
}

# Enables the reCAPTCHA Enterprise API
resource "google_project_service" "recaptcha_enterprise" {
  provider = google-beta

  project = google_firebase_project.vertex.project
  service = "recaptchaenterprise.googleapis.com"

  # Don't disable the service if the resource block is removed by accident.
  disable_on_destroy = false
}

# Enables the Play Integrity API
resource "google_project_service" "play_integrity" {
  provider = google-beta

  project = google_firebase_project.vertex.project
  service = "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 Check
resource "google_firebase_app_check_recaptcha_enterprise_config" "appcheck" {
  provider = google-beta

  project   = google_firebase_project.vertex.project
  app_id    = google_firebase_web_app.app.app_id
  site_key  = "your site key"
  token_ttl = "7200s" # Optional

  depends_on = [google_project_service.recaptcha_enterprise]
}

# Registers the Android app with the Play Integrity provider
resource "google_firebase_app_check_play_integrity_config" "appcheck" {
  provider  = google-beta
  project   = google_firebase_project.vertex.project
  app_id    = google_firebase_android_app.app.app_id
  token_ttl = "7200s" # Optional

  lifecycle {
    precondition {
      condition     = length(google_firebase_android_app.app.sha256_hashes) > 0
      error_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 provider
resource "google_firebase_app_check_app_attest_config" "appcheck" {
  provider  = google-beta
  project   = google_firebase_project.vertex.project
  app_id    = google_firebase_apple_app.app.app_id
  token_ttl = "7200s" # Optional

  lifecycle {
    precondition {
      condition     = google_firebase_apple_app.app.team_id != ""
      error_message = "Provide a Team ID on the Apple App to use App Check"
    }
  }
}

In dieser Konfiguration wird gezeigt, wie Sie ein App Hosting-Backend mit Terraform manuell bereitstellen. Mit diesem Ansatz haben Sie eine detaillierte Kontrolle über die erstellten Ressourcen, müssen aber jede Ressource einzeln definieren. Das ist nützlich, wenn Sie das Backend über die Standardoptionen hinaus anpassen müssen.

# Creates a new Google Cloud project.
resource "google_project" "apphosting" {
  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 App Hosting).
  billing_account = "000000-000000-000000"
}

# Enables required APIs.
resource "google_project_service" "services" {
  provider = google-beta.no_user_project_override
  project  = google_project.apphosting.project_id
  for_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-beta
  project  = google_project.apphosting.project_id

  depends_on = [google_project_service.services]
}

# Creates a Firebase Web App in the new project created earlier.
resource "google_firebase_web_app" "apphosting" {
  provider     = google-beta
  project      = google_firebase_project.apphosting.project
  display_name = "My web app"
}

# Creates a Firebase App Hosting Backend
resource "google_firebase_app_hosting_backend" "example" {
  provider = google-beta
  project  = google_firebase_project.apphosting.project

  # Choose the region closest to your users
  location         = "name-of-region-for-service"
  backend_id       = "name-of-backend-for-service"
  app_id           = google_firebase_web_app.apphosting.app_id
  display_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 Hosting
resource "google_service_account" "service_account" {
  provider = google-beta
  project  = google_firebase_project.apphosting.project

  # Must be firebase-app-hosting-compute
  account_id                   = "firebase-app-hosting-compute"
  display_name                 = "Firebase App Hosting compute service account"

  # Do not throw if already exists
  create_ignore_already_exists = true
}

# Adds permission to the App Hosting service account
resource "google_project_iam_member" "app_hosting_sa" {
  provider = google-beta
  project  = google_firebase_project.apphosting.project

  for_each = toset([
    "roles/firebase.sdkAdminServiceAgent",
    "roles/firebaseapphosting.computeRunner"
  ])

  role   = each.key
  member = google_service_account.service_account.member
}

# Creates a Build
resource "google_firebase_app_hosting_build" "example" {
  provider = google-beta

  project          = google_firebase_app_hosting_backend.example.project
  location         = google_firebase_app_hosting_backend.example.location
  backend          = google_firebase_app_hosting_backend.example.backend_id
  build_id         = "my-build"

  source {
    container {
      # TODO: use your own image
      image = "us-docker.pkg.dev/cloudrun/container/hello"
    }
  }
}

# Rolls out the Build
resource "google_firebase_app_hosting_traffic" "example" {
  provider = google-beta

  project          = google_firebase_app_hosting_backend.example.project
  location         = google_firebase_app_hosting_backend.example.location
  backend          = google_firebase_app_hosting_backend.example.backend_id

  target {
    splits {
      build = google_firebase_app_hosting_build.example.name
      percent = 100
    }
  }
}

Diese Konfiguration zeigt, wie ein App Hosting-Backend mit Anwendungscode bereitgestellt wird, der in einem GitHub-Repository gespeichert ist. Mit diesem Ansatz können Sie Ihre Infrastruktur über GitHub-Pull-Anfragen und CI/CD-Pipelines gemäß dem typischen Modell für App Hosting-Bereitstellungen verwalten und aktualisieren.

# Creates a new Google Cloud project.
resource "google_project" "apphosting" {
  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 App Hosting).
  billing_account = "000000-000000-000000"
}

# Enables required APIs.
resource "google_project_service" "services" {
  provider = google-beta.no_user_project_override
  project  = google_project.apphosting.project_id
  for_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-beta
  project  = google_project.apphosting.project_id

  depends_on = [google_project_service.services]
}

# Creates a Firebase Web App in the new project created earlier.
resource "google_firebase_web_app" "apphosting" {
  provider     = google-beta
  project      = google_firebase_project.apphosting.project
  display_name = "My web app"
}

### Setting up Firebase App Hosting ###

# Creates a Firebase App Hosting Backend
resource "google_firebase_app_hosting_backend" "example" {
  provider = google-beta
  project  = google_firebase_project.apphosting.project

  # Choose the region closest to your users
  location         = "name-of-region-for-service"
  backend_id       = "name-of-backend-for-service"
  app_id           = google_firebase_web_app.apphosting.app_id
  display_name     = "My Backend"
  serving_locality = "GLOBAL_ACCESS" # or "REGIONAL_STRICT"
  service_account  = google_service_account.service_account.email

  codebase {
    repository = google_developer_connect_git_repository_link.my-repository.name
    root_directory = "/"
  }
}

# Creates the service account for Firebase App Hosting
resource "google_service_account" "service_account" {
  provider = google-beta
  project  = google_firebase_project.apphosting.project

  # Must be firebase-app-hosting-compute
  account_id                   = "firebase-app-hosting-compute"
  display_name                 = "Firebase App Hosting compute service account"

  # Do not throw if already exists
  create_ignore_already_exists = true
}

# Adds permission to the App Hosting service account
resource "google_project_iam_member" "app_hosting_sa" {
  provider = google-beta
  project  = google_firebase_project.apphosting.project

  for_each = toset([
    "roles/developerconnect.readTokenAccessor",
    "roles/firebase.sdkAdminServiceAgent",
    "roles/firebaseapphosting.computeRunner"
  ])

  role   = each.key
  member = google_service_account.service_account.member
}

# Configures auto rollout from GitHub
resource "google_firebase_app_hosting_traffic" "example" {
  provider = google-beta

  project  = google_firebase_app_hosting_backend.example.project
  location = google_firebase_app_hosting_backend.example.location
  backend  = google_firebase_app_hosting_backend.example.backend_id

  rollout_policy {
    codebase_branch = "main" # Or another branch
  }
}

###

### Setting up a connection to GitHub ###

# Provisions Service Agent for Developer Connect
resource "google_project_service_identity" "devconnect-p4sa" {
  provider = google-beta
  project  = google_firebase_project.apphosting.project

  service  = "developerconnect.googleapis.com"
}

# Adds permission to Developer Connect Service Agent to manager GitHub tokens
resource "google_project_iam_member" "devconnect-secret" {
  provider = google-beta
  project  = google_firebase_project.apphosting.project

  role     = "roles/secretmanager.admin"
  member   = google_project_service_identity.devconnect-p4sa.member
}

# Connects to a GitHub account
resource "google_developer_connect_connection" "my-connection" {
  provider = google-beta
  project  = google_firebase_project.apphosting.project

  # Must match the google_firebase_app_hosting_backend's location
  location = "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 output
output "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 project
resource "google_developer_connect_git_repository_link" "my-repository" {
  provider = google-beta
  project  = google_firebase_project.apphosting.project
  location = google_developer_connect_connection.my-connection.location

  git_repository_link_id = "my-repo-id"
  parent_connection = google_developer_connect_connection.my-connection.connection_id
  clone_uri = "https://github.com/myuser/myrepo.git"
}

###



Fehlerbehebung und häufig gestellte Fragen

In dieser Anleitung werden die folgenden Terraform-Attribute für die Arbeit mit Projekten verwendet.

project innerhalb eines resource-Blocks

Empfohlen: Fügen Sie das Attribut project nach Möglichkeit in jeden resource-Block ein.

Wenn Sie ein Projektattribut einfügen, 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. Das bedeutet, dass das Kontingent für Ihr eigenes Firebase-Projekt geprüft wird. Damit Ihr neues Projekt jedoch 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.

Achten Sie darauf, dass das Nutzerkonto, mit dem Sie gcloud CLI-Befehle ausführen, die Firebase-Nutzungsbedingungen akzeptiert hat.

  • Sie können dies prüfen, indem Sie sich in einem Browser mit dem Nutzerkonto anmelden und versuchen, ein vorhandenes Firebase-Projekt in der Firebase-Konsole aufzurufen. Wenn Sie ein vorhandenes Firebase-Projekt aufrufen können, hat der Nutzer des Kontos die Firebase-Nutzungsbedingungen akzeptiert.

  • Wenn Sie keine vorhandenen Firebase-Projekte sehen können, hat der Nutzer des Kontos die Firebase-Nutzungsbedingungen wahrscheinlich noch nicht akzeptiert. Erstellen Sie dazu ein neues Firebase-Projekt über die Firebase-Konsole und akzeptieren Sie die Firebase-Nutzungsbedingungen im Rahmen der Projekterstellung. Sie können dieses Projekt sofort über die Projekteinstellungen in der Console löschen.

Warten Sie einige Minuten und versuchen Sie dann noch einmal, terraform apply auszuführen.

Das kann an einer Verzögerung bei der Übertragung in verschiedenen Systemen liegen. Versuchen Sie, das Problem zu beheben, indem Sie die Ressource in den Terraform-Zustand importieren. Führen Sie dazu terraform import aus. Versuchen Sie dann, terraform apply noch einmal auszuführen.

Informationen zum Importieren der einzelnen Ressourcen finden Sie im Abschnitt „Import“ der Terraform-Dokumentation (z. B. die Dokumentation zum Importieren für Cloud Firestore).

Wie der Fehler andeutet, versucht Terraform möglicherweise, mehrere Indexe bereitzustellen und/oder gleichzeitig ein Dokument zu erstellen, und es ist ein Parallelitätsfehler aufgetreten. Versuchen Sie, terraform apply noch einmal auszuführen.

Dieser Fehler bedeutet, dass Terraform nicht weiß, für welches Projekt das Kontingent geprüft werden soll. Prüfen Sie zur Fehlerbehebung Folgendes im resource-Block:

  • 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. In den Firebase-Beispielen ist das google-beta.

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.

    • Lösung:Wählen Sie eine andere Projekt-ID aus.
  • Das Projekt, das mit dieser ID verknüpft ist, wurde vor Kurzem gelöscht (vorläufig gelöscht).

    • Lösung:Wenn Sie der Meinung sind, dass das Projekt, das mit der ID verknüpft ist, 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 vorhanden. Eine mögliche Ursache für den Fehler könnte sein, dass ein vorheriger terraform apply unterbrochen wurde.

    • Lö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

Wenn Sie Ihren Standard-Cloud Storage-Bucket (über google_app_engine_application) bevor Sie versuchen, Ihre Standard-Cloud Firestore-Instanz bereitzustellen, ist Ihre Standard-Cloud Firestore-Instanz bereits bereitgestellt. Die bereitgestellte Datenbankinstanz befindet sich im Datastore-Modus. Das bedeutet, dass nicht über Firebase SDKs, die Authentifizierung oder Firebase Security Rules darauf zugegriffen werden kann. 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.

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 von google_app_engine_application bereitgestellt.

Da die Standardinstanz Cloud Firestore Ihres Projekts bereits bereitgestellt wurde, 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 sie nicht über Firebase-SDKs, die Authentifizierung oder Firebase Security Rules zugänglich ist. 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.