透過 Terraform 設定和管理 Firebase 專案和產品

一、簡介

目標

您可以使用Terraform設定和管理 Firebase 項目,包括基礎架構和 Firebase 產品的程式配置。

此 Codelab 首先介紹如何建立 Terraform 設定檔以建立新的 Firebase 項目,然後介紹如何設定要在該專案中使用的應用程式和 Firebase 產品。我們還介紹了 Terraform 命令列的基礎知識,例如預覽要進行的更改然後實施它們。

如果您想了解如何使用 Terraform 設定和管理 Firebase 專案和產品,那麼這個 Codelab 適合您!

你將學到什麼

  • 如何建立 Terraform 設定檔 ( *.tf )
  • 如何使用 Terraform CLI 指令來管理您的基礎設施
  • 如何修改您的配置以更新您的資源和服務
  • 如何在真實的網頁應用程式上應用您的配置(稱為Friendly Chat
  • 如何在不同環境(生產、登台等)中定義並行(和同步)配置

你需要什麼

要成功使用此 Codelab,您需要基本上熟悉Terraform及其術語,包括以下先決條件:

此 Codelab 提供了一個真實的範例應用程序,以便您可以測試透過 Terraform 提供的內容並與之互動。為此,您需要以下內容:

  • Web 應用程式的範例程式碼 - 在 Codelab 的下一步中下載此程式碼
  • 套件管理器npm (通常與Node.js一起提供) - 安裝這些工具
  • Firebase CLI - 安裝此 CLI 並登入

2.獲取起始碼

在此 Codelab 中,您可以使用真實的 Web 應用程式測試透過 Terraform 提供的內容。我們建議您這樣做,以便您了解使用 Terraform 配置的資源所需的所有步驟。

從命令列克隆 Codelab 的GitHub 儲存庫

git clone https://github.com/firebase/codelab-friendlychat-web

或者,如果您沒有安裝 git,則可以將儲存庫下載為 ZIP 檔案

3. 建立 Terraform 配置

地形設定

  1. 在下載的範例應用程式的程式碼庫中,導覽至web目錄的根目錄。
  2. 在該目錄的根目錄下,使用以下初始設定建立一個名為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語法可讓您在此 Codelab 的後續步驟中區分兩個提供者設定。

在目錄中初始化Terraform

首次建立新配置需要下載配置中指定的提供者。

若要執行此初始化,請從main.tf設定檔所在目錄的根目錄執行以下命令:

terraform init

4.透過Terraform創建Firebase項目

要“建立 Firebase 項目”,請務必記住,每個 Firebase 專案實際上都是一個 Google Cloud 項目,只是為其啟用了 Firebase 服務。

為底層 Google Cloud 專案和 API 新增區塊

  1. 首先,配置底層 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"
      }
    }
    
  2. 接下來,您需要啟用所需的底層 API:服務使用 API 和 Firebase 管理 API。

    當您使用 Firebase 控制台建立 Firebase 專案時,此 API 啟用通常在幕後處理,但需要明確告知 Terraform 來執行此啟用。

    main.tf設定檔(位於建立新雲端項目的區塊下方)中,新增下列資源區塊:

    main.tf
    ...
    
    # 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
    }
    
    透過啟用服務使用 API,您的新專案將能夠接受配額檢查!因此,對於所有後續資源配置和服務啟用,您應該使用帶有user_project_override的提供者(不需要別名)。

新增區塊以啟用 Firebase 服務

「建立 Firebase 專案」所需的最後一件事是在專案上啟用 Firebase 服務。

繼續在main.tf設定檔中新增以下資源區塊。

如上所述,請注意,此資源區塊正在使用帶有user_project_override的提供者(不需要別名)。

主.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 不知道依賴關係,並且在並行配置資源時可能會遇到錯誤。

應用程式配置

  1. 若要設定新資源並啟用設定檔中指定的 API,請從main.tf檔案(應為web )所在目錄的根目錄執行以下命令:
    terraform apply
    
  2. 在終端機中,Terraform 列印它將執行的操作計劃。

    如果一切看起來都符合預期,請輸入yes批准操作。

    main.tf
    Terraform 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 控制台中查看項目來驗證該項目是否已建立。

The Terraform FriendlyChat Codelab project selected on the Firebase console

