Inizia a utilizzare Terraform e Firebase

Firebase sta iniziando a supportare Terraform. Se fai parte di un team che vuole automatizzare e standardizzare la creazione di progetti Firebase con servizi abilitati e risorse specifiche di cui è stato eseguito il provisioning, l'utilizzo di Terraform con Firebase può essere la soluzione ideale.

Il flusso di lavoro di base per l'utilizzo di Terraform con Firebase include quanto segue:

  • Creazione e personalizzazione di un file di configurazione Terraform (un file .tf) che specifica l'infrastruttura di cui vuoi eseguire il provisioning (ovvero le risorse di cui vuoi eseguire il provisioning e i servizi che vuoi attivare).

  • Utilizzando i comandi gcloud CLI che interagiscono con Terraform per eseguire il provisioning dell'infrastruttura specificata nel file .tf.

Che cosa puoi fare con Terraform e Firebase?

L'esempio di flusso di lavoro generalizzato in questa guida consiste nel creare un nuovo progetto Firebase con un'app per Android. Ma puoi fare molto di più con Terraform, ad esempio:

  • Eliminare e modificare l'infrastruttura esistente utilizzando Terraform.

  • Gestisci la configurazione e le attività specifiche del prodotto utilizzando Terraform, ad esempio:

    • Abilitazione dei provider di accesso Firebase Authentication.
    • Creazione di bucket Cloud Storage o istanze di database e deployment di Firebase Security Rules.
    • Creazione di backend, build e altre risorse correlate.Firebase App Hosting

Puoi utilizzare i file di configurazione e i comandi Terraform standard per eseguire tutte queste attività. Per aiutarti in questa operazione, abbiamo fornito file di configurazione Terraform di esempio per diversi casi d'uso comuni.



Flusso di lavoro generalizzato per l'utilizzo di Terraform con Firebase

Prerequisiti

Questa guida è un'introduzione all'utilizzo di Terraform con Firebase, pertanto presuppone una competenza di base con Terraform. Prima di iniziare questo flusso di lavoro, assicurati di aver completato i seguenti prerequisiti.

  • Installa Terraform e acquisisci familiarità con Terraform utilizzando i tutorial ufficiali.

  • Installa Google Cloud CLI (gcloud CLI). Accedi utilizzando un account utente o un service account.

    • Se utilizzi un account utente, devi aver accettato i Termini di servizio di Firebase. Hai accettato i Termini di servizio di Firebase se riesci a visualizzare un progetto Firebase nella console Firebase
    • Affinché Terraform esegua determinate azioni (ad esempio, la creazione di progetti), deve essere vero quanto segue:
      • L'utente o l'account di servizio deve disporre dell'accesso IAM applicabile per queste azioni.
      • Se l'utente o il service account fa parte di un'organizzazione Google Cloud, le policy dell'organizzazione devono consentire all'account di eseguire queste azioni.


Passaggio 1: crea e personalizza un file di configurazione Terraform

Un file di configurazione Terraform deve contenere due sezioni principali (descritte in dettaglio di seguito):

Configurare provider

È necessaria una configurazione provider indipendentemente dai prodotti o servizi Firebase coinvolti.

  1. Crea un file di configurazione Terraform (ad esempio il file main.tf) nella directory locale.

    In questa guida, utilizzerai questo file di configurazione per specificare sia la configurazione di provider sia tutta l'infrastruttura che vuoi che Terraform crei. Tieni presente, tuttavia, che hai diverse opzioni per includere la configurazione del fornitore.

    Hai le seguenti opzioni per includere una configurazione provider nel resto della configurazione Terraform:

    • Opzione 1: includilo nella parte superiore di un singolo file di configurazione .tf di Terraform (come mostrato in questa guida).

      • Utilizza questa opzione se hai appena iniziato a utilizzare Terraform o se stai solo provando Terraform con Firebase.
    • Opzione 2: includilo in un file .tf separato (ad esempio un file provider.tf), a parte il file .tf in cui specifichi l'infrastruttura da creare (ad esempio un file main.tf).

      • Utilizza questa opzione se fai parte di un team più grande che deve standardizzare la configurazione.
      • Quando esegui i comandi Terraform, sia il file provider.tf sia il file main.tf devono trovarsi nella stessa directory.

  2. Includi la seguente configurazione di provider all'inizio del file main.tf.

    Devi utilizzare il provider google-beta perché questa è una versione beta dell'utilizzo di Firebase con Terraform. Presta attenzione quando utilizzi la funzionalità in produzione.

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

    Scopri di più sui diversi tipi di attributi correlati al progetto (inclusi quelli che questa guida chiama "progetto di controllo della quota") quando utilizzi Terraform con Firebase.

  3. Continua alla sezione successiva per completare il file di configurazione e specificare l'infrastruttura da creare.

