1. 簡介
目標
您可以使用 Terraform 設定及管理 Firebase 專案,包括以程式輔助方式設定基礎架構和 Firebase 產品。
本程式碼研究室首先會說明如何建構 Terraform 設定檔來建立新的 Firebase 專案,接著說明如何設定要在該專案中使用的應用程式和 Firebase 產品。我們也會介紹 Terraform 指令列的基本概念,例如預覽即將進行的變更,然後實作這些變更。
如果您想瞭解如何使用 Terraform 設定及管理 Firebase 專案和產品,這個程式碼研究室就是為您而設!
課程內容
- 如何建立 Terraform 設定檔 (
*.tf) - 如何使用 Terraform CLI 指令管理基礎架構
 - 如何修改設定,更新資源和服務
 - 如何在實際的網頁應用程式 (稱為「Friendly Chat」) 中套用設定
 - 如何在不同環境 (實際工作環境、測試環境等) 中定義平行 (且同步) 設定
 
事前準備
- 終端機/控制台
 - 您選擇的 IDE/文字編輯器,例如 WebStorm、Atom、Sublime 或 VS Code
 - 你選擇的瀏覽器,例如 Chrome
 - Google Cloud CLI (gcloud CLI) - 安裝這個 CLI,並使用使用者帳戶或服務帳戶登入
 
如要順利完成本程式碼研究室,您必須具備 Terraform 及其術語的基本能力,包括下列先決條件:
- 安裝 Terraform,並透過官方教學課程熟悉 Terraform
 
本程式碼研究室提供實際的範例應用程式,方便您測試及互動透過 Terraform 佈建的內容。如要執行這項操作,您需要:
- 網頁應用程式的範例程式碼 - 在程式碼研究室的下一個步驟中下載這段程式碼
 - 套件管理工具 npm (通常會隨附於 Node.js) - 安裝這些工具
 - Firebase CLI - 安裝並登入這個 CLI
 
2. 取得範例程式碼
在本程式碼研究室中,您可以透過實際的 Web 應用程式,測試您透過 Terraform 佈建的內容。建議您這麼做,以便瞭解使用 Terraform 佈建資源所需的所有步驟。
從指令列複製程式碼研究室的 GitHub 存放區:
git clone https://github.com/firebase/codelab-friendlychat-web
或者,如果您未安裝 Git,可以將存放區下載為 ZIP 檔案。
3. 建立 Terraform 設定
設定 Terraform
- 在下載的範例應用程式程式碼庫中,前往 
web目錄的根目錄。 - 在該目錄的根層級,建立名為 
main.tf的 Terraform 設定檔,並進行下列初始設定:
main.tf# Terraform configuration to set up providers by version. terraform { required_providers { google-beta = { source = "hashicorp/google-beta" version = "~> 4.0" } } } # Configure the provider not to use the specified project for quota check. # This provider should only be used during project creation and initializing services. provider "google-beta" { alias = "no_user_project_override" user_project_override = false } # Configure the provider that uses the new project's quota. provider "google-beta" { user_project_override = true } 
每個 google-beta 供應商都有名為 user_project_override 的屬性,可決定如何檢查 Terraform 作業的配額。如要佈建大部分資源,請使用 user_project_override = true,也就是根據您自己的 Firebase 專案檢查配額。不過,如要設定新專案以接受配額檢查,請先使用 user_project_override=false。在程式碼研究室的後續步驟中,您可以使用 Terraform alias 語法區分這兩種供應商設定。
在目錄中初始化 Terraform
首次建立新設定時,需要下載設定中指定的供應商。
如要進行這項初始化作業,請從 main.tf 設定檔所在的目錄根層級執行下列指令:
terraform init
4. 透過 Terraform 建立 Firebase 專案
請務必記住,「建立 Firebase 專案」其實是建立 Google Cloud 專案,只是啟用 Firebase 服務。
為基礎 Google Cloud 專案和 API 新增區塊
- 首先,請佈建基礎 Google Cloud 專案。
在main.tf設定檔中,加入下列資源區塊。
您需要指定自己的專案名稱 (例如"Terraform FriendlyChat Codelab") 和專案 ID (例如"terraform-codelab-your-initials")。請注意,name值只會在 Firebase 介面中使用,不會向使用者顯示。不過,project_id值會向 Google 專屬識別您的專案,因此請務必指定專屬值。 main.tf... # Create a new Google Cloud project. resource "google_project" "default" { provider = google-beta.no_user_project_override name = "<PROJECT_NAME_OF_YOUR_PROJECT>" project_id = "<PROJECT_ID_OF_YOUR_PROJECT>" # Required for the project to display in any list of Firebase projects. labels = { "firebase" = "enabled" } } - 接著,您需要啟用必要的基礎 API:Service Usage API 和 Firebase Management API。
使用 Firebase 控制台建立 Firebase 專案時,通常會在幕後處理這項 API 啟用作業,但 Terraform 需要明確指示才能啟用。
在main.tf設定檔中 (就在建立新 Cloud 專案的區塊下方),新增下列資源區塊:
main.tf 啟用 Service Usage API 後,新專案就能接受配額檢查!因此,在後續所有資源佈建和服務啟用作業中,您都應使用供應商 with... # Enable the required underlying Service Usage API. resource "google_project_service" "serviceusage" { provider = google-beta.no_user_project_override project = google_project.default.project_id service = "serviceusage.googleapis.com" # Don't disable the service if the resource block is removed by accident. disable_on_destroy = false } # Enable the required underlying Firebase Management API. resource "google_project_service" "firebase" { provider = google-beta.no_user_project_override project = google_project.default.project_id service = "firebase.googleapis.com" # Don't disable the service if the resource block is removed by accident. disable_on_destroy = false }user_project_override(不需要別名)。 
新增方塊以啟用 Firebase 服務
「建立 Firebase 專案」的最後一個必要步驟,是在專案中啟用 Firebase 服務。
繼續在 main.tf 設定檔中新增下列資源區塊。
如上所述,請注意這個資源區塊使用的是提供者 (不需要別名)。 user_project_override
main.tf
...
# Enable Firebase services for the new project created above.
resource "google_firebase_project" "default" {
  provider = google-beta
  project = google_project.default.project_id
  # Wait until the required APIs are enabled.
  depends_on = [
    google_project_service.firebase,
    google_project_service.serviceusage,
  ]
}
在上述資源區塊中,您可能會注意到 depends_on 子句,這個子句會告知 Terraform 等待啟用基礎 API。如果沒有這個子句,Terraform 就不知道依附元件,平行佈建資源時可能會發生錯誤。
套用設定
- 如要佈建新資源並啟用設定檔中指定的 API,請從 
main.tf檔案 (應為web) 所在的目錄根層級執行下列指令:terraform apply
 - 在終端機中,Terraform 會列印要執行的動作計畫。