5. 透過 Terraform 註冊您的 Firebase 應用

要使用 Firebase,您需要在 Firebase 專案中註冊應用程式的每個平台變體。在此 Codelab 中,您將使用真實的應用程式來測試透過 Terraform 提供的內容並與之互動。此應用程式是一個 Web 應用程序,因此您需要告訴 Terraform 在新建立的 Firebase 專案中註冊 Firebase Web 應用程式。

新增一個區塊來註冊網路應用程式

若要在 Firebase 專案中註冊您的 Web 應用,請在main.tf檔案中附加下列資源區塊。

您需要為您的網頁應用程式指定您自己的display_name 。請注意,此名稱僅在 Firebase 介面中使用,最終使用者不可見。

主.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"
}

應用程式配置

  1. 若要設定新資源,請從main.tf檔案(應該是web )同一目錄的根目錄執行以下命令。
    terraform apply
    
    請注意,此指令不會重新建立新的 Google Cloud 專案。 Terraform 將偵測到具有指定項目 ID 的項目已存在,並將項目的目前狀態與.tf檔案中的內容進行比較,並進行發現的任何變更。
  2. 審查印刷的行動計劃。如果一切看起來都符合預期,請鍵入yes並按 Enter 鍵批准操作。

驗證更改

您可以透過執行以下命令來檢查新配置的資源的狀態:

terraform show

或者,您可以透過在 Firebase 控制台中查看該應用程式來驗證該應用程式是否已在您的專案中成功註冊。前往「專案設定」 ,然後向下捲動到「您的應用程式」部分。

6. 設定 Firebase 身份驗證

身份驗證是任何應用程式的重要組成部分。若要允許最終使用者使用其 Google 帳戶登入您的網路應用程式,您可以啟用 Firebase 驗證並設定使用 Google 方法登入。

請注意,在此 Codelab 中,我們提供了兩種不同的選項來設定 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 登入的方法:

  1. Firebase 控制台中,找到左側面板中的「建置」部分。
  2. 按一下「驗證」 ,按一下「開始」 ,然後按一下「登入方法」標籤(或按一下此處直接前往此處)。
  3. 按一下新增提供者,然後從其他提供者部分選擇Google
  4. 啟動啟用開關。
  5. 將應用程式的面向公眾的名稱設定為諸如FriendlyChat之類的名稱(不需要是全域唯一的)。
  6. 從下拉式選單中選擇項目支援電子郵件,然後按一下「儲存」Configuring Firebase Auth on the Firebase console
  7. 您應該將 Google 視為已啟用的登入提供者。 Firebase console Authentication page: Google sign-in enabled

選項 2:使用 Google Cloud Identity Platform (GCIP) API 透過 Terraform 設定身份驗證

若要透過 Terraform 設定 Firebase 驗證,您必須使用 GCIP API,這表示該專案必須包含在 Blaze 定價方案中。您可以透過將 Cloud Billing 帳號與專案關聯來升級 Firebase 專案以使用 Blaze 計劃。

透過 Terraform 啟用計費

  1. 如果您還沒有 Cloud Billing 帳號,第一步是在Google Cloud Console中建立一個新帳號。執行此操作時,請記下其計費帳戶 ID 。計費帳戶 ID 可以位於計費頁面上與您的項目關聯的計費帳戶 IDEnabling a billing account using the Google Cloud console
  2. 若要透過 Terraform 在專案中啟用計費,請將billing_account屬性新增至main.tf檔案中的現有google_project資源:

    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 登入

  1. 若要使用 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,
      ]
    }
    
  2. 啟用 Google 登入需要您擁有OAuth 用戶端。前往 Google Cloud Console 的API 和服務部分來執行此設定。
  3. 由於這是您第一次為此專案建立用戶端 ID,因此您需要設定 OAuth 同意畫面。
    1. 開啟OAuth 同意畫面頁面,然後選擇您剛剛建立的項目。
    2. 「使用者類型」設定為「外部」 ,然後按一下「建立」
    3. 在下一個畫面中,完成以下操作,然後按一下「儲存並繼續」
      • 將應用程式面向公眾的應用程式名稱設定為諸如FriendlyChat之類的名稱(不需要是全域唯一的)。
      • 從下拉式選單中選擇使用者支援電子郵件
      • 輸入開發人員聯絡資訊的電子郵件。
    4. 在接下來的畫面中,完成以下操作:
      • 接受「範圍」頁面上的預設設置,然後按一下「儲存並繼續」
      • 接受「測試使用者」頁面上的預設設置,然後按一下「儲存並繼續」
      • 查看摘要,然後按一下返回儀表板
      Configuring an OAuth2 client using the Google Cloud console
  4. 透過執行下列操作在「憑證」頁面中設定 OAuth 用戶端:
    1. 按一下建立憑證並選擇OAuth 用戶端 ID
    2. 應用程式類型下拉清單中,選擇Web 應用程式
    3. 「名稱」欄位中,輸入應用程式的名稱,例如FriendlyChat (不需要是全域唯一的)。
    4. 透過設定以下內容,允許您的應用程式的 URL 使用此 OAuth 用戶端:
      • 「授權的 JavaScript 來源」下,按一下「新增 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。
    5. 按一下「儲存」
    Obtaining the OAuth2 Client ID and secret from the Google Cloud console Credentials page
  5. 若要使用 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
      ]
    }
    

