Firebase sta iniziando a supportare Terraform. Se fai parte di un team che vuole automatizzare e standardizzare la creazione di progetti Firebase con risorse specifiche di cui è stato eseguito il provisioning e servizi abilitati, l'utilizzo di Terraform con Firebase può essere una buona soluzione.
Il flusso di lavoro di base per l'utilizzo di Terraform con Firebase include quanto segue:
Crea e personalizza un file di configurazione Terraform (un file
.tf
) che specifica l'infrastruttura da eseguire il provisioning (ovvero le risorse da eseguire il provisioning e i servizi da attivare).Utilizzo dei 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 è la creazione di un nuovo progetto Firebase con un'app per Android. Tuttavia, 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:
- Attivazione dei provider di accesso Firebase Authentication.
- Creazione di bucket o istanze di database Cloud Storage e relativo deployment Firebase Security Rules.
Puoi utilizzare i comandi e i file di configurazione Terraform standard per svolgere tutte queste attività. Per aiutarti, abbiamo fornito file di configurazione Terraform di esempio per diversi scenari di utilizzo 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 conoscenza di base di Terraform. Prima di iniziare questo flusso di lavoro, assicurati di aver completato i seguenti prerequisiti.
Installa Terraform e familiarizza con Terraform utilizzando i tutorial ufficiali.
Installa Google Cloud CLI (gcloud CLI). Accedi utilizzando un account utente o un account di servizio.
Visualizza i requisiti per gli account utente e gli account di servizio
- Se utilizzi un account utente, devi aver accettato i Termini di servizio di Firebase. Hai accettato i TdS di Firebase se riesci a visualizzare un progetto Firebase nella console Firebase
- Affinché Terraform possa eseguire determinate azioni (ad esempio creare progetti), deve essere vero quanto segue:
- L'account utente o di servizio deve disporre dell'accesso IAM applicabile per queste azioni.
- Se l'account utente o di servizio fa parte di un'Google Cloud organizzazione, i criteri 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 richiede due sezioni principali (descritte in dettaglio di seguito):
- Una
provider
sezione di configurazione che indica a quali risorse Terraform è possibile accedere - Una sezione di singoli blocchi
resource
che specificano l'infrastruttura da creare
Configurare provider
È necessaria una configurazione di provider
indipendentemente dai prodotti o servizi Firebase coinvolti.
Crea un file di configurazione Terraform (ad esempio un file
main.tf
) nella directory locale.In questa guida utilizzerai questo file di configurazione per specificare sia la
provider
configurazione sia tutta l'infrastruttura che vuoi che Terraform crei. Tieni presente, tuttavia, che hai a disposizione opzioni per includere la configurazione del fornitore.Visualizza le opzioni per includere la configurazione di
provider
Per includere una configurazione
provider
nel resto della configurazione di Terraform, hai a disposizione le seguenti opzioni:Opzione 1: includilo nella parte superiore di un singolo file di configurazione
.tf
Terraform (come mostrato in questa guida).- Utilizza questa opzione se stai appena iniziando a utilizzare Terraform o se stai solo provando Terraform con Firebase.
Opzione 2: includilo in un file
.tf
separato (ad esempio un fileprovider.tf
), diverso dal file.tf
in cui specifichi l'infrastruttura da creare (ad esempio un filemain.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 filemain.tf
devono trovarsi nella stessa directory.
Includi la seguente configurazione
provider
nella parte superiore del filemain.tf
.Devi utilizzare il provider
google-beta
perché si tratta di una versione beta dell'utilizzo di Firebase con Terraform. Presta attenzione durante l'utilizzo in produzione.# Terraform configuration to set up providers by version. terraform { required_providers { google-beta = { source = "hashicorp/google-beta" version = "~> 5.0" } } } # Configures the provider to use the resource block's specified project for quota checks. provider "google-beta" { user_project_override = true } # Configures the provider to not use the resource block's specified project for quota checks. # This provider should only be used during project creation and initializing services. provider "google-beta" { alias = "no_user_project_override" user_project_override = false }
Scopri di più sui diversi tipi di attributi relativi al progetto (incluso quello che questa guida definisce "progetto di controllo della quota") quando utilizzi Terraform con Firebase.
Vai alla sezione successiva per completare il file di configurazione e specificare l'infrastruttura da creare.
Specificare l'infrastruttura da creare utilizzando i blocchi resource
Nel file di configurazione Terraform (per questa guida, il file main.tf
), devi specificare tutta l'infrastruttura che vuoi che Terraform crei, ovvero tutte le risorse da eseguire il provisioning e tutti i servizi da attivare. In questa guida troverai un elenco completo di tutte le risorse Firebase che supportano Terraform.
Apri il file
main.tf
.Nella configurazione di
provider
, includi la seguente configurazione di blocchiresource
.Questo esempio di base crea un nuovo progetto Firebase e poi 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, ] }
Visualizza una versione fortemente annotata di questo file di configurazione di esempio
Se non hai dimestichezza con l'infrastruttura di progetti e app come risorse, consulta la seguente documentazione:
- Informazioni sui progetti Firebase
- Documentazione di riferimento per la gestione dei progetti Firebase
# 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.
Se è la prima volta che esegui comandi Terraform nella directory, devi inizializzare la directory di configurazione e installare il provider Terraform di Google. A tale scopo, esegui il seguente comando:
terraform init
Crea l'infrastruttura specificata nel file
main.tf
eseguendo il seguente comando:terraform apply
Verifica che il provisioning o l'attivazione di tutti gli elementi sia stato eseguito 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 di Terraform
Le seguenti risorse Firebase e Google sono supportate da Terraform. e continuiamo ad aggiungere altre risorse. Pertanto, se non vedi la risorsa che vuoi gestire con Terraform, torna a controllare a breve per vedere se è disponibile o richiedila aprendo un problema nel repository GitHub.
Gestione di progetti e app Firebase
google_firebase_project
: attiva i servizi Firebase in un progetto Google Cloud esistenteApp Firebase
google_firebase_apple_app
: crea o gestisci un'app per le piattaforme Apple Firebasegoogle_firebase_android_app
: crea o gestisci un'app Firebase per Androidgoogle_firebase_web_app
: crea o gestisci un'app web Firebase
Firebase Authentication
google_identity_platform_config
: attiva Google Cloud Identity Platform (GCIP), che è il backend di Firebase Authentication, e fornisci le impostazioni di autenticazione a livello di progettoLa configurazione di Firebase Authentication tramite Terraform richiede l'attivazione di GCIP. Assicurati di esaminare il file
.tf
di esempio per scoprire come configurare Firebase Authentication.Il progetto in cui Terraform abiliterà GCIP e/o Firebase Authentication deve essere nel piano tariffario Blaze (ovvero il progetto deve avere un account Cloud Billing associato). Puoi farlo in modo programmatico impostando l'attributo
billing_account
nella risorsagoogle_project
.Questa risorsa consente anche altre configurazioni, ad esempio metodi di accesso locale, come anonimo, email/password e autenticazione telefonica, nonché funzioni di blocco e domini autorizzati.
google_identity_platform_default_supported_idp_config
: configura provider di identità federati comuni, come Google, Facebook o Appleidentity_platform_oauth_idp_config
: configura origini provider di identità (IdP) OAuth arbitrariegoogle_identity_platform_inbound_saml_config
: configura le integrazioni SAML
Non ancora supportato:
- Configurazione dell'autenticazione a più fattori (MFA) tramite Terraform
Firebase Data Connect
google_firebase_data_connect_service
: crea un servizio Data Connect
Firebase Realtime Database
google_firebase_database_instance
: crea un'istanza Realtime Database
Non ancora supportato:
- Eseguire il 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 Firestoregoogle_firestore_index
: consente query efficienti per Cloud Firestoregoogle_firestore_document
: inizializza un'istanza Cloud Firestore con un documento specifico in una raccoltaImportante: non utilizzare dati di produzione o utente finale reali in questo documento di seed.
Cloud Storage for Firebase
google_firebase_storage_bucket
: consenti di rendere accessibile un bucket Cloud Storage esistente per gli SDK Firebase, l'autenticazione e Firebase Security Rulesgoogle_storage_bucket_object
: aggiungi un oggetto a un bucket Cloud StorageImportante: non utilizzare dati di produzione o utente finale 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 il suo Firebase Security Rules.
google_firebaserules_ruleset
: definisci i Firebase Security Rules da applicare a un'istanza Cloud Firestore o a un Cloud Storage bucketgoogle_firebaserules_release
: implementa set di regole specifici in un'istanza Cloud Firestore o in un Cloud Storage bucket
Firebase App Check
google_firebase_app_check_service_config
: attiva l'applicazione di App Check per un serviziogoogle_firebase_app_check_app_attest_config
: registra un'app per piattaforme Apple con il provider App Attestgoogle_firebase_app_check_device_check_config
: registra un'app per piattaforme Apple con il provider DeviceCheckgoogle_firebase_app_check_play_integrity_config
: registra un'app per Android con il provider Play Integritygoogle_firebase_app_check_recaptcha_enterprise_config
: registra un'app web con il provider reCAPTCHA Enterprisegoogle_firebase_app_check_recaptcha_v3_config
: registra un'app web con il provider reCAPTCHA v3google_firebase_app_check_debug_token
: utilizza i token di debug per i test
Firebase Extensions
google_firebase_extensions_instance
: installa o aggiorna un'istanza di un Firebase Extension
File di configurazione Terraform di esempio per casi d'uso comuni
Configura Firebase Authentication con GCIP
Questa configurazione crea un nuovo progetto Google Cloud, associato a un account Cloud Billing (il piano tariffario Blaze è obbligatorio per Firebase Authentication con GCIP), attiva 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" # Required for the project to display in a list of Firebase projects. labels = { "firebase" = "enabled" } } # Enables required APIs. resource "google_project_service" "auth" { provider = google-beta.no_user_project_override project = google_project.auth.project_id for_each = toset([ "cloudbilling.googleapis.com", "cloudresourcemanager.googleapis.com", "serviceusage.googleapis.com", "identitytoolkit.googleapis.com", ]) service = each.key # Don't disable the service if the resource block is removed by accident. disable_on_destroy = false } # Enables Firebase services for the new project created above. resource "google_firebase_project" "auth" { provider = google-beta project = google_project.auth.project_id depends_on = [ google_project_service.auth, ] } # Creates an Identity Platform config. # Also enables Firebase Authentication with Identity Platform in the project if not. resource "google_identity_platform_config" "auth" { provider = google-beta project = google_project.auth.project_id # Auto-deletes anonymous users autodelete_anonymous_users = true # Configures local sign-in methods, like anonymous, email/password, and phone authentication. sign_in { allow_duplicate_emails = true anonymous { enabled = true } email { enabled = true password_required = false } phone_number { enabled = true test_phone_numbers = { "+11231231234" = "000000" } } } # Sets an SMS region policy. sms_region_config { allowlist_only { allowed_regions = [ "US", "CA", ] } } # Configures blocking functions. blocking_functions { triggers { event_type = "beforeSignIn" function_uri = "https://us-east1-${google_project.auth.project_id}.cloudfunctions.net/before-sign-in" } forward_inbound_credentials { refresh_token = true access_token = true id_token = true } } # Configures a temporary quota for new signups for anonymous, email/password, and phone number. quota { sign_up_quota_config { quota = 1000 start_time = "" quota_duration = "7200s" } } # Configures authorized domains. authorized_domains = [ "localhost", "${google_project.auth.project_id}.firebaseapp.com", "${google_project.auth.project_id}.web.app", ] # Wait for identitytoolkit.googleapis.com to be enabled before initializing Authentication. depends_on = [ google_project_service.auth, ] } # Creates a Firebase Android App in the new project created above. resource "google_firebase_android_app" "auth" { provider = google-beta project = google_project.auth.project_id display_name = "My Android app" package_name = "android.package.name" # Wait for Firebase to be enabled in the Google Cloud project before creating this App. depends_on = [ google_firebase_project.auth, ] } # Creates a Firebase Apple-platforms App in the new project created above. resource "google_firebase_apple_app" "auth" { provider = google-beta project = google_project.auth.project_id display_name = "My Apple app" bundle_id = "apple.app.12345" # Wait for Firebase to be enabled in the Google Cloud project before creating this App. depends_on = [ google_firebase_project.auth, ] } # Creates a Firebase Web App in the new project created above. resource "google_firebase_web_app" "auth" { provider = google-beta project = google_project.auth.project_id display_name = "My Web app" # The other App types (Android and Apple) use "DELETE" by default. # Web apps don't use "DELETE" by default due to backward-compatibility. deletion_policy = "DELETE" # Wait for Firebase to be enabled in the Google Cloud project before creating this App. depends_on = [ google_firebase_project.auth, ] }
Esegui il provisioning di un servizio Firebase Data Connect
Questa configurazione crea un nuovo progetto Google Cloud, attiva i servizi Firebase per il progetto ed 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" }
Esegui il provisioning dell'istanza Firebase Realtime Database predefinita
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" # Required for the project to display in a list of Firebase projects. labels = { "firebase" = "enabled" } } # Enables required APIs. resource "google_project_service" "rtdb" { provider = google-beta.no_user_project_override project = google_project.rtdb.project_id for_each = toset([ "serviceusage.googleapis.com", "cloudresourcemanager.googleapis.com", "firebasedatabase.googleapis.com", ]) service = each.key # Don't disable the service if the resource block is removed by accident. disable_on_destroy = false } # Enables Firebase services for the new project created above. resource "google_firebase_project" "rtdb" { provider = google-beta project = google_project.rtdb.project_id } # Provisions the default Realtime Database default instance. resource "google_firebase_database_instance" "database" { provider = google-beta project = google_project.rtdb.project_id # See available locations: https://firebase.google.com/docs/database/locations region = "name-of-region" # This value will become the first segment of the database's URL. instance_id = "${google_project.rtdb.project_id}-default-rtdb" type = "DEFAULT_DATABASE" # Wait for Firebase to be enabled in the Google Cloud project before initializing Realtime Database. depends_on = [ google_firebase_project.rtdb, ] } # Creates a Firebase Android App in the new project created above. resource "google_firebase_android_app" "rtdb" { provider = google-beta project = google_project.rtdb.project_id display_name = "My Android app" package_name = "android.package.name" # Wait for Firebase to be enabled in the Google Cloud project before creating this App. depends_on = [ google_firebase_project.rtdb, ] } # Creates a Firebase Apple-platforms App in the new project created above. resource "google_firebase_apple_app" "rtdb" { provider = google-beta project = google_project.rtdb.project_id display_name = "My Apple app" bundle_id = "apple.app.12345" # Wait for Firebase to be enabled in the Google Cloud project before creating this App. depends_on = [ google_firebase_project.rtdb, ] } # Creates a Firebase Web App in the new project created above. resource "google_firebase_web_app" "rtdb" { provider = google-beta project = google_project.rtdb.project_id display_name = "My Web app" # The other App types (Android and Apple) use "DELETE" by default. # Web apps don't use "DELETE" by default due to backward-compatibility. deletion_policy = "DELETE" # Wait for Firebase to be enabled in the Google Cloud project before creating this App. depends_on = [ google_firebase_project.rtdb, ] }
Esegui il provisioning di più istanze Firebase Realtime Database
Questa configurazione crea un nuovo progetto Google Cloud, associato a un account Cloud Billing (è necessario il piano tariffario Blaze per più istanze Realtime Database), attiva 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" # Required for the project to display in a list of Firebase projects. labels = { "firebase" = "enabled" } } # Enables required APIs. resource "google_project_service" "rtdb-multi" { provider = google-beta.no_user_project_override project = google_project.rtdb-multi.project_id for_each = toset([ "cloudbilling.googleapis.com", "serviceusage.googleapis.com", "cloudresourcemanager.googleapis.com", "firebasedatabase.googleapis.com", ]) service = each.key # Don't disable the service if the resource block is removed by accident. disable_on_destroy = false } # Enables Firebase services for the new project created above. resource "google_firebase_project" "rtdb-multi" { provider = google-beta project = google_project.rtdb-multi.project_id } # Provisions the default Realtime Database default instance. resource "google_firebase_database_instance" "database-default" { provider = google-beta project = google_project.rtdb-multi.project_id # See available locations: https://firebase.google.com/docs/database/locations region = "name-of-region" # This value will become the first segment of the database's URL. instance_id = "${google_project.rtdb-multi.project_id}-default-rtdb" type = "DEFAULT_DATABASE" # Wait for Firebase to be enabled in the Google Cloud project before initializing Realtime Database. depends_on = [ google_firebase_project.rtdb-multi, ] } # Provisions an additional Realtime Database instance. resource "google_firebase_database_instance" "database-additional" { provider = google-beta project = google_project.rtdb-multi.project_id # See available locations: https://firebase.google.com/docs/projects/locations#rtdb-locations # This location doesn't need to be the same as the default database instance. region = "name-of-region" # This value will become the first segment of the database's URL. instance_id = "name-of-additional-database-instance" type = "USER_DATABASE" # Wait for Firebase to be enabled in the Google Cloud project before initializing Realtime Database. depends_on = [ google_firebase_project.rtdb-multi, ] } # Creates a Firebase Android App in the new project created above. resource "google_firebase_android_app" "rtdb-multi" { provider = google-beta project = google_project.rtdb-multi.project_id display_name = "My Android app" package_name = "android.package.name" # Wait for Firebase to be enabled in the Google Cloud project before creating this App. depends_on = [ google_firebase_project.rtdb-multi, ] } # Creates a Firebase Apple-platforms App in the new project created above. resource "google_firebase_apple_app" "rtdb-multi" { provider = google-beta project = google_project.rtdb-multi.project_id display_name = "My Apple app" bundle_id = "apple.app.12345" # Wait for Firebase to be enabled in the Google Cloud project before creating this App. depends_on = [ google_firebase_project.rtdb-multi, ] } # Creates a Firebase Web App in the new project created above. resource "google_firebase_web_app" "rtdb-multi" { provider = google-beta project = google_project.rtdb-multi.project_id display_name = "My Web app" # The other App types (Android and Apple) use "DELETE" by default. # Web apps don't use "DELETE" by default due to backward-compatibility. deletion_policy = "DELETE" # Wait for Firebase to be enabled in the Google Cloud project before creating this App. depends_on = [ google_firebase_project.rtdb-multi, ] }
Esegui il provisioning dell'istanza predefinitaCloud Firestore
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.
Esegue inoltre 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 di seed.
# Creates a new Google Cloud project. resource "google_project" "firestore" { provider = google-beta.no_user_project_override folder_id = "folder-id-for-new-project" name = "Project Display Name" project_id = "project-id-for-new-project" # Required for the project to display in a list of Firebase projects. labels = { "firebase" = "enabled" } } # Enables required APIs. resource "google_project_service" "firestore" { provider = google-beta.no_user_project_override project = google_project.firestore.project_id for_each = toset([ "cloudresourcemanager.googleapis.com", "serviceusage.googleapis.com", "firestore.googleapis.com", "firebaserules.googleapis.com", ]) service = each.key # Don't disable the service if the resource block is removed by accident. disable_on_destroy = false } # Enables Firebase services for the new project created above. resource "google_firebase_project" "firestore" { provider = google-beta project = google_project.firestore.project_id } # Provisions the Firestore database instance. resource "google_firestore_database" "firestore" { provider = google-beta project = google_project.firestore.project_id name = "(default)" # See available locations: https://firebase.google.com/docs/firestore/locations location_id = "name-of-region" # "FIRESTORE_NATIVE" is required to use Firestore with Firebase SDKs, authentication, and Firebase Security Rules. type = "FIRESTORE_NATIVE" concurrency_mode = "OPTIMISTIC" # Wait for Firebase to be enabled in the Google Cloud project before initializing Firestore. depends_on = [ google_firebase_project.firestore, ] } # Creates a ruleset of Firestore Security Rules from a local file. resource "google_firebaserules_ruleset" "firestore" { provider = google-beta project = google_project.firestore.project_id source { files { name = "firestore.rules" # Write security rules in a local file named "firestore.rules". # Learn more: https://firebase.google.com/docs/firestore/security/get-started content = file("firestore.rules") } } # Wait for Firestore to be provisioned before creating this ruleset. depends_on = [ google_firestore_database.firestore, ] } # Releases the ruleset for the Firestore instance. resource "google_firebaserules_release" "firestore" { provider = google-beta name = "cloud.firestore" # must be cloud.firestore ruleset_name = google_firebaserules_ruleset.firestore.name project = google_project.firestore.project_id # Wait for Firestore to be provisioned before releasing the ruleset. depends_on = [ google_firestore_database.firestore, ] } # Adds a new Firestore index. resource "google_firestore_index" "indexes" { provider = google-beta project = google_project.firestore.project_id collection = "quiz" query_scope = "COLLECTION" fields { field_path = "question" order = "ASCENDING" } fields { field_path = "answer" order = "ASCENDING" } # Wait for Firestore to be provisioned before adding this index. depends_on = [ google_firestore_database.firestore, ] } # Adds a new Firestore document with seed data. # Don't use real end-user or production data in this seed document. resource "google_firestore_document" "doc" { provider = google-beta project = google_project.firestore.project_id collection = "quiz" document_id = "question-1" fields = "{\"question\":{\"stringValue\":\"Favorite Database\"},\"answer\":{\"stringValue\":\"Firestore\"}}" # Wait for Firestore to be provisioned before adding this document. depends_on = [ google_firestore_database.firestore, ] } # Creates a Firebase Android App in the new project created above. resource "google_firebase_android_app" "firestore" { provider = google-beta project = google_project.firestore.project_id display_name = "My Android app" package_name = "android.package.name" # Wait for Firebase to be enabled in the Google Cloud project before creating this App. depends_on = [ google_firebase_project.firestore, ] } # Creates a Firebase Apple-platforms App in the new project created above. resource "google_firebase_apple_app" "firestore" { provider = google-beta project = google_project.firestore.project_id display_name = "My Apple app" bundle_id = "apple.app.12345" # Wait for Firebase to be enabled in the Google Cloud project before creating this App. depends_on = [ google_firebase_project.firestore, ] } # Creates a Firebase Web App in the new project created above. resource "google_firebase_web_app" "firestore" { provider = google-beta project = google_project.firestore.project_id display_name = "My Web app" # The other App types (Android and Apple) use "DELETE" by default. # Web apps don't use "DELETE" by default due to backward-compatibility. deletion_policy = "DELETE" # Wait for Firebase to be enabled in the Google Cloud project before creating this App. depends_on = [ google_firebase_project.firestore, ] }
Questo è il set di regole di Cloud Firestore Security Rules che deve trovarsi in un file locale chiamato firestore.rules
.
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /some_collection/{document} { allow read, create, update: if request.auth != null; } } }
Esegui il provisioning del bucket Cloud Storage predefinito
Esegui il provisioning di Cloud Storage bucket aggiuntivi
Questa configurazione crea un nuovo progetto Google Cloud, associato a un account Cloud Billing (è necessario il piano tariffario Blaze per i bucket aggiuntivi), attiva 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.
Esegue inoltre 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" # Required for the project to display in a list of Firebase projects. labels = { "firebase" = "enabled" } } # Enables required APIs. resource "google_project_service" "storage-multi" { provider = google-beta.no_user_project_override project = google_project.storage-multi.project_id for_each = toset([ "cloudbilling.googleapis.com", "serviceusage.googleapis.com", "cloudresourcemanager.googleapis.com", "firebaserules.googleapis.com", "firebasestorage.googleapis.com", "storage.googleapis.com", ]) service = each.key # Don't disable the service if the resource block is removed by accident. disable_on_destroy = false } # Enables Firebase services for the new project created above. resource "google_firebase_project" "storage-multi" { provider = google-beta project = google_project.storage-multi.project_id } # Provisions a Cloud Storage bucket. resource "google_storage_bucket" "bucket-1" { provider = google-beta project = google_project.storage-multi.project_id name = "name-of-storage-bucket" # See available locations: https://cloud.google.com/storage/docs/locations#available-locations location = "name-of-region-for-bucket" } # Provisions an additional Cloud Storage bucket. resource "google_storage_bucket" "bucket-2" { provider = google-beta project = google_project.storage-multi.project_id name = "name-of-additional-storage-bucket" # See available locations: https://cloud.google.com/storage/docs/locations#available-locations # This location does not need to be the same as the existing Storage bucket. location = "name-of-region-for-additional-bucket" } # Makes the first Storage bucket accessible for Firebase SDKs, authentication, and Firebase Security Rules. resource "google_firebase_storage_bucket" "bucket-1" { provider = google-beta project = google_project.storage-multi.project_id bucket_id = google_storage_bucket.bucket-1.name } # Makes the additional Storage bucket accessible for Firebase SDKs, authentication, and Firebase Security Rules. resource "google_firebase_storage_bucket" "bucket-2" { provider = google-beta project = google_project.storage-multi.project_id bucket_id = google_storage_bucket.bucket-2.name } # Creates a ruleset of Firebase Security Rules from a local file. resource "google_firebaserules_ruleset" "storage-multi" { provider = google-beta project = google_project.storage-multi.project_id source { files { # Write security rules in a local file named "storage.rules" # Learn more: https://firebase.google.com/docs/storage/security/get-started name = "storage.rules" content = file("storage.rules") } } # Wait for the Storage buckets to be provisioned before creating this ruleset. depends_on = [ google_firebase_project.storage-multi, ] } # Releases the ruleset to the first Storage bucket. resource "google_firebaserules_release" "bucket-1" { provider = google-beta name = "firebase.storage/${google_storage_bucket.bucket-1.name}" ruleset_name = "projects/${google_project.storage-multi.project_id}/rulesets/${google_firebaserules_ruleset.storage-multi.name}" project = google_project.storage-multi.project_id } # Releases the ruleset to the additional Storage bucket. resource "google_firebaserules_release" "bucket-2" { provider = google-beta name = "firebase.storage/${google_storage_bucket.bucket-2.name}" ruleset_name = "projects/${google_project.storage-multi.project_id}/rulesets/${google_firebaserules_ruleset.storage-multi.name}" project = google_project.storage-multi.project_id } # Uploads a new file to the first Storage bucket. # Do not use real end-user or production data in this file. resource "google_storage_bucket_object" "cat-picture-multi" { provider = google-beta name = "cat.png" source = "path/to/cat.png" bucket = google_storage_bucket.bucket-1.name } # Creates a Firebase Android App in the new project created above. resource "google_firebase_android_app" "storage-multi" { provider = google-beta project = google_project.storage-multi.project_id display_name = "My Android app" package_name = "android.package.name" # Wait for Firebase to be enabled in the Google Cloud project before creating this App. depends_on = [ google_firebase_project.storage-multi, ] } # Creates a Firebase Apple-platforms App in the new project created above. resource "google_firebase_apple_app" "storage-multi" { provider = google-beta project = google_project.storage-multi.project_id display_name = "My Apple app" bundle_id = "apple.app.12345" # Wait for Firebase to be enabled in the Google Cloud project before creating this App. depends_on = [ google_firebase_project.storage-multi, ] } # Creates a Firebase Web App in the new project created above. resource "google_firebase_web_app" "storage-multi" { provider = google-beta project = google_project.storage-multi.project_id display_name = "My Web app" # Wait for Firebase to be enabled in the Google Cloud project before creating this App. depends_on = [ google_firebase_project.storage-multi, ] }
Questo è il set di regole di Cloud Storage Security Rules che deve trovarsi in un file locale chiamato storage.rules
.
rules_version = '2'; service firebase.storage { match /b/{bucket}/o { match /some_folder/{fileName} { allow read, write: if request.auth != null; } } }
Proteggere una risorsa API con Firebase App Check
Questa configurazione crea un nuovo progetto Google Cloud, attiva i servizi Firebase per il progetto e configura e attiva l'applicazione forzata di Firebase App Check per Cloud Firestore in modo che sia possibile accedervi 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" # Required for the project to display in a list of Firebase projects. labels = { "firebase" = "enabled" } } # Enables required APIs. resource "google_project_service" "services" { provider = google-beta.no_user_project_override project = google_project.appcheck.project_id for_each = toset([ "cloudresourcemanager.googleapis.com", "firebase.googleapis.com", "firebaseappcheck.googleapis.com", "firestore.googleapis.com", "serviceusage.googleapis.com", ]) service = each.key # Don't disable the service if the resource block is removed by accident. disable_on_destroy = false } # Enables Firebase services for the new project created earlier. resource "google_firebase_project" "appcheck" { provider = google-beta project = google_project.appcheck.project_id depends_on = [google_project_service.services] } # Provisions the Firestore database instance. resource "google_firestore_database" "database" { provider = google-beta project = google_firebase_project.appcheck.project name = "(default)" # See available locations: https://firebase.google.com/docs/projects/locations#default-cloud-location location_id = "name-of-region" # "FIRESTORE_NATIVE" is required to use Firestore with Firebase SDKs, authentication, and Firebase Security Rules. type = "FIRESTORE_NATIVE" concurrency_mode = "OPTIMISTIC" # Wait for Firebase to be enabled in the Google Cloud project before initializing Firestore. depends_on = [ google_firebase_project.appcheck, ] } # Creates a Firebase Android App in the new project created earlier. resource "google_firebase_android_app" "appcheck" { provider = google-beta project = google_firebase_project.appcheck.project display_name = "Play Integrity app" package_name = "package.name.playintegrity" sha256_hashes = [ # TODO: insert your Android app's SHA256 certificate ] } # It takes a while for App Check to recognize the new app # If your app already exists, you don't have to wait 30 seconds. resource "time_sleep" "wait_30s" { depends_on = [google_firebase_android_app.appcheck] create_duration = "30s" } # Register the Android app with the Play Integrity provider resource "google_firebase_app_check_play_integrity_config" "appcheck" { provider = google-beta project = google_firebase_project.appcheck.project app_id = google_firebase_android_app.appcheck.app_id depends_on = [time_sleep.wait_30s, google_firestore_database.database] lifecycle { precondition { condition = length(google_firebase_android_app.appcheck.sha256_hashes) > 0 error_message = "Provide a SHA-256 certificate on the Android App to use App Check" } } } # Enable enforcement of App Check for Firestore resource "google_firebase_app_check_service_config" "firestore" { provider = google-beta project = google_firebase_project.appcheck.project service_id = "firestore.googleapis.com" depends_on = [google_project_service.services] }
Installa un'istanza di un Firebase Extension
Questa configurazione crea un nuovo progetto Google Cloud, attiva 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" # Required for the project to display in a list of Firebase projects. labels = { "firebase" = "enabled" } } # Enables required APIs. resource "google_project_service" "extensions" { provider = google-beta.no_user_project_override project = google_project.extensions.project_id for_each = toset([ "cloudbilling.googleapis.com", "cloudresourcemanager.googleapis.com", "serviceusage.googleapis.com", "firebase.googleapis.com", "firebaseextensions.googleapis.com", ]) service = each.key # Don't disable the service if the resource block is removed by accident. disable_on_destroy = false } # Enables Firebase services for the new project created above. resource "google_firebase_project" "extensions" { provider = google-beta project = google_project.extensions.project_id depends_on = [ google_project_service.extensions, ] } # Installs an instance of the "Translate Text in Firestore" extension. # Or updates the extension if the specified instance already exists. resource "google_firebase_extensions_instance" "translation" { provider = google-beta project = google_project.extensions.project_id instance_id = "translate-text-in-firestore" config { extension_ref = "firebase/firestore-translate-text" params = { COLLECTION_PATH = "posts/comments/translations" DO_BACKFILL = true LANGUAGES = "ar,en,es,de,fr" INPUT_FIELD_NAME = "input" LANGUAGES_FIELD_NAME = "languages" OUTPUT_FIELD_NAME = "translated" } system_params = { "firebaseextensions.v1beta.function/location" = "us-central1" "firebaseextensions.v1beta.function/memory" = "256" "firebaseextensions.v1beta.function/minInstances" = "0" "firebaseextensions.v1beta.function/vpcConnectorEgressSettings" = "VPC_CONNECTOR_EGRESS_SETTINGS_UNSPECIFIED" } } }
Risoluzione dei problemi e domande frequenti
Vuoi
scoprire di più su tutti i diversi attributi relativi al progetto (come
project
e user_project_override
)
Questa guida utilizza i seguenti attributi Terraform quando si lavora con "projects".
project
all'interno di un bloccoresource
Consigliato: se possibile, includi l'attributo
project
in ogniresource
bloccoSe includi un attributo del progetto, Terraform creerà l'infrastruttura specificata nel blocco delle risorse all'interno del progetto specificato. Questa guida e i nostri file di configurazione di esempio utilizzano tutti questa pratica.
Consulta la documentazione ufficiale di Terraform su
project
.user_project_override
all'interno del bloccoprovider
Per il provisioning della maggior parte delle risorse, devi utilizzare
user_project_override = true
, il che significa controllare la quota rispetto al tuo progetto Firebase. Tuttavia, per configurare il nuovo progetto in modo che possa accettare i controlli della quota, devi prima utilizzareuser_project_override = false
.Consulta la documentazione ufficiale di Terraform su
user_project_override
.
Viene visualizzato questo errore:
generic::permission_denied: Firebase Tos Not Accepted
.
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 con accesso all'account utente e tentando di visualizzare un progetto Firebase esistente nella console Firebase. Se riesci a visualizzare un progetto Firebase esistente, significa che l'account utente ha accettato i TdS di Firebase.
Se non riesci a visualizzare alcun progetto Firebase esistente, è probabile che l'account utente non abbia accettato i TdS 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 Impostazioni progetto nella console.
Dopo aver eseguito
terraform apply
, viene visualizzato questo errore:
generic::permission_denied: IAM authority does not have the
permission
.
Attendi qualche minuto e riprova a eseguire terraform apply
.
La
creazione di una risorsa non è riuscita, ma quando esegui di nuovo terraform apply
viene visualizzato il messaggio ALREADY_EXISTS
.
Ciò potrebbe essere dovuto a un ritardo nella propagazione in vari sistemi. Prova a risolvere questo
problema importando la risorsa nello stato Terraform eseguendo
terraform import
. Quindi prova a eseguire di nuovo terraform apply
.
Puoi scoprire come importare ogni risorsa nella sezione "Importazione" della documentazione di Terraform (ad esempio, la documentazione"Importazione" per Cloud Firestore).
Quando lavori con
Cloud Firestore, viene visualizzato questo errore: Error creating Index: googleapi:
Error 409;...Concurrent access -- try again
Come suggerisce l'errore, Terraform potrebbe provare a eseguire il provisioning di più indici
e/o a creare un documento contemporaneamente e aver riscontrato un errore di concorrenza.
Prova a eseguire di nuovo terraform apply
.
Viene visualizzato questo errore:
"you may need to specify 'X-Goog-User-Project' HTTP header for quota and
billing purposes"
.
Questo errore indica che Terraform non sa su 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
.
Quando crei un nuovo progetto Google Cloud, viene visualizzato l'errore che indica che l'ID progetto specificato per il nuovo progetto esiste già.
Ecco i possibili motivi per cui l'ID progetto potrebbe già esistere:
Il progetto associato a quell'ID appartiene a qualcun altro.
- Per risolvere il problema: scegli un altro ID progetto.
Il progetto associato a questo ID è stato eliminato di recente (in stato di eliminazione soft).
- Per risolvere il problema: se ritieni che il progetto associato all'ID ti appartenga, controlla il suo stato utilizzando l'API REST
projects.get
.
- Per risolvere il problema: se ritieni che il progetto associato all'ID ti appartenga, controlla il suo stato utilizzando l'API REST
Il progetto associato a quell'ID esiste correttamente per l'utente corrente. Una possibile causa dell'errore potrebbe essere che un
terraform apply
precedente sia stato interrotto.- 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
- Per risolvere il problema: esegui i seguenti comandi:
Perché devi eseguire il provisioning dell'istanza Cloud Firestore predefinita prima del bucket Cloud Storage predefinito?
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, scoprirai che il provisioning dell'istanza Cloud Firestore predefinita è già stato eseguito. 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, dovrai svuotare il
database e poi modificarne il tipo nella
console Google Cloud.
Quando
provi a eseguire il provisioning di Cloud Storage (tramite
google_app_engine_application
) e poi della tua istanza Cloud Firestore predefinita, viene visualizzato questo errore:
Error: Error creating Database: googleapi: Error 409: Database already
exists. Please use another database_id
.
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.
Poiché l'istanza Cloud Firestore predefinita del progetto è già
effettuata, google_firestore_database
restituirà un errore se provi a eseguire nuovamente il provisioning esplicito di quell'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.