如果一切正常,請輸入yes核准動作。
main.tfTerraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # google_firebase_project.default will be created + resource "google_firebase_project" "default" { + display_name = (known after apply) + id = (known after apply) + project = "terraform-friendlychat-codelab" + project_number = (known after apply) } # google_project.default will be created + resource "google_project" "default" { + auto_create_network = true + id = (known after apply) + labels = { + "firebase" = "enabled" } + name = "Terraform FriendlyChat Codelab" + number = (known after apply) + project_id = "terraform-friendlychat-codelab" + skip_delete = (known after apply) } # google_project_service.firebase will be created + resource "google_project_service" "firebase" { + disable_on_destroy = false + id = (known after apply) + project = "terraform-friendlychat-codelab" + service = "firebase.googleapis.com" } # google_project_service.serviceusage will be created + resource "google_project_service" "serviceusage" { + disable_on_destroy = false + id = (known after apply) + project = "terraform-friendlychat-codelab" + service = "serviceusage.googleapis.com" } Plan: 4 to add, 0 to change, 0 to destroy. Do you want to perform these actions? Terraform will perform the actions described above. Only 'yes' will be accepted to approve. Enter a value: yes # <---- 
請注意,如果只需要預覽變更,而不需套用,可以改用 terraform plan 指令。
驗證變更
Terraform 執行完畢後,您可以執行下列指令,檢查所有 Terraform 佈建的資源和已啟用的服務狀態:
terraform show
以下是您應會看到的列印內容範例。您的狀態會包含專案專屬的值。
# google_firebase_project.default:
resource "google_firebase_project" "default" {
    display_name   = "Terraform FriendlyChat Codelab"
    id             = "projects/terraform-friendlychat-codelab"
    project        = "terraform-friendlychat-codelab"
    project_number = "000000000"
}
# google_project.default:
resource "google_project" "default" {
    auto_create_network = true
    id                  = "projects/terraform-friendlychat-codelab"
    labels              = {
        "firebase" = "enabled"
    }
    name                = "Terraform FriendlyChat Codelab"
    number              = "000000000"
    project_id          = "terraform-friendlychat-codelab"
}
# google_project_service.firebase:
resource "google_project_service" "firebase" {
    disable_on_destroy = false
    id                 = "terraform-friendlychat-codelab/firebase.googleapis.com"
    project            = "terraform-friendlychat-codelab"
    service            = "firebase.googleapis.com"
}
# google_project_service.serviceusage:
resource "google_project_service" "serviceusage" {
    disable_on_destroy = false
    id                 = "terraform-friendlychat-codelab/serviceusage.googleapis.com"
    project            = "terraform-friendlychat-codelab"
    service            = "serviceusage.googleapis.com"
}
或者,您也可以在 Firebase 控制台中查看專案,確認專案已建立。

5. 透過 Terraform 註冊 Firebase 應用程式
如要使用 Firebase,您必須在 Firebase 專案中註冊應用程式的每個平台變體。在本程式碼研究室中,您將使用實際應用程式測試透過 Terraform 佈建的項目,並與之互動。這個應用程式是網頁應用程式,因此您需要告知 Terraform 在新建立的 Firebase 專案中註冊 Firebase 網頁應用程式。
新增區塊來註冊網頁應用程式
如要在 Firebase 專案中註冊網頁應用程式,請在 main.tf 檔案中附加下列資源區塊。
您必須為網頁應用程式指定專屬的 display_name。請注意,這個名稱只會顯示在 Firebase 介面中,不會對終端使用者顯示。
main.tf
...
# Create a Firebase Web App in the new project created above.
resource "google_firebase_web_app" "default" {
  provider = google-beta
  project      = google_firebase_project.default.project
  display_name = "<DISPLAY_NAME_OF_YOUR_WEB_APP>"
  deletion_policy = "DELETE"
}
套用設定
- 如要佈建新資源,請從 
main.tf檔案所在的目錄根層級 (應為web) 執行下列指令。 請注意,這項指令不會重新建立新的 Google Cloud 專案。Terraform 會偵測到具有指定專案 ID 的專案已存在,並比較專案的目前狀態與terraform apply
.tf檔案中的內容,然後進行任何變更。 - 查看列印的行動方案。如果一切正常,請輸入 
yes並按下 Enter 鍵,核准這些動作。 
驗證變更
您可以執行下列指令,檢查新佈建資源的狀態:
terraform show
或者,您也可以在 Firebase 控制台中查看應用程式,確認是否已成功註冊至專案。前往「專案設定」,然後向下捲動至「您的應用程式」部分。
6. 設定 Firebase 驗證
驗證是任何應用程式的重要環節。如要讓使用者透過 Google 帳戶登入您的網路應用程式,可以啟用 Firebase 驗證,並設定「使用 Google 帳戶登入」方法。
請注意,在本程式碼研究室中,我們提供兩種不同的 Firebase 驗證設定選項:
- 選項 1 (建議):在控制台中設定 Firebase 驗證,不需要 GCIP。
- 使用這個選項表示您不必將新專案與 Cloud Billing 帳戶建立關聯。
 
 - 選項 2:使用 Google Cloud Identity Platform (GCIP) API,透過 Terraform 設定 Firebase Authentication。