應用程式配置

  1. 若要根據您的設定驗證,請從main.tf檔案(應該是web )所在目錄的根目錄執行以下指令:
    export TF_VAR_oauth_client_secret="<YOUR_OAUTH_CLIENT_SECRET>"
    
    terraform apply
    
    請注意,執行terraform apply不會重新建立新的Google Cloud專案. Terraform 將偵測到具有指定項目 ID 的項目已存在,並將項目的目前狀態與.tf檔案中的狀態進行比較。然後它將進行它發現的任何更改。
  2. 審查印刷的行動計劃。如果一切看起來都符合預期,請鍵入yes並按 Enter 鍵批准操作。

驗證更改

  1. Firebase 控制台中,找到左側面板中的「建置」部分。
  2. 按一下「驗證」 ,然後按一下「登入方法」標籤(或按一下此處直接前往此處)。
  3. 您應該將 Google 視為已啟用的登入提供者。 Firebase console Authentication page: Google sign-in enabled

7. 設定 Firestore 資料庫及其安全性規則

對於此 Codelab 的 Web 應用,您將在 Firestore 資料庫中儲存最終使用者之間的訊息。

  1. 若要啟用所需的 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
      ]
    }
    
  2. <NAME_OF_DESIRED_REGION>變更為您希望資料庫駐留的區域。

    開發生產應用程式時,您會希望它位於靠近大多數使用者的區域,並且與其他 Firebase 服務(例如 Cloud Functions)相同。對於此 Codelab,您可以使用us-east1 (南卡羅來納州)或使用您附近的區域(請參閱Cloud Firestore 位置)。
  3. Firebase 可以存取的每個 Firestore 資料庫執行個體都必須受到Firebase 安全性規則的保護。

    此 Codelab 的範例程式碼在檔案firestore.rules中提供了一組安全 Firestore 規則,您可以在web目錄的根目錄中找到該規則。
  4. 將下列資源區塊附加到main.tf檔案以執行以下操作:
    • 從本機firestore.rules檔案建立 Firebase 安全性規則的規則集。
    • 發布 Firestore 實例的規則集。
    請注意,這些資源區塊的作用相當於點擊 Firebase 控制台中的「發布」按鈕或執行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
        ]
      }
    }
    
  5. 執行terraform apply以設定 Firestore 資料庫並部署其安全性規則。
  6. 驗證資料庫是否已配置以及其安全性規則是否已部署:
    1. Firebase 控制台中,找到左側面板中的「建置」部分。
    2. 前往Firestore 資料庫部分,然後按一下「規則」標籤。
    Verifying Cloud Firestore rules using the Firebase console

8. 設定 Cloud Storage 儲存桶及其安全規則

