Firebase 開始支援 Terraform。如果您的團隊希望自動化及標準化 Firebase 專案建立作業,並提供特定資源和啟用服務,建議您使用 Firebase 搭配 Terraform 使用。
搭配 Firebase 使用 Terraform 的基本工作流程包括:
建立並自訂 Terraform 設定檔 (
.tf
檔案),指定要佈建的基礎架構 (也就是要佈建的資源和要啟用的服務)。使用與 Terraform 介面的 gcloud CLI 指令,佈建
.tf
檔案中指定的基礎架構。
Terraform 和 Firebase 有哪些用途?
本指南中的一般工作流程範例是使用 Android 應用程式建立新的 Firebase 專案。不過,您可以透過 Terraform 執行更多操作,例如:
使用 Terraform 刪除及修改現有基礎架構。
使用 Terraform 管理特定產品的設定和工作,例如:
- 啟用 Firebase Authentication 登入資訊提供者。
- 建立 Cloud Storage 儲存桶或資料庫執行個體,並為其部署 Firebase Security Rules。
您可以使用標準的 Terraform 設定檔和指令完成所有這些工作。為協助您完成這項工作,我們提供幾個常見用途的 Terraform 設定檔範例。
搭配 Firebase 使用 Terraform 的一般工作流程
必要條件
本指南介紹如何在 Firebase 中使用 Terraform,因此假設您具備基本的 Terraform 操作能力。請先完成下列必要條件,再開始這個工作流程。
安裝 Terraform,並透過官方教學課程熟悉 Terraform。
安裝 Google Cloud CLI (gcloud CLI)。使用使用者帳戶或服務帳戶登入。
查看使用者帳戶和服務帳戶的相關需求
- 如果使用的是使用者帳戶,您必須接受 Firebase 服務條款 (Firebase ToS)。如果您可以在 Firebase 控制台中查看 Firebase 專案,表示您已接受 Firebase 服務條款。
- 如要讓 Terraform 執行特定動作 (例如建立專案),必須符合下列條件:
- 使用者或服務帳戶必須具備適用的 IAM 存取權,才能執行這些動作。
- 如果使用者或服務帳戶隸屬於 Google Cloud 機構,則機構政策必須允許帳戶執行這些動作。
步驟 1:建立並自訂 Terraform 設定檔
Terraform 設定檔需要兩個主要部分 (詳情請見下文):
設定 provider
無論涉及哪些 Firebase 產品或服務,都必須設定 provider
。
在本機目錄中建立 Terraform 設定檔 (例如
main.tf
檔案)。在本指南中,您將使用這個設定檔來指定
provider
設定,以及您希望 Terraform 建立的所有基礎架構。不過,您可以選擇如何納入供應器設定。查看如何納入
provider
設定的選項您可以透過下列選項,將
provider
設定納入其他 Terraform 設定:選項 1:在單一 Terraform
.tf
設定檔頂端加入此值 (如本指南所示)。- 如果您剛開始使用 Terraform,或只是想透過 Firebase 試用 Terraform,請使用這個選項。
選項 2:除了您指定要建立基礎架構的
.tf
檔案 (例如main.tf
檔案) 外,請在獨立的.tf
檔案 (例如provider.tf
檔案) 中加入該值。- 如果您是需要將設定標準化的大型團隊成員,請使用這個選項。
- 執行 Terraform 指令時,
provider.tf
檔案和main.tf
檔案必須位於相同目錄中。
在
main.tf
檔案頂端加入下列provider
設定。您必須使用
google-beta
供應工具,因為這是使用 Firebase 與 Terraform 的 Beta 版。在實際工作環境中使用時請謹慎小心。# 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 }
進一步瞭解在 Firebase 中使用 Terraform 時的不同類型的專案相關屬性 (包括本指南所稱的「配額檢查專案」)。
請繼續閱讀下一節,完成設定檔並指定要建立的基礎架構。
使用 resource
區塊指定要建立的基礎架構
在 Terraform 設定檔 (本指南的 main.tf
檔案) 中,您需要指定要讓 Terraform 建立的所有基礎架構 (也就是您要佈建的所有資源,以及要啟用的所有服務)。您可以在本指南中查看支援 Terraform 的所有 Firebase 資源完整清單。
開啟
main.tf
檔案。在
provider
設定下方,加入下列resource
區塊的設定。這個基本範例會建立新的 Firebase 專案,然後在該專案中建立 Firebase Android 應用程式。
# 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, ] }
查看此設定檔範例的註解版本
如果您不熟悉專案和應用程式資源的基礎架構,請參閱下列說明文件:
- 瞭解 Firebase 專案
- 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, ] }
步驟 2:執行 Terraform 指令,建立指定的基礎架構
如要佈建資源並啟用 main.tf
檔案中指定的服務,請在 main.tf
檔案所在的目錄中執行下列指令。如要進一步瞭解這些指令,請參閱 Terraform 說明文件。
如果這是您第一次在目錄中執行 Terraform 指令,則需要初始化設定目錄並安裝 Google Terraform 供應器。執行下列指令即可:
terraform init
執行下列指令,建立
main.tf
檔案中指定的基礎架構:terraform apply
確認所有項目是否已如預期佈建或啟用:
選項 1:執行下列指令,查看終端機顯示的設定:
terraform show
選項 2:在 Firebase 控制台中查看 Firebase 專案。
支援 Terraform 的 Firebase 資源
下列 Firebase 和 Google 資源支援 Terraform。我們會持續新增更多資源!因此,如果您找不到要使用 Terraform 管理的資源,請盡快再次查看是否可用,或在 GitHub 存放區中提出問題。
Firebase 專案和應用程式管理
google_firebase_project
:在現有的 Google Cloud 專案中啟用 Firebase 服務Firebase 應用程式
google_firebase_apple_app
:建立或管理 Firebase Apple 平台應用程式google_firebase_android_app
:建立或管理 Firebase Android 應用程式google_firebase_web_app
:建立或管理 Firebase 網頁應用程式
Firebase Authentication
google_identity_platform_config
:啟用 Google Cloud Identity Platform (GCIP) (Firebase Authentication 的後端),並提供專案層級的驗證設定如要透過 Terraform 設定 Firebase Authentication,您必須啟用 GCIP。請務必查看範例
.tf
檔案,瞭解如何設定 Firebase Authentication。在 Terraform 啟用 GCIP 和/或 Firebase Authentication 的專案必須採用 Blaze 價格方案 (也就是說,專案必須有相關聯的 Cloud Billing 帳戶)。您可以透過程式輔助方式,在
google_project
資源中設定billing_account
屬性。這個資源也支援更多設定,例如匿名、電子郵件/密碼和電話驗證等本機登入方法,以及封鎖函式和授權網域。
google_identity_platform_default_supported_idp_config
:設定 Google、Facebook 或 Apple 等常見的聯合身分識別資訊提供者identity_platform_oauth_idp_config
- 設定任意 OAuth 身分識別資訊提供者 (IdP) 來源google_identity_platform_inbound_saml_config
- 設定 SAML 整合
尚未支援:
- 透過 Terraform 設定多重驗證 (MFA)
Firebase Data Connect
google_firebase_data_connect_service
- 建立 Data Connect 服務
Firebase Realtime Database
google_firebase_database_instance
- 建立 Realtime Database 例項
尚未支援:
- 透過 Terraform 部署 Firebase Realtime Database Security Rules (瞭解如何使用其他工具部署這些 Rules,包括程式設計選項)
Cloud Firestore
google_firestore_database
- 建立 Cloud Firestore 例項google_firestore_index
:啟用 Cloud Firestore 的效率查詢google_firestore_document
:使用集合中的特定文件為 Cloud Firestore 例項播種重要事項:請勿在這個種子文件中使用實際的使用者或正式版資料。
Cloud Storage for Firebase
google_firebase_storage_bucket
:讓現有的 Cloud Storage 儲存體可供 Firebase SDK、驗證和 Firebase Security Rules 存取google_storage_bucket_object
:將物件新增至 Cloud Storage 值區重要事項:請勿在這個檔案中使用實際的使用者或實際生產資料。
Firebase Security Rules (適用於 Cloud Firestore 和 Cloud Storage)
請注意,Firebase Realtime Database 會為其 Firebase Security Rules 使用不同的佈建系統。
google_firebaserules_ruleset
:定義套用至 Cloud Firestore 例項或 Cloud Storage 值區的 Firebase Security Rulesgoogle_firebaserules_release
:將特定規則集部署至 Cloud Firestore 執行個體或 Cloud Storage 值區
Firebase App Check
google_firebase_app_check_service_config
:為服務啟用 App Check 強制執行google_firebase_app_check_app_attest_config
:向 App Attest 供應商註冊 Apple 平台應用程式google_firebase_app_check_device_check_config
:向 DeviceCheck 供應商註冊 Apple 平台應用程式google_firebase_app_check_play_integrity_config
:向 Play Integrity 供應商註冊 Android 應用程式google_firebase_app_check_recaptcha_enterprise_config
:向 reCAPTCHA Enterprise 供應商註冊網頁應用程式google_firebase_app_check_recaptcha_v3_config
:向 reCAPTCHA v3 供應商註冊網頁應用程式google_firebase_app_check_debug_token
- 使用偵錯權杖進行測試
Firebase Extensions
google_firebase_extensions_instance
:安裝或更新 Firebase Extension 的例項
常見用途的 Terraform 設定檔範例
使用 GCIP 設定 Firebase Authentication
這個設定會建立新的 Google Cloud 專案,並將專案與 Cloud Billing 帳戶建立關聯 (Firebase Authentication 需要使用 GCIP 的 Blaze 定價方案),為專案啟用 Firebase 服務,使用 GCIP 設定 Firebase Authentication,並將三種不同的應用程式類型註冊至專案。
請注意,您必須啟用 GCIP,才能透過 Terraform 設定 Firebase Authentication。
# 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, ] }
佈建 Firebase Data Connect 服務
這個設定會建立新的 Google Cloud 專案、為專案啟用 Firebase 服務,並佈建 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" }
佈建預設 Firebase Realtime Database 執行個體
這個設定會建立新的 Google Cloud 專案、為專案啟用 Firebase 服務、佈建專案的預設 Realtime Database 例項,並將三種不同的應用程式類型註冊至專案。
# 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, ] }
佈建多個 Firebase Realtime Database 執行個體
這個設定會建立新的 Google Cloud 專案,並將專案與 Cloud Billing 帳戶建立關聯 (多個 Realtime Database 執行個體需要使用 Blaze 定價方案),為專案啟用 Firebase 服務、佈建多個 Realtime Database 執行個體 (包括專案的預設 Realtime Database 執行個體),以及在專案中註冊三種不同的應用程式類型。
# 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, ] }
佈建預設 Cloud Firestore 執行個體
這個設定會建立新的 Google Cloud 專案、為專案啟用 Firebase 服務、佈建專案的預設 Cloud Firestore 例項,並將三種不同的應用程式類型註冊至專案。
它也會為預設 Cloud Firestore 例項提供 Firebase Security Rules、建立 Cloud Firestore 索引,以及新增含有種子資料的 Cloud Firestore 文件。
# 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, ] }
這是 Cloud Firestore Security Rules 的規則集,應位於名為 firestore.rules
的本機檔案中。
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /some_collection/{document} { allow read, create, update: if request.auth != null; } } }
佈建預設 Cloud Storage 值區
佈建其他 Cloud Storage 值區
這個設定會建立新的 Google Cloud 專案,並將專案與 Cloud Billing 帳戶建立關聯 (需要 Blaze 定價方案才能使用其他桶),為專案啟用 Firebase 服務、佈建其他非預設 Cloud Storage 桶,並在專案中註冊三種不同的應用程式類型。
它也會為每個 Cloud Storage bucket 佈建 Firebase Security Rules,並將檔案上傳至其中一個 Cloud Storage bucket。
# 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, ] }
這是 Cloud Storage Security Rules 的規則集,應位於名為 storage.rules
的本機檔案中。
rules_version = '2'; service firebase.storage { match /b/{bucket}/o { match /some_folder/{fileName} { allow read, write: if request.auth != null; } } }
使用 Firebase App Check 保護 API 資源
這個設定會建立新的 Google Cloud 專案,為專案啟用 Firebase 服務,並設定並啟用 Firebase App Check 的 Cloud Firestore 強制執行機制,讓使用者只能透過 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] }
安裝 Firebase Extension 的例項
這個設定會建立新的 Google Cloud 專案、為專案啟用 Firebase 服務,並在專案中安裝新的 Firebase Extension 例項。如果執行個體已存在,其參數會根據設定檔中提供的值進行更新。
# 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" } } }
疑難排解與常見問題
您想進一步瞭解所有不同的專案相關屬性 (例如 project
和 user_project_override
)
本指南在處理「projects」時,會使用下列 Terraform 屬性。
resource
區塊中的project
建議做法:盡可能在每個
resource
區塊中加入project
屬性只要加入專案屬性,Terraform 就會在指定專案內的資源區塊中建立指定基礎架構。本指南和設定檔範例都採用這種做法。
請參閱
project
的官方 Terraform 說明文件。provider
區塊中的user_project_override
如要配置大部分資源,您應使用
user_project_override = true
,也就是根據自己的 Firebase 專案檢查配額。不過,如要設定新專案,讓專案接受配額檢查,您必須先使用user_project_override = false
。請參閱
user_project_override
的官方 Terraform 說明文件。
您會收到以下錯誤:
generic::permission_denied: Firebase Tos Not Accepted
。
請確認您用來執行 gcloud CLI 指令的使用者帳戶已接受 Firebase 服務條款 (Firebase ToS)。
您可以使用已登入使用者帳戶的瀏覽器,嘗試在 Firebase 控制台中查看現有的 Firebase 專案,藉此進行檢查。如果您可以查看現有的 Firebase 專案,表示使用者帳戶已接受 Firebase 服務條款。
如果您無法查看任何現有的 Firebase 專案,表示使用者帳戶可能尚未接受 Firebase 服務條款。如要修正這個問題,請透過 Firebase 控制台建立新的 Firebase 專案,並在建立專案時接受 Firebase 服務條款。您可以立即透過控制台的「專案設定」刪除這個專案。
執行 terraform apply
後,您會收到以下錯誤訊息:generic::permission_denied: IAM authority does not have the
permission
。
請稍候幾分鐘,然後再嘗試執行 terraform apply
。
建立資源失敗,但再次執行 terraform apply
時,會顯示 ALREADY_EXISTS
。
這可能是因為各系統的傳播延遲。請嘗試執行 terraform import
,將資源匯入 Terraform 狀態,以解決這個問題。然後再試一次。terraform apply
如要瞭解如何匯入各項資源,請參閱 Terraform 說明文件中的「Import」一節 (例如 Cloud Firestore 的「Import」說明文件)。
使用 Cloud Firestore 時,您會收到以下錯誤:Error creating Index: googleapi:
Error 409;...Concurrent access -- try again
如錯誤訊息所示,Terraform 可能會嘗試同時佈建多個索引和/或建立文件,並發生並行錯誤。請嘗試再次執行 terraform apply
。
您會收到以下錯誤:"you may need to specify 'X-Goog-User-Project' HTTP header for quota and
billing purposes"
。
這個錯誤表示 Terraform 不知道要針對哪個專案檢查配額。如要排解問題,請在 resource
區塊中檢查下列項目:
- 請確認你已為
project
屬性指定值。 - 請確認您使用的是
user_project_override = true
(沒有別名) 的供應器,在 Firebase 範例中為google-beta
。
建立新的 Google Cloud 專案時,您會收到錯誤訊息,指出為新專案指定的專案 ID 已存在。
以下是專案 ID 可能已存在的可能原因:
與該 ID 相關聯的專案屬於其他使用者。
- 解決方法:請選擇其他專案 ID。
與該 ID 相關聯的專案最近已遭刪除 (處於軟刪除狀態)。
- 解決方法:如果您認為與 ID 相關聯的專案屬於您,請使用
projects.get
REST API 檢查專案狀態。
- 解決方法:如果您認為與 ID 相關聯的專案屬於您,請使用
與該 ID 相關聯的專案確實存在於目前使用者下。發生這項錯誤的可能原因可能是先前的
terraform apply
遭到中斷。- 解決方法:請執行下列指令:
terraform import google_project.default PROJECT_ID
然後
terraform import google_firebase_project.default PROJECT_ID
- 解決方法:請執行下列指令:
為什麼需要在預設 Cloud Storage 值區之前,先佈建預設 Cloud Firestore 執行個體?
如果您在嘗試佈建預設 Cloud Firestore 執行個體之前,已透過 google_app_engine_application
佈建預設 Cloud Storage 儲存體,您會發現預設 Cloud Firestore 執行個體已佈建完成。請注意,已佈建的資料庫執行個體處於 Datastore 模式,這表示 Firebase SDK、驗證或 Firebase Security Rules 無法存取該執行個體。如果您想搭配這些 Firebase 服務使用 Cloud Firestore,就必須清空資料庫,然後在 Google Cloud 控制台中變更資料庫類型。
嘗試透過 google_app_engine_application
佈建 Cloud Storage 和預設 Cloud Firestore 執行個體時,您會收到以下錯誤訊息:Error: Error creating Database: googleapi: Error 409: Database already
exists. Please use another database_id
。
當您透過 google_app_engine_application
佈建專案的預設 Cloud Storage 值區,且專案尚未有預設 Cloud Firestore 執行個體時,google_app_engine_application
會自動佈建專案的預設 Cloud Firestore 執行個體。
因此,由於專案的預設 Cloud Firestore 例項「已」佈建,如果您嘗試再次明確佈建該預設例項,google_firestore_database
就會發生錯誤。
專案的預設 Cloud Firestore 例項佈建完成後,您就無法「重新佈建」或變更位置。請注意,已佈建資料庫例項處於 Datastore 模式,這表示 Firebase SDK、驗證或 Firebase Security Rules 無法存取該資料庫。如果您想搭配這些 Firebase 服務使用 Cloud Firestore,就必須清空資料庫,然後在 Google Cloud 控制台中變更資料庫類型。