- 使用這個選項表示您必須將新專案與 Cloud Billing 帳戶建立關聯,因為 GCIP 規定專案必須採用 Blaze 定價方案。
 
 
選項 1:使用 Firebase 控制台設定驗證
如要使用 Firebase 主控台設定 Firebase 驗證,專案不一定要採用 Blaze 定價方案。
以下說明如何設定 Firebase 驗證,並透過 Google 登入:
- 在 Firebase 控制台中,找出左側面板的「Build」部分。
 - 依序點選「Authentication」和「Get started」,然後點選「Sign-in method」分頁標籤 (或按這裡直接前往該分頁)。
 - 按一下「新增供應商」,然後在「其他供應商」部分選取「Google」。
 - 啟用「啟用」切換鈕。
 - 將應用程式的公開名稱設為類似 
FriendlyChat的名稱 (不必是全域唯一的名稱)。 - 從下拉式選單中選擇「專案支援電子郵件」,然後按一下「儲存」。

 - 您應該會看到 Google 已啟用為登入服務供應商。

 
選項 2:使用 Google Cloud Identity Platform (GCIP) API,透過 Terraform 設定驗證
如要透過 Terraform 設定 Firebase Authentication,您必須使用 GCIP API,也就是說,專案必須採用 Blaze 計費方案。如要將 Firebase 專案升級至 Blaze 方案,請將 Cloud Billing 帳戶與專案建立關聯。
透過 Terraform 啟用計費功能
- 如果沒有 Cloud Billing 帳戶,請先在 Google Cloud 控制台建立新帳戶。請記下該帳戶的帳單帳戶 ID。如要查看帳單帳戶 ID,請前往與專案相關聯的帳單帳戶 ID 帳單頁面。

 - 如要透過 Terraform 在專案中啟用帳單功能,請在 
main.tf檔案的現有google_project資源中新增billing_account屬性:
main.tf... # Create a new Google Cloud project. resource "google_project" "default" { provider = google-beta.no_user_project_override name = "<PROJECT_NAME_OF_YOUR_PROJECT>" project_id = "<PROJECT_ID_OF_YOUR_PROJECT>" billing_account = "<YOUR_BILLING_ACCOUNT_ID>" # Add this line with your Cloud Billing account ID # Required for the project to display in any list of Firebase projects. labels = { "firebase" = "enabled" } } ... 
透過 Terraform 啟用 Firebase 驗證和 Google 登入功能
- 如要使用 GCIP 佈建 Firebase Authentication,請在 
main.tf檔案中附加下列資源區塊:
main.tf... # Enable the Identity Toolkit API. resource "google_project_service" "auth" { provider = google-beta project = google_firebase_project.default.project service = "identitytoolkit.googleapis.com" # Don't disable the service if the resource block is removed by accident. disable_on_destroy = false } # Create an Identity Platform config. # Also, enable Firebase Authentication using Identity Platform (if Authentication isn't yet enabled). resource "google_identity_platform_config" "auth" { provider = google-beta project = google_firebase_project.default.project # For example, you can configure to auto-delete anonymous users. autodelete_anonymous_users = true # Wait for identitytoolkit.googleapis.com to be enabled before initializing Authentication. depends_on = [ google_project_service.auth, ] } - 如要啟用「使用 Google 帳戶登入」,您必須擁有 OAuth 用戶端。如要進行這項設定,請前往 Google Cloud Console 的「API 和服務」部分。
 - 這是您第一次為這個專案建立用戶端 ID,因此需要設定 OAuth 同意畫面。
- 開啟 OAuth 同意畫面頁面,然後選取您剛建立的專案。
 - 將「使用者類型」設為「外部」,然後按一下「建立」。
 - 在下一個畫面中,完成下列步驟,然後按一下「儲存並繼續」。
- 將應用程式的公開名稱設為類似 
FriendlyChat的名稱 (不必是全域唯一的名稱)。 - 從下拉式選單中選擇「使用者支援電子郵件」。
 - 輸入「開發人員聯絡資訊」的電子郵件地址。
 
 - 將應用程式的公開名稱設為類似 
 - 在下一個畫面中,完成下列步驟:
- 在「範圍」頁面接受預設值,然後按一下「儲存並繼續」。
 - 接受「測試使用者」頁面上的預設值,然後按一下「儲存並繼續」。
 - 查看摘要,然後按一下「返回資訊主頁」。
 

 
 - 在「憑證」頁面中設定 OAuth 用戶端,方法如下:
- 按一下「建立憑證」,然後選取「OAuth 用戶端 ID」。
 - 從「應用程式類型」下拉式選單中,選取「網頁應用程式」。
 - 在「Name」欄位中輸入應用程式名稱,例如 
FriendlyChat(不必是全域不重複的名稱)。 - 設定下列項目,允許應用程式的網址使用這個 OAuth 用戶端:
- 在「已授權的 JavaScript 來源」下方,按一下「新增 URI」,然後輸入 
https://<PROJECT_ID>.firebaseapp.com,其中<PROJECT_ID>是您在main.tf中設定的專案 ID。 - 按一下「Authorized redirect URIs」(已授權的重新導向 URI) 下方的「Add URI」(新增 URI),然後輸入 
https://<PROJECT_ID>.firebaseapp.com/__/auth/handler,其中<PROJECT_ID>是您在main.tf中設定的專案 ID。 
 - 在「已授權的 JavaScript 來源」下方,按一下「新增 URI」,然後輸入 
 - 按一下 [儲存]。
 

 - 如要使用 OAuth 用戶端 ID 和用戶端密鑰啟用 Google 登入功能,請在 
main.tf檔案中附加下列程式碼區塊:
main.tf... variable "oauth_client_secret" { type = string description = "OAuth client secret. For this codelab, you can pass in this secret through the environment variable TF_VAR_oauth_client_secret. In a real app, you should use a secret manager service." sensitive = true } resource "google_identity_platform_default_supported_idp_config" "google_sign_in" { provider = google-beta project = google_firebase_project.default.project enabled = true idp_id = "google.com" client_id = "<YOUR_OAUTH_CLIENT_ID>" client_secret = var.oauth_client_secret depends_on = [ google_identity_platform_config.auth ] } 
套用設定
- 如要根據設定檔設定驗證,請從 
main.tf檔案 (應為web) 所在的目錄根層級執行下列指令:export TF_VAR_oauth_client_secret="<YOUR_OAUTH_CLIENT_SECRET>"
 請注意,執行terraform apply
terraform apply不會重新建立新的 Google Cloud 專案。Terraform 會偵測到具有指定專案 ID 的專案已存在,並比較專案的目前狀態與.tf檔案中的內容。然後進行任何變更。 - 查看列印的行動方案。如果一切正常,請輸入 
yes並按下 Enter 鍵,核准這些動作。 
驗證變更
- 在 Firebase 控制台中,找出左側面板的「Build」部分。
 - 依序點選「Authentication」和「Sign-in method」分頁標籤 (或按這裡直接前往該分頁)。
 - 您應該會看到 Google 已啟用為登入服務供應商。

 
7. 設定 Firestore 資料庫及其安全規則
在本程式碼研究室的網頁應用程式中,您會在 Firestore 資料庫中儲存使用者之間的訊息。
- 如要啟用必要 API 並佈建資料庫執行個體,請在 
main.tf檔案中附加下列資源區塊:
main.tf... # Enable required APIs for Cloud Firestore. resource "google_project_service" "firestore" { provider = google-beta project = google_firebase_project.default.project for_each = toset([ "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 } # Provision the Firestore database instance. resource "google_firestore_database" "default" { provider = google-beta project = google_firebase_project.default.project name = "(default)" # See available locations: # https://firebase.google.com/docs/firestore/locations location_id = "<NAME_OF_DESIRED_REGION>" # "FIRESTORE_NATIVE" is required to use Firestore with Firebase SDKs, # authentication, and Firebase Security Rules. type = "FIRESTORE_NATIVE" concurrency_mode = "OPTIMISTIC" depends_on = [ google_project_service.firestore ] } - 將 
<NAME_OF_DESIRED_REGION>改為您希望資料庫所在的地區。
開發正式版應用程式時,您會希望資料庫位於大多數使用者附近的地區,並與其他 Firebase 服務 (例如 Cloud Functions) 位於同一地區。在本程式碼研究室中,您可以使用us-east1(南卡羅來納州),或使用離您最近的區域 (請參閱 Cloud Firestore 位置)。 - Firebase 可存取的每個 Firestore 資料庫執行個體,都必須受到 Firebase 安全性規則保護。
本程式碼研究室的範例程式碼會在firestore.rules檔案中提供一組安全的 Firestore 規則,您可以在web目錄的根層級找到該檔案。 - 在 
main.tf檔案中附加下列資源區塊,即可執行下列操作:- 從本機 
firestore.rules檔案建立 Firebase 安全性規則的規則集。 - 發布 Firestore 執行個體的規則集。
 
firebase deploy --only firestore:rules.
main.tf。... # Create a ruleset of Firestore Security Rules from a local file. resource "google_firebaserules_ruleset" "firestore" { provider = google-beta project = google_firebase_project.default.project source { files { name = "firestore.rules" # Write security rules in a local file named "firestore.rules". # Learn more: https://firebase.google.com/docs/firestore/security/get-started content = file("firestore.rules") } } # Wait for Firestore to be provisioned before creating this ruleset. depends_on = [ google_firestore_database.default, ] } # Release 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_firebase_project.default.project # Wait for Firestore to be provisioned before releasing the ruleset. depends_on = [ google_firestore_database.default, ] lifecycle { replace_triggered_by = [ google_firebaserules_ruleset.firestore ] } } - 從本機 
 - 執行 