Specifica l'infrastruttura da creare utilizzando i blocchi resource

Nel file di configurazione Terraform (main.tf in questa guida), devi specificare tutta l'infrastruttura che vuoi che Terraform crei (ovvero tutte le risorse di cui vuoi eseguire il provisioning e tutti i servizi che vuoi attivare). In questa guida, trovi un elenco completo di tutte le risorse Firebase che supportano Terraform.

  1. Apri il file main.tf.

  2. Nella configurazione provider, includi la seguente configurazione dei blocchi resource.

    Questo esempio di base crea un nuovo progetto Firebase e poi crea un'app Firebase per Android all'interno del progetto.

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

Se non hai familiarità con l'infrastruttura di progetti e app come risorse, consulta la seguente documentazione:

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


Passaggio 2: esegui i comandi Terraform per creare l'infrastruttura specificata

Per eseguire il provisioning delle risorse e attivare i servizi specificati nel file main.tf, esegui i seguenti comandi dalla stessa directory del file main.tf. Per informazioni dettagliate su questi comandi, consulta la documentazione di Terraform.

  1. Se è la prima volta che esegui comandi Terraform nella directory, devi inizializzare la directory di configurazione e installare il provider Google Terraform. Per farlo, esegui questo comando:

    terraform init
  2. Crea l'infrastruttura specificata nel file main.tf eseguendo il seguente comando:

    terraform apply
  3. Verifica che il provisioning o l'attivazione siano stati eseguiti come previsto:

    • Opzione 1: visualizza la configurazione stampata nel terminale eseguendo il seguente comando:

      terraform show
    • Opzione 2: visualizza il progetto Firebase nella console Firebase.



Risorse Firebase con supporto Terraform

Le seguenti risorse Firebase e Google supportano Terraform. e aggiungiamo sempre nuove risorse. Pertanto, se non vedi la risorsa che vuoi gestire con Terraform, ricontrolla a breve per vedere se è disponibile o richiedila segnalando un problema nel repository GitHub.


Gestione di progetti e app Firebase

  • google_firebase_project: attiva i servizi Firebase in un progetto Google Cloud esistente

  • App Firebase


Firebase Authentication

Non ancora supportato:

  • Configurazione dell'autenticazione a più fattori (MFA) tramite Terraform

Firebase App Hosting


Firebase Data Connect


Firebase Realtime Database

Non ancora supportato:

  • Deployment di Firebase Realtime Database Security Rules tramite Terraform (scopri come eseguire il deployment di questi Rules utilizzando altri strumenti, incluse le opzioni programmatiche)

Cloud Firestore

  • google_firestore_database: crea un'istanza Cloud Firestore

  • google_firestore_index: consente query efficienti per Cloud Firestore

  • google_firestore_document: esegui il seeding di un'istanza di Cloud Firestore con un documento specifico in una raccolta

    Importante: non utilizzare dati di produzione o di utenti finali reali in questo documento iniziale.


Cloud Storage for Firebase

  • google_firebase_storage_bucket: rendi accessibile un bucket Cloud Storage esistente per gli SDK Firebase, l'autenticazione e Firebase Security Rules

  • google_storage_bucket_object: aggiungi un oggetto a un bucket Cloud Storage

    Importante:non utilizzare dati di produzione o di utenti finali reali in questo file.


Firebase Security Rules (per Cloud Firestore e Cloud Storage)

Tieni presente che Firebase Realtime Database utilizza un sistema di provisioning diverso per i suoi Firebase Security Rules.

  • google_firebaserules_ruleset: definisci Firebase Security Rules che si applicano a un'istanza Cloud Firestore o a un bucket Cloud Storage

  • google_firebaserules_release: distribuisci regole specifiche a un'istanza Cloud Firestore o a un bucket Cloud Storage


Firebase App Check


Firebase Extensions



File di configurazione Terraform di esempio per casi d'uso comuni

Questa configurazione crea un nuovo progetto Google Cloud, associa il progetto a un account Cloud Billing (il piano tariffario Blaze è necessario per Firebase Authentication con GCIP), abilita i servizi Firebase per il progetto, configura Firebase Authentication con GCIP e registra tre diversi tipi di app con il progetto.

