1. 簡介
目標
您可以使用 Terraform 設定及管理 Firebase 專案,包括基礎架構和 Firebase 產品的程式輔助設定。
本程式碼研究室會先說明如何建構 Terraform 設定檔來建立新的 Firebase 專案,隨後說明如何設定要在這項專案中使用的應用程式和 Firebase 產品。此外,我們還會介紹 Terraform 指令列的基本概念,例如預覽要進行的變更,然後實作。
如果您想瞭解如何使用 Terraform 設定及管理 Firebase 專案和產品,歡迎參考本程式碼研究室!
課程內容
- 如何建立 Terraform 設定檔 (
*.tf
) - 如何使用 Terraform CLI 指令管理基礎架構
- 如何修改設定,以更新資源和服務
- 如何在真實網頁應用程式 (稱為友善即時通訊) 中套用設定
- 如何在不同環境 (正式環境、測試環境等) 中定義平行 (和非同步) 設定
事前準備
- 終端機/控制台
- 您選擇的 IDE/文字編輯器,例如 WebStorm、Atom、Sublime 或 VS Code
- 您選擇的瀏覽器,例如 Chrome
- Google Cloud CLI (gcloud CLI):安裝這個 CLI,並使用使用者帳戶或服務帳戶登入
如要順利使用本程式碼研究室,您必須具備基本能力,熟悉 Terraform 及其術語,包括下列必要條件:
- 安裝 Terraform,並透過官方教學課程深入瞭解 Terraform
本程式碼研究室提供真正的範例應用程式,方便您測試透過 Terraform 佈建的內容,並與之互動。為此,您需要符合以下條件:
- 網頁應用程式的程式碼範例 - 在程式碼研究室的下一個步驟中下載這段程式碼
- 套件管理員 npm (通常隨附於 Node.js) - 安裝這些工具
- Firebase CLI - 安裝這個 CLI 並登入
2. 取得範例程式碼
在本程式碼研究室中,您可以使用實體網頁應用程式,測試透過 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 專案」,請注意,每個 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
設定檔中加入下列資源區塊:
main.tf 敬上 啟用 Service Usage API 之後,新專案就能接受配額檢查!因此,對於所有後續資源佈建及啟用服務,供應商應「搭配」 使用... # 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 驗證。
- 如果採用這個選項,您必須將新專案與 Cloud Billing 帳戶建立關聯,因為 GCIP 的專案必須採用 Blaze 定價方案。
選項 1:使用 Firebase 控制台設定驗證
如要透過 Firebase 控制台設定 Firebase 驗證,您的專案不一定要採用 Blaze 定價方案。
以下說明如何設定 Firebase 驗證並使用 Google 帳戶登入:
- 在 Firebase 控制台,找到左側面板中的「建構」部分。
- 依序點選「驗證」和「開始使用」,然後點選「登入方式」分頁標籤 (或按這裡直接前往)。
- 按一下「新增供應商」,然後在「其他供應商」部分中選取「Google」。
- 將「啟用」切換鈕撥到開啟狀態。
- 將應用程式的公開名稱設為
FriendlyChat
之類的名稱 (這個名稱不必在全域範圍內重複)。 - 在下拉式選單中選擇「專案支援電子郵件」,然後按一下「儲存」。
- 您應該會看到 Google 是已啟用的登入服務供應商。
選項 2:使用 Google Cloud Identity Platform (GCIP) API 透過 Terraform 設定驗證機制
如要透過 Terraform 設定 Firebase 驗證功能,您必須使用 GCIP API,這代表專案必須採用 Blaze 定價方案。只要將 Cloud Billing 帳戶連結至專案,即可升級 Firebase 專案使用 Blaze 方案。
透過 Terraform 啟用計費功能
- 如果您還沒有 Cloud Billing 帳戶,請先前往 Google Cloud 控制台建立新帳戶。輸入 ID 時,請記下「帳單帳戶 ID」,如要找出帳單帳戶 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" } } ...
啟用 Firebase 驗證並透過 Terraform 登入 Google
- 如要透過 GCIP 佈建 Firebase 驗證,請以下列資源區塊附加
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, ] }
- 您必須擁有 OAuth 用戶端,才能使用 Google 登入功能。前往 API 與Google Cloud 控制台的「服務」專區,即可進行這項設定。
- 由於這是您第一次建立這項專案的用戶端 ID,因此您必須設定 OAuth 同意畫面。
- 開啟 OAuth 同意畫面,然後選取您剛才建立的專案。
- 將「使用者類型」設為「外部」,然後按一下「建立」。
- 在下一個畫面中,完成以下步驟,然後按一下「儲存並繼續」。
- 將應用程式公開的「應用程式名稱」設為
FriendlyChat
這類名稱 (不一定要是全域通用的名稱)。 - 從下拉式選單中選取「使用者支援電子郵件」。
- 輸入「開發人員聯絡資訊」的電子郵件地址。
- 將應用程式公開的「應用程式名稱」設為
- 在下一個畫面中,完成下列步驟:
- 接受「Scopes」頁面中的預設值,然後按一下「Save and Continue」。
- 在「測試使用者」頁面中接受預設值,然後按一下「儲存並繼續」。
- 查看摘要,然後按一下「返回資訊主頁」。
- 請按照下列步驟操作,在「憑證」頁面設定 OAuth 用戶端:
- 按一下「建立憑證」,然後選取「OAuth 用戶端 ID」。
- 在「應用程式類型」下拉式選單中,選取「網頁應用程式」。
- 在「Name」欄位中輸入應用程式名稱,例如
FriendlyChat
(名稱不必在全域範圍內重複)。 - 設定下列設定,允許應用程式的網址使用這個 OAuth 用戶端:
- 在「Authorized JavaScript origins」(已授權的 JavaScript 來源) 下方,按一下「Add URI」,然後輸入
https://<PROJECT_ID>.firebaseapp.com
,其中<PROJECT_ID>
是您在main.tf
中設定的專案 ID。 - 在「已授權的重新導向 URI」下方,按一下「新增 URI」,然後輸入
https://<PROJECT_ID>.firebaseapp.com/__/auth/handler
,其中<PROJECT_ID>
是您在main.tf
中設定的專案 ID。
- 在「Authorized JavaScript origins」(已授權的 JavaScript 來源) 下方,按一下「Add 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 控制台,找到左側面板中的「建構」部分。
- 點選「驗證」,然後點選「登入方式」分頁標籤 (或按這裡直接前往)。
- 您應該會看到 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>
變更為您要存放資料庫的區域。
在開發正式版應用程式時,建議將它設在使用者最接近使用者的地區,也應該位於 Cloud Functions 等其他 Firebase 服務中。在本程式碼研究室中,您可以使用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 控制台,找到左側面板中的「建構」部分。
- 前往「Firestore 資料庫」專區,然後按一下「規則」分頁標籤。
8. 設定 Cloud Storage 值區及其安全性規則
在本程式碼研究室的網頁應用程式中,您會將使用者共用的圖片儲存在 Cloud Storage 值區中。
- 如要啟用必要的 API 並佈建 Cloud Storage 預設值區,請附加
main.tf
檔案及下列資源區塊。
請注意,專案的預設 Cloud Storage 值區是透過 Google App Engine 佈建,且必須與 Firestore 資料庫位於相同位置。詳情請參閱「App Engine 位置」。
如要使用專案中的多個值區,請使用google_storage_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 值區的規則集。
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 值區,並部署其安全性規則。 - 請確認值區已佈建完畢,且已部署其安全性規則:
- 在 Firebase 控制台,找到左側面板中的「建構」部分。
- 前往「儲存空間」專區,然後按一下「規則」分頁標籤。
9. 在本機執行應用程式
您現在可以首次執行網頁應用程式!您將使用 Firebase 代管模擬器,在本機提供應用程式。
- 開啟新的終端機視窗,然後從
web
目錄執行下列 Firebase CLI 指令,啟動模擬器:firebase emulators:start --project=<PROJECT_ID>
- 在瀏覽器中,透過 CLI 傳回的本機網址開啟網頁應用程式 (通常為
http://localhost:5000
)。
您應該會看到 LoyaltyChat 應用程式的 UI,但目前尚無法正常運作。應用程式尚未連結至 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 才能知道您希望這些 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 取得 Firebase 設定,做為 CLI 中的「輸出值」。
- 在
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
屬性,以及使用自有值設定billing_account
屬性 (如果您是透過 Terraform 設定驗證)。 - 在
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
中繼引數的main.tf
檔案完整設定:web/terraform-checkpoints/replicate-config/main-foreach.tf
如要使用這項設定,請務必完成下列步驟:- 從
main-foreach.tf
複製設定,然後貼到main.tf
檔案中。 - 在
main.tf
檔案中執行下列操作:- 在
google_project
資源區塊中更新name
屬性、project-id
屬性,以及使用自有值設定billing_account
屬性 (如果您是透過 Terraform 設定驗證)。 - 在
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 產品 (驗證、Firestore、Cloud Storage 和安全性規則)
- 使用 Firebase 本機模擬器套件在本機執行及測試網頁應用程式
- 將 Firebase 匯入網頁應用程式
- 使用 Terraform 複製多個環境中的設定
如要進一步瞭解 Firebase 和 Terraform,請參閱說明文件。這個頁面會列出支援 Terraform 的所有 Firebase 產品、常見用途的 Terraform 設定範例,以及實用的疑難排解和常見問題。