terraform apply,佈建 Firestore 資料庫並部署安全性規則。 - 確認資料庫已佈建,且安全性規則已部署:
- 在 Firebase 控制台中,找出左側面板的「Build」部分。
 - 前往「Firestore Database」(Firestore 資料庫) 區段,然後按一下「Rules」(規則) 分頁標籤。
 

 
8. 設定 Cloud Storage bucket 及其安全規則
在本程式碼研究室的網頁應用程式中,您將在 Cloud Storage bucket 中儲存使用者之間共用的圖片。
- 如要啟用必要 API 並佈建 Cloud Storage 預設 bucket,請在 
main.tf檔案中附加下列資源區塊。
請注意,專案的預設 Cloud Storage bucket 是透過 Google App Engine 佈建,且必須與 Firestore 資料庫位於相同位置。詳情請參閱「App Engine 地理位置」。
如要在專案中建立多個 bucket,請使用google_storage_bucket資源佈建 bucket (本程式碼研究室未顯示)。
main.tf... # Enable required APIs for Cloud Storage for Firebase. resource "google_project_service" "storage" { provider = google-beta project = google_firebase_project.default.project for_each = toset([ "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 } # Provision the default Cloud Storage bucket for the project via Google App Engine. resource "google_app_engine_application" "default" { provider = google-beta project = google_firebase_project.default.project # See available locations: https://firebase.google.com/docs/projects/locations#default-cloud-location # This will set the location for the default Storage bucket and the App Engine App. location_id = "<NAME_OF_DESIRED_REGION_FOR_DEFAULT_BUCKET>" # Must be in the same location as Firestore (above) # Wait until Firestore is provisioned first. depends_on = [ google_firestore_database.default ] } # Make the default Storage bucket accessible for Firebase SDKs, authentication, and Firebase Security Rules. resource "google_firebase_storage_bucket" "default-bucket" { provider = google-beta project = google_firebase_project.default.project bucket_id = google_app_engine_application.default.default_bucket } - Firebase 可存取的每個 Cloud Storage 值區都必須受到 Firebase 安全性規則保護。
本程式碼研究室的範例程式碼會在storage.rules檔案中提供一組安全的 Firestore 規則,您可以在web目錄的根層級找到該檔案。 - 在 
main.tf檔案中附加下列資源區塊,即可執行下列操作:- 從本機檔案建立 Firebase 安全性規則的規則集。
 - 發布 Storage bucket 的規則集。
 
firebase deploy --only storage.
main.tf。... # Create a ruleset of Cloud Storage Security Rules from a local file. resource "google_firebaserules_ruleset" "storage" { provider = google-beta project = google_firebase_project.default.project source { files { # Write security rules in a local file named "storage.rules". # Learn more: https://firebase.google.com/docs/storage/security/get-started name = "storage.rules" content = file("storage.rules") } } # Wait for the default Storage bucket to be provisioned before creating this ruleset. depends_on = [ google_firebase_storage_bucket.default-bucket, ] } # Release the ruleset to the default Storage bucket. resource "google_firebaserules_release" "default-bucket" { provider = google-beta name = "firebase.storage/${google_app_engine_application.default.default_bucket}" ruleset_name = "projects/${google_firebase_project.default.project}/rulesets/${google_firebaserules_ruleset.storage.name}" project = google_firebase_project.default.project lifecycle { replace_triggered_by = [ google_firebaserules_ruleset.storage ] } } - 執行 
terraform apply,佈建預設的 Cloud Storage bucket 並部署其安全性規則。 - 確認已佈建 bucket,且已部署安全規則:
- 在 Firebase 控制台中,找出左側面板的「Build」部分。
 - 前往「儲存空間」部分,然後按一下「規則」分頁標籤。
 

 