Tieni presente che l'attivazione di GCIP è necessaria per configurare Firebase Authentication tramite Terraform.

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

Questa configurazione crea un nuovo progetto Google Cloud, abilita i servizi Firebase per il progetto e esegue il provisioning di un servizio Data Connect.

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

Questa configurazione crea un nuovo progetto Google Cloud, attiva i servizi Firebase per il progetto, esegue il provisioning dell'istanza Realtime Database predefinita del progetto e registra tre diversi tipi di app con il progetto.

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

Questa configurazione crea un nuovo progetto Google Cloud, lo associa a un account Cloud Billing (il piano tariffario Blaze è necessario per più istanze Realtime Database), abilita i servizi Firebase per il progetto, esegue il provisioning di più istanze Realtime Database (inclusa l'istanza Realtime Database predefinita del progetto) e registra tre diversi tipi di app con il progetto.

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

Questa configurazione crea un nuovo progetto Google Cloud, attiva i servizi Firebase per il progetto, esegue il provisioning dell'istanza Cloud Firestore predefinita del progetto e registra tre diversi tipi di app con il progetto.

Inoltre, esegue il provisioning di Firebase Security Rules per l'istanza Cloud Firestore predefinita, crea un indice Cloud Firestore e aggiunge un documento Cloud Firestore con dati iniziali.

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

Questo è il set di regole di Cloud Firestore Security Rules che deve trovarsi in un file locale denominato firestore.rules.

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

Questa configurazione crea un nuovo progetto Google Cloud, lo associa a un account Cloud Billing (il piano tariffario Blaze è necessario per i bucket aggiuntivi), abilita i servizi Firebase per il progetto, esegue il provisioning di bucket Cloud Storage aggiuntivi non predefiniti e registra tre diversi tipi di app con il progetto.

Inoltre, esegue il provisioning di Firebase Security Rules per ogni bucket Cloud Storage e carica un file in uno dei bucket Cloud Storage.

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

Questo è il set di regole di Cloud Storage Security Rules che deve trovarsi in un file locale denominato storage.rules.

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

Questa configurazione crea un nuovo progetto Google Cloud, abilita i servizi Firebase per il progetto e configura e abilita l'applicazione di Firebase App Check per Cloud Firestore in modo che sia accessibile solo dalla tua app per Android.

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

Questa configurazione crea un nuovo progetto Google Cloud, abilita i servizi Firebase per il progetto e installa una nuova istanza di un Firebase Extension nel progetto. Se l'istanza esiste già, i relativi parametri vengono aggiornati in base ai valori forniti nella configurazione.

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

Questa configurazione crea un nuovo progetto Google Cloud, abilita i servizi Firebase per il progetto, incluso Firebase AI Logic, e configura e abilita l'applicazione di Firebase App Check per Firebase AI Logic in modo che sia accessibile solo dalle tue app.

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

Questa configurazione mostra come eseguire manualmente il provisioning di un backend App Hosting utilizzando Terraform. Questo approccio ti offre un controllo granulare sulle risorse create, ma richiede di definire ogni risorsa singolarmente. Questa opzione è utile quando devi personalizzare il backend oltre le opzioni predefinite.

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

Questa configurazione mostra come eseguire il provisioning di un backend App Hosting utilizzando il codice dell'applicazione archiviato in un repository GitHub. Questo approccio ti consente di gestire e aggiornare la tua infrastruttura tramite le richieste di pull di GitHub e le pipeline CI/CD in base al modello tipico per i deployment di App Hosting.

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

###



Risoluzione dei problemi e domande frequenti

Questa guida utilizza i seguenti attributi Terraform quando si lavora con "projects".

project all'interno di un blocco di resource

Consigliato: se possibile, includi l'attributo project in ogni blocco resource.

Se includi un attributo project, Terraform creerà l'infrastruttura specificata nel blocco resource all'interno del progetto specificato. Questa guida e i nostri file di configurazione di esempio utilizzano questa pratica.

Consulta la documentazione ufficiale di Terraform su project.

user_project_override all'interno del blocco provider

Per il provisioning della maggior parte delle risorse, devi utilizzare user_project_override = true, ovvero controllare la quota rispetto al tuo progetto Firebase. Tuttavia, per configurare il nuovo progetto in modo che possa accettare i controlli delle quote, devi prima utilizzare user_project_override = false.

Consulta la documentazione ufficiale di Terraform su user_project_override.

Assicurati che l'account utente che utilizzi per eseguire i comandi gcloud CLI abbia accettato i Termini di servizio di Firebase.

  • Puoi eseguire questo controllo utilizzando un browser in cui è stato eseguito l'accesso all'account utente e provando a visualizzare un progetto Firebase esistente nella console Firebase. Se riesci a visualizzare un progetto Firebase esistente, l'account utente ha accettato i Termini di servizio di Firebase.

  • Se non riesci a visualizzare alcun progetto Firebase esistente, è probabile che l'account utente non abbia accettato i Termini di servizio di Firebase. Per risolvere il problema, crea un nuovo progetto Firebase tramite la console Firebase e accetta i Termini di servizio di Firebase durante la creazione del progetto. Puoi eliminare immediatamente questo progetto tramite le impostazioni del progetto nella console.

Attendi qualche minuto e riprova a eseguire terraform apply.

Ciò potrebbe essere dovuto a un ritardo di propagazione in vari sistemi. Prova a risolvere questo problema importando la risorsa nello stato di Terraform eseguendo terraform import. Quindi prova a eseguire di nuovo terraform apply.

Puoi scoprire come importare ogni risorsa nella sezione "Importa" della relativa documentazione di Terraform (ad esempio, la documentazione"Importa" per Cloud Firestore).

Come suggerisce l'errore, Terraform potrebbe tentare di eseguire il provisioning di più indici e/o creare un documento contemporaneamente e si è verificato un errore di concorrenza. Prova a eseguire di nuovo terraform apply.

Questo errore significa che Terraform non sa rispetto a quale progetto controllare la quota. Per risolvere il problema, controlla quanto segue nel blocco resource:

  • Assicurati di aver specificato un valore per l'attributo project.
  • Assicurati di utilizzare il provider con user_project_override = true (nessun alias), che negli esempi di Firebase è google-beta.

Ecco i possibili motivi per cui l'ID progetto potrebbe già esistere:

  • Il progetto associato a questo ID appartiene a un'altra persona.

    • Soluzione:scegli un altro ID progetto.
  • Il progetto associato a questo ID è stato eliminato di recente (in stato di eliminazione temporanea).

    • Per risolvere il problema:se ritieni che il progetto associato all'ID ti appartenga, controlla lo stato del progetto utilizzando l'API REST projects.get.
  • Il progetto associato a questo ID esiste correttamente per l'utente corrente. Una possibile causa dell'errore potrebbe essere l'interruzione di un precedente terraform apply.

    • Per risolvere il problema, esegui i seguenti comandi:
      terraform import google_project.default PROJECT_ID e poi
      terraform import google_firebase_project.default PROJECT_ID

Se hai eseguito il provisioning del bucket Cloud Storage predefinito (tramite google_app_engine_application) prima di provare a eseguire il provisioning dell'istanza Cloud Firestore predefinita, noterai che l'istanza Cloud Firestore predefinita è già stata sottoposta a provisioning. Tieni presente che l'istanza di database di cui è stato eseguito il provisioning è in modalità Datastore, il che significa che non è accessibile agli SDK Firebase, all'autenticazione o a Firebase Security Rules. Se vuoi utilizzare Cloud Firestore con questi servizi Firebase, devi svuotare il database e poi modificarne il tipo nella console Google Cloud.

Quando esegui il provisioning del bucket Cloud Storage predefinito di un progetto (tramite google_app_engine_application) e il progetto non ha ancora la sua istanza Cloud Firestore predefinita, google_app_engine_application esegue automaticamente il provisioning dell'istanza Cloud Firestore predefinita del progetto.

Pertanto, poiché l'istanza Cloud Firestore predefinita del progetto è già di cui è stato eseguito il provisioning, google_firestore_database genererà un errore se provi a eseguire di nuovo il provisioning di questa istanza predefinita.

Una volta eseguito il provisioning dell'istanza Cloud Firestore predefinita del progetto, non puoi "eseguire nuovamente il provisioning" o modificarne la posizione. Tieni presente che l'istanza del database di cui è stato eseguito il provisioning è in modalità Datastore, il che significa che non è accessibile agli SDK Firebase, all'autenticazione o a Firebase Security Rules. Se vuoi utilizzare Cloud Firestore con questi servizi Firebase, devi svuotare il database e poi modificarne il tipo nella console Google Cloud.