對於此 Codelab 的 Web 應用,您將在 Cloud Storage 儲存分區中儲存最終使用者之間共用的映像。

  1. 若要啟用所需的 API 並配置 Cloud Storage 預設儲存桶,請在main.tf檔案中附加以下資源區塊。

    請注意,您的專案的預設 Cloud Storage 儲存桶是透過 Google App Engine 預先配備的,並且必須與您的 Firestore 資料庫具有相同的位置。有關詳細信息,請參閱App Engine 位置

    如果您想要在專案中使用多個儲存桶,請使用google_storage_bucket資源(本 Codelab 中未顯示)來設定它們

    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
    }
    
  2. Firebase 可以存取的每個 Cloud Storage 儲存分區都必須受到Firebase 安全性規則的保護。

    此 Codelab 的範例程式碼在檔案storage.rules中提供了一組安全的 Firestore 規則,您可以在web目錄的根目錄中找到該規則。
  3. 將下列資源區塊附加到main.tf檔案以執行以下操作:
    • 從本機檔案建立 Firebase 安全規則的規則集。
    • 釋放儲存桶的規則集。
    請注意,這些資源區塊的作用相當於點擊 Firebase 控制台中的Publish按鈕或執行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
        ]
      }
    }
    
  4. 執行terraform apply以預配預設 Cloud Storage 儲存桶並部署其安全規則。
  5. 驗證儲存桶是否已配置以及其安全性規則是否已部署:
    1. Firebase 控制台中,找到左側面板中的「建置」部分。
    2. 轉到儲存部分,然後按一下規則標籤。
    Verifying security rules using the Firebase console

9. 在本地運行您的應用程式

您現在已準備好首次運行您的網路應用程式了!您將使用Firebase 託管模擬器在本地為您的應用程式提供服務。

  1. 開啟新的終端窗口,然後從web目錄執行以下 Firebase CLI 指令來啟動模擬器:
    firebase emulators:start --project=<PROJECT_ID>
    
  2. 在瀏覽器中,透過 CLI 傳回的本機 URL(通常http://localhost:5000 )開啟 Web 應用程式。

您應該會看到FriendlyChat 應用程式的UI,它(尚未!)運行。該應用程式尚未連接到 Firebase,但透過完成此 Codelab 的後續步驟,它將連接到!

請注意,每當您對 Web 應用程式進行變更時(就像在此 Codelab 的以下步驟中所做的那樣),請刷新瀏覽器以使用這些變更更新本機 URL。

10. 安裝、設定和初始化 Firebase

要讓應用程式與 Firebase 搭配使用,您的應用程式需要 Firebase SDK 和 Firebase 專案的 Firebase 配置。

此 Codelab 的範例程式碼已經是一個可運行的應用,具有在應用中使用各種 Firebase 產品所需的所有依賴項和功能。如果您想要查看已經完成的操作,可以查看web/package.jsonweb/src/index.js

儘管範例程式碼大部分已完成,您仍然需要執行一些操作才能運行應用程序,包括:安裝 Firebase SDK、啟動建置、將 Firebase 配置新增到應用程序,最後初始化 Firebase。

安裝 Firebase SDK 並開始建置 Webpack

您需要運行一些命令來啟動應用程式的建置。

  1. 打開一個新的終端機視窗。
  2. 確保您位於web目錄的根目錄。
  3. 執行npm install以下載 Firebase SDK。
  4. 執行npm update以更新任何依賴項。
  5. 運行npm run start啟動 webpack。

對於 Codelab 的其餘部分,webpack 現在將不斷重建您的原始程式碼。

將您的 Firebase 設定新增至您的應用

您還需要將 Firebase 配置新增到您的應用,以便 Firebase SDK 知道您希望它們使用哪個 Firebase 專案。

對於此 Codelab,您有兩種不同的選項來取得 Firebase 配置:

  • 選項 1 :從 Firebase 控制台取得您的 Firebase 配置。
  • 選項 2 :透過 Terraform 取得您的 Firebase 配置。

選項 1:從 Firebase 控制台取得配置並將其新增至您的程式碼庫

  1. 在 Firebase 控制台中,前往您的專案設定
  2. 向下捲動至「您的應用程式」卡,然後選擇您的網頁應用程式。
  3. 從 Firebase SDK 程式碼段窗格中選擇「配置」 ,然後複製配置程式碼段。
  4. 將您的配置貼到應用程式的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 中的輸出值

  1. main.tf檔案中,找到google_firebase_web_app資源區塊(在專案中註冊網路應用程式的區塊)。
  2. 緊接著該塊之後,添加以下塊:

    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", "")
      }
    }
    
    ...
    
  3. 由於data區塊和output區塊不用於以任何方式修改基礎設施,因此您只需要執行以下命令。
    1. 若要將 Web 應用程式的 Firebase 設定載入到目錄的 Terraform 狀態中,請執行下列命令:
      terraform refresh
      
    2. 若要列印 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"
          }
        }
      }
      
  4. value映射中複製值。
  5. 將這些值(您的設定)貼到應用程式的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檔案中加入以下內容:

索引.js

...

const firebaseAppConfig = getFirebaseConfig();
initializeApp(firebaseAppConfig);

試試您的應用程式

現在 Firebase 的一切都已配置完畢,您可以嘗試您的功能性 Web 應用程式了。

  1. 刷新為您的應用程式提供服務的瀏覽器。
  2. 現在您應該能夠登入 Google 並開始在聊天中發布訊息。如果您有圖像文件,甚至可以上傳它們!

11. 跨環境複製您的配置

Terraform 擅長管理多個類似配置的基礎架構(例如,設定類似產品專案的暫存 Firebase 專案)。

在此 Codelab 中,您將建立第二個 Firebase 專案作為臨時環境。

若要複製現有配置來建立此暫存項目,您有兩個選擇:

  • 選項 1 :製作 Terraform 配置的副本。
    此選項為複製項目與來源項目的差異程度提供了最大的靈活性。
  • 選項 2 :透過for_each重複使用配置。
    如果每個項目不應有顯著差異並且您希望將變更立即傳播到所有項目,則此選項可提供更多程式碼重用。

選項 1:製作 Terraform 配置的副本

此選項為複製專案與來源專案的差異程度提供了最大的靈活性,例如具有不同顯示名稱和分階段部​​署的應用程式。

  1. web目錄的根目錄中,建立一個名為main_staging.tf的新 Terraform 設定檔。
  2. main.tf檔案中複製所有資源區塊( terraformprovider者區塊除外),然後將它們貼上到main_staging.tf檔案中。
  3. 然後,您需要修改main_staging.tf中的每個複製資源區塊,以便它們與您的暫存項目一起使用:
    • 資源標籤:使用新名稱以避免衝突。例如,將resource "google_project" "default"重新命名為resource "google_project" "staging"
    • 資源參考:更新每一項。例如,將google_firebase_project.default.project更新為google_firebase_project.staging.project
    您可以在此 Codelab 的 GitHub 儲存庫中找到main_staging.tf檔案的完整配置:

    web/terraform-checkpoints/replicate-config/main_staging-copypaste.tf

    如果您想使用此配置,請確保執行以下操作:
    1. main_staging-copypaste.tf複製配置,然後將其貼上到main_staging.tf檔案中。
    2. main_staging.tf檔案中,執行以下操作:
      • google_project資源區塊中,使用您自己的值更新name屬性、 project-id屬性以及(如果您透過 Terraform 設定驗證) billing_account屬性。
      • google_firebase_web_app資源區塊中,使用您自己的值更新display_name屬性。
      • google_firestore_databasegoogle_app_engine_application資源塊中,使用您自己的值更新location_id屬性。
    main_staging.tf
    # 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"
    }
    
  4. 執行terraform apply以配置新的「暫存」Firebase 專案及其所有資源並啟用其服務。
  5. 像以前一樣在Firebase 控制台中檢查所有內容,以驗證所有內容是否已按預期配置和啟用。

選項 2:透過for_each重複使用配置