9. 在本機執行應用程式
您現在可以首次執行網頁應用程式!您可以使用 Firebase Hosting 模擬器在本機提供應用程式。
- 開啟新的終端機視窗,然後從 
web目錄執行下列 Firebase CLI 指令,啟動模擬器:firebase emulators:start --project=<PROJECT_ID>
 - 在瀏覽器中,透過 CLI 傳回的本機網址 (通常是 
http://localhost:5000) 開啟網路應用程式。 
您應該會看到 FriendlyChat 應用程式的 UI,但目前還無法運作。應用程式尚未連結至 Firebase,但完成本程式碼研究室的後續步驟後,應用程式就會連結至 Firebase!
請注意,每當您變更網頁應用程式時 (例如在本程式碼研究室的後續步驟中),請重新整理瀏覽器,以使用這些變更更新本機網址。
10. 安裝、設定及初始化 Firebase
如要讓應用程式與 Firebase 搭配運作,應用程式必須具備 Firebase SDK 和 Firebase 專案的 Firebase 設定。
本程式碼研究室的範例程式碼已是可運作的應用程式,其中包含在應用程式中使用各種 Firebase 產品所需的所有依附元件和函式。如要查看已完成的作業,請參閱 web/package.json 和 web/src/index.js。
雖然範例程式碼大致完整,但您仍需完成幾項工作,才能執行應用程式,包括:安裝 Firebase SDK、啟動建構作業、將 Firebase 設定新增至應用程式,最後初始化 Firebase。
安裝 Firebase SDK 並啟動 webpack 建構作業
您需要執行幾個指令,才能開始建構應用程式。
- 開啟新的終端機視窗。
 - 確認您位於 
web目錄的根層級。 - 執行 
npm install,下載 Firebase SDK。 - 執行 
npm update更新所有依附元件。 - 執行 
npm run start啟動 webpack。 
在本程式碼研究室的其餘部分,webpack 現在會持續重建原始碼。
將 Firebase 設定新增至應用程式
您也需要在應用程式中新增 Firebase 設定,讓 Firebase SDK 知道要使用哪個 Firebase 專案。
在本程式碼研究室中,您有兩種不同的 Firebase 設定取得方式:
- 選項 1:從 Firebase 控制台取得 Firebase 設定。
 - 方法 2:透過 Terraform 取得 Firebase 設定。
 
選項 1:從 Firebase 控制台取得設定,並新增至程式碼集
- 在 Firebase 控制台中,前往「專案設定」。
 - 向下捲動至「你的應用程式」資訊卡,然後選取您的網頁應用程式。
 - 從 Firebase SDK 程式碼片段窗格中選取「Config」,然後複製設定程式碼片段。
 - 將設定貼到應用程式的 
web/src/firebase-config.js檔案中,如下所示:
firebase-config.js... const config = { apiKey: "<API_KEY>", authDomain: "<PROJECT_ID>.firebaseapp.com", projectId: "<PROJECT_ID>", storageBucket: "<PROJECT_ID>.appspot.com", messagingSenderId: "<SENDER_ID>", appId: "<APP_ID>", measurementId: "<G-MEASUREMENT_ID>", }; ... 
方法 2:透過 Terraform 取得設定,並新增至程式碼集
或者,您也可以透過 Terraform,在 CLI 中以輸出值的形式取得 Firebase 設定。
- 在 
main.tf檔案中,找出google_firebase_web_app資源區塊 (向專案註冊 Web 應用程式的區塊)。 - 在該區塊後方立即新增下列區塊:
main.tf... data "google_firebase_web_app_config" "default" { provider = google-beta project = google_firebase_project.default.project web_app_id = google_firebase_web_app.default.app_id } output "friendlychat_web_app_config" { value = { projectId = google_firebase_project.default.project appId = google_firebase_web_app.default.app_id apiKey = data.google_firebase_web_app_config.default.api_key authDomain = data.google_firebase_web_app_config.default.auth_domain storageBucket = lookup(data.google_firebase_web_app_config.default, "storage_bucket", "") messagingSenderId = lookup(data.google_firebase_web_app_config.default, "messaging_sender_id", "") measurementId = lookup(data.google_firebase_web_app_config.default, "measurement_id", "") } } ... - 由於 
data區塊和output區塊不適用於以任何方式修改基礎架構,因此您只需要執行下列指令。- 如要將網頁應用程式的 Firebase 設定載入目錄的 Terraform 狀態,請執行下列指令:
terraform refresh
 - 如要列印 Firebase 設定值,請執行下列指令:
 以下是設定的輸出範例。列印的輸出內容會包含專案和應用程式的值。terraform output –json
{ "friendlychat_web_app_config": { "sensitive": false, "type": [ "object", { "apiKey": "string", "appId": "string", "authDomain": "string", "measurementId": "string", "messagingSenderId": "string", "projectId": "string", "storageBucket": "string" } ], "value": { "apiKey": "<API_KEY>", "appId": "<APP_ID>", "authDomain": "<PROJECT_ID>.firebaseapp.com", "measurementId": "<G-MEASUREMENT_ID>", "messagingSenderId": "<SENDER_ID>", "projectId": "<PROJECT_ID>", "storageBucket": "<PROJECT_ID>.appspot.com" } } } 
 - 如要將網頁應用程式的 Firebase 設定載入目錄的 Terraform 狀態,請執行下列指令:
 - 複製 
value對應中的值。 - 將這些值 (您的設定) 貼到應用程式的 
web/src/firebase-config.js檔案中,如下所示:
firebase-config.js... const config = { apiKey: "<API_KEY>", appId: "<APP_ID>", authDomain: "<PROJECT_ID>.firebaseapp.com", measurementId: "<G-MEASUREMENT_ID>", messagingSenderId: "<SENDER_ID>", projectId: "<PROJECT_ID>", storageBucket: "<PROJECT_ID>.appspot.com", }; ... 
在應用程式中初始化 Firebase
最後,如要初始化 Firebase,請在應用程式的 web/src/index.js 檔案中附加下列內容:
...
const firebaseAppConfig = getFirebaseConfig();
initializeApp(firebaseAppConfig);
試用應用程式
Firebase 設定完成後,您就可以試用功能正常的網頁應用程式。
- 重新整理提供應用程式的瀏覽器。
 - 現在您應該可以透過 Google 登入,並開始在即時通訊中發布訊息。你甚至可以上傳圖片檔案!
 
11. 在不同環境中複製設定
Terraform 擅長管理多個設定類似的基礎架構 (例如設定與正式版專案類似的 Firebase 測試專案)。
在本程式碼研究室中,您將建立第二個 Firebase 專案做為預先發布環境。
如要複製現有設定來建立這個測試專案,有兩種做法:
- 方法 1:複製 Terraform 設定。
這個選項可讓您彈性決定複製專案與來源專案的差異程度。 - 選項 2:使用 
for_each重複使用設定。
如果各專案之間不應有顯著差異,且您想一次將變更傳播至所有專案,這個選項可提供更多程式碼重複使用機會。 
方法 1:複製 Terraform 設定
這個選項提供最大的彈性,讓複製的專案與來源專案有差異,例如應用程式的顯示名稱不同,以及推出階段性發布。
- 在 
web目錄的根層級,建立名為main_staging.tf的新 Terraform 設定檔。 - 從 
main.tf檔案複製所有資源區塊 (terraform和provider區塊除外),然後貼到main_staging.tf檔案中。 - 接著,您必須在 
main_staging.tf中修改每個複製的資源區塊,才能搭配測試專案使用:- 資源標籤:使用新名稱,避免發生衝突。舉例來說,將 
resource "google_project" "default"重新命名為resource "google_project" "staging"。 - 資源參照:更新每個參照。舉例來說,將 
google_firebase_project.default.project更新為google_firebase_project.staging.project。 
main_staging.tf檔案的完整設定:web/terraform-checkpoints/replicate-config/main_staging-copypaste.tf
如要使用這項設定,請務必執行下列操作:- 從 
main_staging-copypaste.tf複製設定,然後貼到main_staging.tf檔案中。 - 在 
main_staging.tf檔案中,執行下列操作:- 在 
google_project資源區塊中,使用您自己的值更新name屬性、project-id屬性,以及 (如果您透過 Terraform 設定驗證)billing_account屬性。 - 在 
google_firebase_web_app資源區塊中,將display_name屬性更新為您自己的值。 - 在 
google_firestore_database和google_app_engine_application資源區塊中,使用您自己的值更新location_id屬性。 
 - 在 
 
# Create a new Google Cloud project. resource "google_project" "staging" { provider = google-beta.no_user_project_override name = "<PROJECT_NAME_OF_STAGING_PROJECT>" project_id = "<PROJECT_ID_OF_STAGING_PROJECT" # Required if you want to set up Authentication via Terraform billing_account = "<YOUR_BILLING_ACCOUNT_ID>" # Required for the project to display in any list of Firebase projects. labels = { "firebase" = "enabled" } } # Enable the required underlying Service Usage API. resource "google_project_service" "staging_serviceusage" { provider = google-beta.no_user_project_override project = google_project.staging.project_id service = "serviceusage.googleapis.com" # Don't disable the service if the resource block is removed by accident. disable_on_destroy = false } # Enable the required underlying Firebase Management API. resource "google_project_service" "staging_firebase" { provider = google-beta.no_user_project_override project = google_project.staging.project_id service = "firebase.googleapis.com" # Don't disable the service if the resource block is removed by accident. disable_on_destroy = false } # Enable Firebase services for the new project created above. resource "google_firebase_project" "staging" { provider = google-beta project = google_project.staging.project_id # Wait until the required APIs are enabled. depends_on = [ google_project_service.staging_serviceusage, google_project_service.staging_firebase, ] } # Create a Firebase Web App in the new project created above. resource "google_firebase_web_app" "staging" { provider = google-beta project = google_firebase_project.staging.project display_name = "<DISPLAY_NAME_OF_YOUR_WEB_APP>" deletion_policy = "DELETE" } - 資源標籤:使用新名稱,避免發生衝突。舉例來說,將 
 - 執行 
terraform apply,佈建新的「測試」Firebase 專案和所有資源,並啟用服務。 - 如先前所述,請前往 Firebase 控制台檢查,確認所有項目都已佈建並啟用。
 
方法 2:使用 for_each 重複使用設定
如果各專案不應有顯著差異,且您想一次將變更傳播至所有專案,這個選項可提供更多程式碼重複使用機會。這項功能使用 Terraform 語言中的 for_each 中繼引數。
- 開啟 
main.tf檔案。 - 在要複製的每個資源區塊中,新增 
for_each中繼引數,如下所示:
main.tf 您可以在本程式碼研究室的 GitHub 存放區中,找到使用# Create new Google Cloud projects. resource "google_project" "default" { provider = google-beta.no_user_project_override name = each.value # Create a unique project ID for each project, with each ID starting with <PROJECT_ID>. project_id = "<PROJECT_ID>-${each.key}" # Required if you want to set up Authentication via Terraform billing_account = "<YOUR_BILLING_ACCOUNT_ID>" # Required for the projects to display in any list of Firebase projects. labels = { "firebase" = "enabled" } for_each = { prod = "<PROJECT_NAME_OF_PROD_PROJECT>" staging = "<PROJECT_NAME_OF_STAGING_PROJECT>" } } # Enable the required underlying Service Usage API. resource "google_project_service" "serviceusage" { provider = google-beta.no_user_project_override for_each = google_project.default project = each.value.project_id service = "serviceusage.googleapis.com" # Don't disable the service if the resource block is removed by accident. disable_on_destroy = false } # Enable the required underlying Firebase Management API. resource "google_project_service" "firebase" { provider = google-beta.no_user_project_override for_each = google_project.default project = each.value.project_id service = "firebase.googleapis.com" # Don't disable the service if the resource block is removed by accident. disable_on_destroy = false } # Enable Firebase services for each of the new projects created above. resource "google_firebase_project" "default" { provider = google-beta for_each = google_project.default project = each.value.project_id depends_on = [ google_project_service.serviceusage, google_project_service.firebase, ] } # Create a Firebase Web App in each of the new projects created above. resource "google_firebase_web_app" "default" { provider = google-beta for_each = google_firebase_project.default project = each.value.project # The Firebase Web App created in each project will have the same display name. display_name = "<DISPLAY_NAME_OF_YOUR_WEB_APP>" deletion_policy = "DELETE" } # NOTE: For this codelab, we recommend setting up Firebase Authentication # using the Firebase console. However, if you set up Firebase Authentication # using Terraform, copy-paste from your main.tf the applicable blocks. # Make sure to add the `for_each` meta-argument into each block. # Copy-paste from your main.tf file the applicable resource blocks # for setting up Cloud Firestore (including rules) and # for setting up Cloud Storage for Firebase (including rules). # Make sure to add the `for_each` meta-argument into each block.for_eachmeta 引數的main.tf檔案完整設定:web/terraform-checkpoints/replicate-config/main-foreach.tf
如要使用這項設定,請務必執行下列操作:- 從 
main-foreach.tf複製設定,然後貼到main.tf檔案中。 - 在 
main.tf檔案中,執行下列操作:- 在 
google_project資源區塊中,使用您自己的值更新name屬性、project-id屬性,以及 (如果您透過 Terraform 設定驗證)billing_account屬性。 - 在 
google_firebase_web_app資源區塊中,將display_name屬性更新為您自己的值。 - 在 
google_firestore_database和google_app_engine_application資源區塊中,使用您自己的值更新location_id屬性。 
 - 在 
 
 - 從 
 - 請先瞭解並修正 Terraform 解讀這項設定的方式,再套用設定,因為這與現有基礎架構不同。
- 目前,如果您套用使用 
for_each的設定,資源位址會如下所示: 不過,您在本程式碼研究室第一部分建立的現有專案,在 Terraform 中稱為:google_project.default["prod"] google_project.default["staging"] google_firebase_project.default["prod"] google_firebase_project.default["staging"] google_firebase_web_app.default["prod"] google_firebase_web_app.default["staging"]google_project.default google_firebase_project.default google_firebase_android_app.default - 執行 
terraform plan,查看 Terraform 在目前狀態下會採取哪些動作。
輸出內容應會顯示 Terraform 將刪除您在本程式碼研究室第一部分建立的專案,並建立兩個新專案。這是因為 Terraform 不知道位址google_project.default的專案已移至新位址google_project.default["prod"]。 - 如要修正這個問題,請執行 
terraform state mv指令:terraform state mv "google_project.default" "google_project.default[\"prod\"]"
 - 同樣地,如要修正所有其他資源區塊,請針對 
google_firebase_project、google_firebase_web_app和main.tf檔案中的所有其他資源區塊執行terraform state mv。 - 現在再次執行 
terraform plan時,應該不會顯示 Terraform 會刪除您在本程式碼研究室第一部分建立的專案。 
 - 目前,如果您套用使用 
 - 執行 
terraform apply,佈建新的「測試」Firebase 專案和所有資源,並啟用服務。 - 如先前所述,請前往 Firebase 控制台檢查,確認所有項目都已佈建並啟用。
 
12. 額外步驟:部署預先發布和正式版應用程式
- 在應用程式的程式碼集中,將 
firebase-config.js變更為使用暫存專案的 Firebase 設定。
如要回顧如何取得 Firebase 設定並新增至應用程式,請參閱本程式碼研究室的先前步驟「將 Firebase 設定新增至應用程式」。 - 在 
web目錄的根層級,執行下列指令,將應用程式部署至測試環境 Firebase 專案。firebase deploy --only hosting --project=<STAGING_PROJECT_ID>
 - 透過 
firebase deploy輸出內容中列印的網址,在瀏覽器中開啟預先發布的應用程式。請嘗試登入、傳送訊息及上傳圖片。
將應用程式部署至 Firebase 專案時,系統會使用實際的 Firebase 資源,而非模擬資源。與測試版應用程式互動時,您應該會在 Firebase 控制台的測試版專案中看到資料和圖片。 - 在暫存環境中測試應用程式後,請將 
firebase-config.js變更回使用正式版專案的 Firebase 設定 (您在本程式碼研究室中建立的第一個專案)。 - 在 
web目錄的根層級,執行下列指令,將應用程式部署至正式版 Firebase 專案。firebase deploy --only hosting --project=<PRODUCTION_PROJECT_ID>
 - 透過 
firebase deploy輸出內容中列印的網址,在瀏覽器中開啟正式版應用程式。嘗試登入、傳送訊息及上傳圖片。
Firebase 控制台的正式版專案中應該會顯示資料和圖片。 - 完成與這兩個應用程式的互動後,您可以停止 Firebase 放送這些應用程式。針對每個專案執行下列指令:
firebase hosting:disable --project=<STAGING_PROJECT_ID>
firebase hosting:disable --project=<PRODUCTION_PROJECT_ID>
 
13. 恭喜!
您已使用 Terraform 設定即時通訊網頁應用程式!您也已按照開發環境的最佳做法,為測試和正式環境建立個別的 Firebase 專案。
涵蓋內容
- 使用 Terraform CLI 管理雲端資源
 - 使用 Terraform 設定 Firebase 產品 (Authentication、Firestore、Cloud Storage 和 Security Rules)
 - 使用 Firebase 本機模擬器套件在本機執行及測試網頁應用程式
 - 將 Firebase 匯入網頁應用程式
 - 使用 Terraform 在多個環境中複製設定
 
如要進一步瞭解 Firebase 和 Terraform,請參閱說明文件。您可以查看支援 Terraform 的所有 Firebase 產品清單、常見用途的 Terraform 設定範例,以及實用的疑難排解和常見問題。