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
的名稱 (不必是全域唯一的名稱)。 - 從下拉式選單中選擇「使用者支援電子郵件」。
- 輸入「開發人員聯絡資訊」的電子郵件地址。
- 將應用程式的公開名稱設為類似
- 在下一個畫面中,完成下列步驟:
- 在「範圍」頁面接受預設值,然後按一下「儲存並繼續」。
- 接受「測試使用者」頁面上的預設值,然後按一下「儲存並繼續」。
- 查看摘要,然後按一下「返回資訊主頁」。
- 在「Credentials」頁面中設定 OAuth 用戶端,方法如下:
- 按一下「建立憑證」,然後選取「OAuth 用戶端 ID」。
- 從「應用程式類型」下拉式選單中,選取「網頁應用程式」。
- 在「名稱」欄位中輸入應用程式名稱,例如
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」部分,然後按一下「規則」分頁標籤。
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,且已部署安全規則:
- 在 Firebase 控制台中,找出左側面板的「Build」部分。
- 前往「儲存空間」部分,然後按一下「規則」分頁標籤。
9. 在本機執行應用程式
現在可以首次執行網頁應用程式了!您可以使用 Firebase 託管模擬器在本機提供應用程式。
- 開啟新的終端機視窗,然後從
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
資源區塊 (向專案註冊網路應用程式的區塊)。 - 在該區塊後方立即新增下列區塊:
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_each
meta 引數的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 設定範例,以及實用的疑難排解和常見問題。