如果每個項目不應有顯著差異並且您希望將變更立即傳播到所有項目,則此選項可提供更多程式碼重用。它使用 Terraform 語言中的for_each元參數。

  1. 開啟您的main.tf檔案。
  2. 在要複製的每個資源區塊中,新增一個for_each元參數,如下所示:

    main.tf
    # 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.
    
    您可以在此 Codelab 的 GitHub 儲存庫中找到使用for_each元參數的main.tf檔案的完整配置:

    web/terraform-checkpoints/replicate-config/main-foreach.tf

    如果您想使用此配置,請確保執行以下操作:
    1. main-foreach.tf複製配置,然後將其貼上到main.tf檔案中。
    2. 在您的main.tf檔案中,執行以下操作:
      • google_project Resource區塊中,更新name屬性, project-id屬性,並且(如果透過Terraform設定驗證)具有您自己的值的billing_account屬性。
      • google_firebase_web_app資源區塊中,使用您自己的值更新display_name屬性。
      • google_firestore_databasegoogle_app_engine_application資源區塊中,用您自己的值更新location_id屬性。
  3. 與其立即套用此配置,與現有基礎結構相比,了解和修復有關Terraform如何解釋該配置的一些內容很重要。
    1. 目前,如果您套用了使用for_each的配置,資源位址將如下所示:
      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"]
      
      但是,您在此codelab的第一部分中建立的現有專案是Terraform,terraform已知:
      google_project.default
      google_firebase_project.default
      google_firebase_android_app.default
      
    2. 運行terraform plan ,以查看鑑於當前狀態將採取什麼行動Terraform。

      輸出應表示Terraform將刪除您在此Codelab第一部分中建立的項目,並建立兩個新項目。這是因為Terraform不知道地址上的項目google_project.default已移至新的地址google_project.default["prod"]
    3. 若要解決此問題,請執行terraform state mv命令:
      terraform state mv "google_project.default" "google_project.default[\"prod\"]"
      
    4. 同樣,要修復所有其他資源區塊,請為google_firebase_project執行terraform state mvgoogle_firebase_web_app以及main.tf檔案中的所有其他資源區塊。
    5. 現在,如果您再次執行terraform plan ,則不應表示Terraform會刪除您在此Codelab第一部分中建立的項目。
  4. 執行terraform apply於提供您的新「登台」火箱專案及其所有資源,並啟用其服務。
  5. 透過像以前一樣在壁爐控制台中檢查它們,驗證所有內容是否按預期進行配置和啟用。

12.獎勵步驟:部署分期和產品應用程式

  1. 在應用程式的程式碼庫中,更改firebase-config.js以使用分期專案中的firebase配置。

    若要提醒自己如何取得Firebase配置並將其新增至您的應用程式中,請參閱此Codelab的較早步驟,請將Firebase設定新增至應用程式。
  2. 在您的web目錄的根源上,執行以下命令將您的應用程式部署到登台Firebase專案。
    firebase deploy --only hosting --project=<STAGING_PROJECT_ID>
    
  3. 透過在firebase deploy輸出中列印的URL在瀏覽器中開啟您的分期應用程式。嘗試登錄,發送訊息和上傳圖像。

    當您將應用程式部署到firebase專案時,它會使用真實的firebase資源,而不是模仿資源。當您與登台應用程式進行互動時,您應該在Firebase控制台中看到資料和圖像。
  4. 在分期進行測試後,將firebase-config.js更改為使用Prod Project的Firebase Config(您在此Codelab中建立的第一個專案)。
  5. 在您的web目錄的根源上,執行以下命令將您的應用程式部署到生產Firebase專案中。
    firebase deploy --only hosting --project=<PRODUCTION_PROJECT_ID>
    
  6. 透過在firebase deploy輸出中列印的URL在瀏覽器中開啟您的生產應用程式。嘗試登錄,發送訊息和上傳圖像。

    您應該在Firebase控制台的生產專案中看到資料和映像。
  7. 完成此Codelab的兩個應用程式進行互動後,您可以阻止Firebase為它們提供服務。為您的每個專案執行以下命令:
    firebase hosting:disable --project=<STAGING_PROJECT_ID>
    
    firebase hosting:disable --project=<PRODUCTION_PROJECT_ID>
    

13.恭喜!

您已經使用Terraform配置即時聊天網路應用程式!而且,您透過建立用於分期和產品的單獨的Firebase專案來遵循開發環境的最佳實踐。

我們涵蓋的內容

  • 使用Terraform CLI管理雲端資源
  • 使用Terraform配置Firebase產品(身份驗證,Firestore,雲端儲存和安全性規則)
  • 使用Firebase本機模擬器套件在本地運行和測試Web應用程式
  • 將firebase導入Web應用程式
  • 使用Terraform在多個環境中複製配置

有關Firebase和Terraform的更多信息,請訪問我們的文件。您可以找到具有Terraform支援的所有Firebase產品的列表,常見用例的樣本Terraform配置以及有用的故障排除和FAQ。