Thiết lập và quản lý các dự án cũng như sản phẩm Firebase thông qua Terraform

1. Giới thiệu

Bàn thắng

Bạn có thể sử dụng Terraform để thiết lập và quản lý một dự án Firebase, bao gồm cả cấu hình theo chương trình của cơ sở hạ tầng và các sản phẩm của Firebase.

Trước tiên, lớp học lập trình này mô tả cách tạo tệp cấu hình Terraform để tạo một dự án Firebase mới, sau đó là cách định cấu hình các ứng dụng và sản phẩm Firebase mà bạn muốn sử dụng trong dự án đó. Chúng tôi cũng đề cập đến những kiến thức cơ bản về dòng lệnh Terraform, chẳng hạn như xem trước những thay đổi sẽ được thực hiện rồi triển khai những thay đổi đó.

Nếu bạn muốn tìm hiểu cách thiết lập và quản lý các dự án cũng như sản phẩm của Firebase bằng Terraform, thì lớp học lập trình này chính là dành cho bạn!

Kiến thức bạn sẽ học được

  • Cách tạo tệp cấu hình Terraform (*.tf)
  • Cách sử dụng các lệnh Terraform CLI để quản lý cơ sở hạ tầng
  • Cách sửa đổi cấu hình để cập nhật tài nguyên và dịch vụ
  • Cách áp dụng cấu hình của bạn trên một ứng dụng web thực (gọi là Friendly Chat)
  • Cách xác định các cấu hình song song (và đồng bộ) trong nhiều môi trường (sản xuất, dàn dựng, v.v.)

Bạn cần có

Để hoàn thành lớp học lập trình này, bạn cần có kiến thức cơ bản về Terraform và thuật ngữ của Terraform, bao gồm cả các điều kiện tiên quyết sau:

  • Cài đặt Terraform và làm quen với Terraform bằng các hướng dẫn chính thức của họ

Lớp học lập trình này cung cấp một ứng dụng mẫu thực tế để bạn có thể kiểm thử và tương tác với những gì bạn cung cấp thông qua Terraform. Để làm được việc này, bạn cần có:

  • Mã mẫu cho một ứng dụng web – tải mã này xuống trong bước tiếp theo của lớp học lập trình
  • Trình quản lý gói npm (thường đi kèm với Node.js) – cài đặt các công cụ này
  • Firebase CLI – cài đặt CLI này và đăng nhập

2. Lấy mã khởi đầu

Trong lớp học lập trình này, bạn có thể kiểm thử những gì bạn cung cấp thông qua Terraform bằng một ứng dụng web thực. Bạn nên làm việc này để hiểu rõ tất cả các bước cần thiết để sử dụng các tài nguyên do Terraform cung cấp.

Sao chép kho lưu trữ GitHub của lớp học lập trình từ dòng lệnh:

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

Ngoài ra, nếu chưa cài đặt git, bạn có thể tải kho lưu trữ xuống dưới dạng tệp ZIP.

3. Tạo cấu hình Terraform

Thiết lập Terraform

  1. Trong cơ sở mã của ứng dụng mẫu đã tải xuống, hãy chuyển đến gốc của thư mục web.
  2. Ở thư mục gốc của thư mục đó, hãy tạo một tệp cấu hình Terraform có tên là main.tf với chế độ thiết lập ban đầu sau đây:

    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
    }
    

Mỗi nhà cung cấp google-beta đều có một thuộc tính tên là user_project_override. Thuộc tính này xác định cách Terraform sẽ kiểm tra hạn mức của các thao tác. Để cung cấp hầu hết các tài nguyên, bạn nên sử dụng user_project_override = true, tức là kiểm tra hạn mức đối với dự án Firebase của riêng bạn. Tuy nhiên, để thiết lập dự án mới sao cho dự án đó có thể chấp nhận các lượt kiểm tra hạn mức, trước tiên, bạn cần sử dụng user_project_override=false. Cú pháp alias của Terraform cho phép bạn phân biệt giữa hai chế độ thiết lập nhà cung cấp trong các bước tiếp theo của lớp học lập trình này.

Khởi chạy Terraform trong thư mục

Khi tạo một cấu hình mới lần đầu tiên, bạn cần tải nhà cung cấp được chỉ định trong cấu hình xuống.

Để thực hiện quá trình khởi chạy này, hãy chạy lệnh sau từ gốc của cùng một thư mục với tệp cấu hình main.tf:

terraform init

4. Tạo dự án Firebase thông qua Terraform

Để "tạo một dự án Firebase", bạn cần nhớ rằng mỗi dự án Firebase thực chất là một dự án Google Cloud, chỉ khác là dự án đó có bật các dịch vụ của Firebase.

Thêm các khối cho dự án và API cơ bản trên Google Cloud

  1. Trước tiên, hãy cung cấp dự án cơ bản trên Google Cloud.

    Vào tệp cấu hình main.tf, hãy thêm khối tài nguyên sau.

    Bạn cần chỉ định tên dự án của riêng mình (chẳng hạn như "Terraform FriendlyChat Codelab") và mã dự án của riêng mình (chẳng hạn như "terraform-codelab-your-initials"). Xin lưu ý rằng giá trị name chỉ được dùng trong các giao diện Firebase và người dùng cuối không nhìn thấy giá trị này. Tuy nhiên, giá trị project_id xác định dự án của bạn một cách duy nhất với Google, vì vậy, hãy đảm bảo rằng bạn chỉ định một giá trị duy nhất. 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. Tiếp theo, bạn cần bật các API cơ bản bắt buộc: Service Usage API và Firebase Management API.

    Việc bật API này thường được xử lý ngầm khi bạn sử dụng bảng điều khiển Firebase để tạo một dự án Firebase, nhưng bạn cần chỉ định rõ ràng cho Terraform thực hiện việc bật này.

    Vào tệp cấu hình main.tf (ngay bên dưới khối tạo dự án Cloud mới), hãy thêm khối tài nguyên sau:

    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
    }
    
    Khi bật Service Usage API, dự án mới của bạn sẽ có thể chấp nhận các lượt kiểm tra hạn mức! Vì vậy, đối với tất cả các hoạt động cung cấp tài nguyên và bật dịch vụ sau đó, bạn nên sử dụng nhà cung cấp với user_project_override (không cần bí danh).

Thêm một khối để bật các dịch vụ của Firebase

Điều kiện cuối cùng cần thiết để "tạo một dự án Firebase" là bật các dịch vụ Firebase trên dự án.

Tiếp tục trong tệp cấu hình main.tf, hãy thêm khối tài nguyên sau.

Như đã đề cập ở trên, xin lưu ý rằng khối tài nguyên này đang sử dụng nhà cung cấp với user_project_override (không cần bí danh).

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,
  ]
}

Trong khối tài nguyên ở trên, bạn có thể nhận thấy mệnh đề depends_on. Mệnh đề này yêu cầu Terraform đợi cho đến khi các API cơ bản được bật. Nếu không có mệnh đề này, Terraform sẽ không biết về phần phụ thuộc và có thể gặp lỗi khi cung cấp tài nguyên song song.

Áp dụng cấu hình

  1. Để cung cấp các tài nguyên mới và bật các API được chỉ định trong tệp cấu hình, hãy chạy lệnh sau từ gốc của cùng thư mục với tệp main.tf (phải là web):
    terraform apply
    
  2. Trong thiết bị đầu cuối, Terraform sẽ in một kế hoạch hành động mà nó sẽ thực hiện.

    Nếu mọi thứ diễn ra như dự kiến, hãy phê duyệt các hành động bằng cách nhập 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 # <----
    

Xin lưu ý rằng nếu chỉ cần xem trước các thay đổi mà không cần áp dụng, bạn có thể sử dụng lệnh terraform plan.

Xác thực các thay đổi

Sau khi Terraform chạy xong, bạn có thể kiểm tra trạng thái của tất cả các tài nguyên được cung cấp bởi Terraform và các dịch vụ được bật bằng cách chạy lệnh sau:

terraform show

Sau đây là ví dụ về nội dung bạn sẽ thấy được in. Trạng thái của bạn sẽ chứa các giá trị dành riêng cho dự án của bạn.

# 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"
}

Ngoài ra, bạn có thể xác minh rằng dự án đã được tạo bằng cách xem dự án đó trong bảng điều khiển của Firebase.

Dự án Terraform FriendlyChat Codelab được chọn trên bảng điều khiển Firebase

5. Đăng ký ứng dụng Firebase thông qua Terraform

Để sử dụng Firebase, bạn cần đăng ký từng biến thể nền tảng của ứng dụng trong dự án Firebase. Trong lớp học lập trình này, bạn sẽ sử dụng một ứng dụng thực để kiểm thử và tương tác với những gì bạn cung cấp thông qua Terraform. Đây là một ứng dụng web, vì vậy bạn cần yêu cầu Terraform đăng ký một Ứng dụng web Firebase trong dự án Firebase mới tạo.

Thêm một khối để đăng ký ứng dụng web

Để đăng ký ứng dụng web trong dự án Firebase, hãy thêm khối tài nguyên sau vào tệp main.tf.

Bạn cần chỉ định display_name của riêng mình cho ứng dụng web. Xin lưu ý rằng tên này chỉ được dùng trong các giao diện Firebase và người dùng cuối sẽ không nhìn thấy.

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

Áp dụng cấu hình

  1. Để cung cấp tài nguyên mới, hãy chạy lệnh sau từ thư mục gốc của cùng một thư mục với tệp main.tf (phải là web).
    terraform apply
    
    Xin lưu ý rằng lệnh này sẽ không tạo lại một dự án Google Cloud mới. Terraform sẽ phát hiện thấy một dự án có mã dự án được chỉ định đã tồn tại, đồng thời so sánh trạng thái hiện tại của dự án với nội dung trong tệp .tf và thực hiện mọi thay đổi mà nó tìm thấy.
  2. Xem lại kế hoạch hành động đã in. Nếu mọi thứ đều như mong đợi, hãy nhập yes rồi nhấn Enter để phê duyệt các thao tác.

Xác thực các thay đổi

Bạn có thể kiểm tra trạng thái của tài nguyên vừa được cấp phép bằng cách chạy lệnh sau:

terraform show

Ngoài ra, bạn có thể xác minh rằng ứng dụng đã được đăng ký thành công trong dự án của mình bằng cách xem ứng dụng đó trong bảng điều khiển của Firebase. Chuyển đến phần Cài đặt dự án, rồi di chuyển xuống phần Ứng dụng của bạn.

6. Thiết lập tính năng Xác thực Firebase

Xác thực là một phần quan trọng của mọi ứng dụng. Để cho phép người dùng cuối đăng nhập vào ứng dụng web bằng Tài khoản Google của họ, bạn có thể bật Xác thực Firebase và thiết lập phương thức đăng nhập bằng Google.

Xin lưu ý rằng trong lớp học lập trình này, chúng tôi cung cấp 2 lựa chọn để thiết lập Xác thực Firebase:

  • Cách 1 (Nên dùng): Thiết lập Xác thực Firebase trong bảng điều khiển mà không cần GCIP.
    • Nếu sử dụng lựa chọn này, bạn sẽ không phải liên kết dự án mới với một tài khoản thanh toán Cloud.
  • Cách 2: Thiết lập Xác thực Firebase thông qua Terraform bằng cách sử dụng API Nền tảng nhận dạng của Google Cloud (GCIP).
    • Nếu sử dụng lựa chọn này, bạn phải liên kết dự án mới với một tài khoản thanh toán Cloud vì GCIP yêu cầu dự án phải sử dụng gói giá linh hoạt.

Cách 1: Thiết lập tính năng Xác thực bằng bảng điều khiển của Firebase

Để thiết lập Xác thực Firebase bằng bảng điều khiển của Firebase, dự án của bạn không cần phải sử dụng gói giá Linh hoạt.

Sau đây là cách thiết lập tính năng Xác thực Firebase và đăng nhập bằng Google:

  1. Trong bảng điều khiển của Firebase, hãy tìm mục Tạo trong bảng điều khiển bên trái.
  2. Nhấp vào Xác thực, nhấp vào Bắt đầu, rồi nhấp vào thẻ Phương thức đăng nhập (hoặc nhấp vào đây để chuyển thẳng đến thẻ này).
  3. Nhấp vào Thêm nhà cung cấp mới rồi chọn Google trong phần Nhà cung cấp khác.
  4. Kích hoạt nút bật/tắt Bật.
  5. Đặt tên công khai của ứng dụng thành một tên nào đó, chẳng hạn như FriendlyChat (tên này không cần phải là duy nhất trên toàn cầu).
  6. Chọn Email hỗ trợ dự án trong trình đơn thả xuống, rồi nhấp vào Lưu.Định cấu hình Firebase Auth trên bảng điều khiển của Firebase
  7. Bạn sẽ thấy Google là một nhà cung cấp dịch vụ đăng nhập đã bật.Trang Xác thực của bảng điều khiển Firebase: Đã bật tính năng đăng nhập bằng Google

Cách 2: Thiết lập quy trình xác thực thông qua Terraform bằng cách sử dụng API Google Cloud Identity Platform (GCIP)

Để thiết lập Xác thực Firebase thông qua Terraform, bạn phải sử dụng API GCIP. Điều này có nghĩa là dự án phải thuộc gói giá Blaze. Bạn nâng cấp dự án Firebase để sử dụng gói Blaze bằng cách liên kết một tài khoản thanh toán trên đám mây với dự án đó.

Bật tính năng thanh toán thông qua Terraform

  1. Nếu bạn chưa có Tài khoản thanh toán trên đám mây, bước đầu tiên là tạo một tài khoản mới trong Bảng điều khiển Google Cloud. Khi làm như vậy, hãy ghi lại Mã tài khoản thanh toán của tài khoản đó. Bạn có thể tìm thấy mã tài khoản thanh toán trên trang Thanh toán trong mã tài khoản thanh toán được liên kết với dự án của bạn.Bật tài khoản thanh toán bằng bảng điều khiển Google Cloud
  2. Để bật tính năng thanh toán trong dự án thông qua Terraform, hãy thêm một thuộc tính billing_account vào tài nguyên google_project hiện có trong tệp main.tf:

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

Bật tính năng Xác thực Firebase và đăng nhập bằng Google thông qua Terraform

  1. Để cung cấp Xác thực Firebase bằng GCIP, hãy thêm các khối tài nguyên sau vào tệp 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. Để bật tính năng đăng nhập bằng Google, bạn cần có một ứng dụng OAuth. Chuyển đến mục API và dịch vụ của Google Cloud Console để thiết lập.
  3. Vì đây là lần đầu tiên tạo mã ứng dụng khách cho dự án này, nên bạn cần định cấu hình màn hình đồng ý OAuth.
    1. Mở trang màn hình xin phép bằng OAuth, rồi chọn dự án bạn vừa tạo.
    2. Đặt Loại người dùng thành Bên ngoài, rồi nhấp vào Tạo.
    3. Trên màn hình tiếp theo, hãy hoàn tất các bước sau rồi nhấp vào Lưu và tiếp tục.
      • Đặt Tên ứng dụng xuất hiện công khai của ứng dụng thành một tên nào đó, chẳng hạn như FriendlyChat (tên này không cần phải là duy nhất trên toàn cầu).
      • Chọn Email hỗ trợ người dùng trong trình đơn thả xuống.
      • Nhập email cho Thông tin liên hệ của nhà phát triển.
    4. Ở các màn hình tiếp theo, hãy hoàn tất các bước sau:
      • Chấp nhận các giá trị mặc định trên trang Phạm vi, sau đó nhấp vào Lưu và tiếp tục.
      • Chấp nhận các giá trị mặc định trên trang Người dùng kiểm thử, sau đó nhấp vào Lưu và tiếp tục.
      • Xem lại bản tóm tắt rồi nhấp vào Quay lại trang tổng quan.
      Định cấu hình ứng dụng OAuth2 bằng Google Cloud Console
  4. Thiết lập một ứng dụng OAuth trong trang Thông tin đăng nhập bằng cách làm như sau:
    1. Nhấp vào Tạo thông tin xác thực rồi chọn Mã ứng dụng OAuth.
    2. Trong trình đơn thả xuống Loại ứng dụng, hãy chọn Ứng dụng web.
    3. Trong trường Tên, hãy nhập tên ứng dụng của bạn, ví dụ: FriendlyChat (tên này không cần phải là duy nhất trên toàn cầu).
    4. Cho phép URL của ứng dụng sử dụng ứng dụng OAuth này bằng cách đặt các thông tin sau:
      • Trong mục Nguồn gốc JavaScript được uỷ quyền, hãy nhấp vào Thêm URI rồi nhập
        https://<PROJECT_ID>.firebaseapp.com, trong đó <PROJECT_ID> là mã dự án mà bạn đặt trong main.tf.
      • Trong mục URI chuyển hướng được uỷ quyền, hãy nhấp vào Thêm URI rồi nhập
        https://<PROJECT_ID>.firebaseapp.com/__/auth/handler, trong đó <PROJECT_ID> là mã dự án mà bạn đặt trong main.tf.
    5. Nhấp vào Lưu.
    Lấy mã ứng dụng và khoá bí mật của ứng dụng OAuth2 trên trang Thông tin đăng nhập của bảng điều khiển Google Cloud
  5. Để bật tính năng đăng nhập bằng Google bằng mã ứng dụng OAuth và khoá bí mật của ứng dụng, hãy thêm khối sau vào tệp 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
      ]
    }
    

Áp dụng cấu hình

  1. Để thiết lập quy trình Xác thực theo cấu hình của bạn, hãy chạy các lệnh sau từ thư mục gốc của cùng thư mục với tệp main.tf (phải là web):
    export TF_VAR_oauth_client_secret="<YOUR_OAUTH_CLIENT_SECRET>"
    
    terraform apply
    
    Xin lưu ý rằng việc chạy terraform apply sẽ không tạo lại một dự án Google Cloud mới. Terraform sẽ phát hiện thấy một dự án có mã dự án được chỉ định đã tồn tại và sẽ so sánh trạng thái hiện tại của dự án với trạng thái trong tệp .tf. Sau đó, công cụ này sẽ thực hiện mọi thay đổi mà nó tìm thấy.
  2. Xem lại kế hoạch hành động đã in. Nếu mọi thứ đều như mong đợi, hãy nhập yes rồi nhấn Enter để phê duyệt các thao tác.

Xác thực các thay đổi

  1. Trong bảng điều khiển của Firebase, hãy tìm mục Tạo trong bảng điều khiển bên trái.
  2. Nhấp vào Xác thực, sau đó nhấp vào thẻ Phương thức đăng nhập (hoặc nhấp vào đây để chuyển thẳng đến thẻ này).
  3. Bạn sẽ thấy Google là một nhà cung cấp dịch vụ đăng nhập đã bật.Trang Xác thực của bảng điều khiển Firebase: Đã bật tính năng đăng nhập bằng Google

7. Thiết lập cơ sở dữ liệu Firestore và các Quy tắc bảo mật của cơ sở dữ liệu đó

Đối với ứng dụng web của lớp học lập trình này, bạn sẽ lưu trữ tin nhắn giữa người dùng cuối trong cơ sở dữ liệu Firestore.

  1. Để bật các API bắt buộc và cung cấp phiên bản cơ sở dữ liệu, hãy thêm các khối tài nguyên sau vào tệp 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. Thay đổi <NAME_OF_DESIRED_REGION> thành khu vực mà bạn muốn cơ sở dữ liệu cư trú.

    Khi phát triển một ứng dụng sản xuất, bạn sẽ muốn cơ sở dữ liệu này nằm ở một khu vực gần với phần lớn người dùng và có điểm chung với các dịch vụ khác của Firebase, chẳng hạn như Cloud Functions. Trong lớp học lập trình này, bạn có thể sử dụng us-east1 (Nam Carolina) hoặc sử dụng khu vực gần bạn nhất (xem các vị trí của Cloud Firestore).
  3. Mọi phiên bản cơ sở dữ liệu Firestore mà Firebase có thể truy cập đều phải được bảo vệ bằng Quy tắc bảo mật của Firebase.

    Mã mẫu của lớp học lập trình này cung cấp một bộ quy tắc bảo mật của Firestore trong tệp firestore.rules. Bạn có thể tìm thấy tệp này ở thư mục gốc của web.
  4. Thêm các khối tài nguyên sau vào tệp main.tf để thực hiện những việc sau:
    • Tạo một bộ quy tắc gồm các Quy tắc bảo mật của Firebase từ tệp firestore.rules cục bộ.
    • Phát hành bộ quy tắc cho phiên bản Firestore.
    Xin lưu ý rằng các khối tài nguyên này thực hiện tương đương với việc nhấp vào nút Xuất bản trong bảng điều khiển Firebase hoặc chạy 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. Chạy terraform apply để cung cấp cơ sở dữ liệu Firestore và triển khai các quy tắc bảo mật của cơ sở dữ liệu đó.
  6. Xác minh rằng cơ sở dữ liệu đã được cung cấp và các quy tắc bảo mật của cơ sở dữ liệu đã được triển khai:
    1. Trong bảng điều khiển của Firebase, hãy tìm mục Tạo trong bảng điều khiển bên trái.
    2. Chuyển đến mục Cơ sở dữ liệu Firestore, rồi nhấp vào thẻ Quy tắc.
    Xác minh các quy tắc của Cloud Firestore bằng bảng điều khiển của Firebase

8. Thiết lập một bộ chứa Cloud Storage và các Quy tắc bảo mật của bộ chứa đó

Đối với ứng dụng web của lớp học lập trình này, bạn sẽ lưu trữ hình ảnh được chia sẻ giữa người dùng cuối trong một vùng chứa Cloud Storage.

  1. Để bật các API cần thiết và cung cấp bộ chứa mặc định của Cloud Storage, hãy thêm các khối tài nguyên sau vào tệp main.tf.

    Xin lưu ý rằng bộ chứa Cloud Storage mặc định cho dự án của bạn được cung cấp thông qua Google App Engine và phải có cùng vị trí với cơ sở dữ liệu Firestore. Hãy xem Vị trí của App Engine để biết thêm thông tin.

    Nếu bạn muốn có nhiều vùng chứa trong dự án, hãy cung cấp các vùng chứa đó bằng tài nguyên google_storage_bucket (không xuất hiện trong lớp học lập trình này).

    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. Mọi bộ chứa Cloud Storage mà Firebase có thể truy cập đều phải được bảo vệ bằng Quy tắc bảo mật của Firebase.

    Mã mẫu của lớp học lập trình này cung cấp một bộ quy tắc bảo mật của Firestore trong tệp storage.rules. Bạn có thể tìm thấy tệp này ở thư mục gốc của web.
  3. Thêm các khối tài nguyên sau vào tệp main.tf để thực hiện những việc sau:
    • Tạo một bộ quy tắc gồm các Quy tắc bảo mật của Firebase từ tệp cục bộ.
    • Phát hành bộ quy tắc cho Thùng lưu trữ.
    Xin lưu ý rằng các khối tài nguyên này thực hiện tương đương với việc nhấp vào nút Xuất bản trong bảng điều khiển Firebase hoặc chạy 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. Chạy terraform apply để cung cấp bộ chứa Cloud Storage mặc định và triển khai các quy tắc bảo mật của bộ chứa đó.
  5. Xác minh rằng vùng chứa đã được cung cấp và các quy tắc bảo mật của vùng chứa đó đã được triển khai:
    1. Trong bảng điều khiển của Firebase, hãy tìm mục Tạo trong bảng điều khiển bên trái.
    2. Chuyển đến mục Bộ nhớ, rồi nhấp vào thẻ Quy tắc.
    Xác minh các quy tắc bảo mật bằng bảng điều khiển của Firebase

9. Chạy ứng dụng của bạn trên thiết bị

Giờ đây, bạn đã sẵn sàng chạy ứng dụng web của mình lần đầu tiên! Bạn sẽ sử dụng trình mô phỏng Lưu trữ Firebase để phân phát ứng dụng của mình trên thiết bị.

  1. Mở một cửa sổ dòng lệnh mới rồi chạy lệnh Firebase CLI sau đây từ thư mục web để khởi động trình mô phỏng:
    firebase emulators:start --project=<PROJECT_ID>
    
  2. Trong trình duyệt, hãy mở ứng dụng web của bạn tại URL cục bộ do CLI trả về (thường là http://localhost:5000).

Bạn sẽ thấy giao diện người dùng của ứng dụng FriendlyChat, nhưng giao diện này chưa hoạt động (hiện tại). Ứng dụng chưa được kết nối với Firebase, nhưng khi bạn hoàn tất các bước tiếp theo của lớp học lập trình này, ứng dụng sẽ được kết nối!

Xin lưu ý rằng bất cứ khi nào bạn thực hiện thay đổi đối với ứng dụng web của mình (như bạn sẽ làm trong các bước sau của lớp học lập trình này), hãy làm mới trình duyệt để cập nhật URL cục bộ bằng những thay đổi đó.

10. Cài đặt, định cấu hình và khởi chạy Firebase

Để một ứng dụng hoạt động với Firebase, ứng dụng của bạn cần có SDK Firebase và cấu hình Firebase cho dự án Firebase.

Mã mẫu cho lớp học lập trình này đã là một ứng dụng hoạt động với tất cả các phần phụ thuộc và chức năng cần thiết để sử dụng nhiều sản phẩm của Firebase trong ứng dụng. Bạn có thể xem trong web/package.jsonweb/src/index.js nếu muốn xem những gì đã được thực hiện.

Mặc dù mã mẫu gần như hoàn chỉnh, nhưng bạn vẫn cần làm một số việc để chạy ứng dụng, bao gồm: cài đặt Firebase SDK, bắt đầu bản dựng, thêm cấu hình Firebase vào ứng dụng và cuối cùng là khởi chạy Firebase.

Cài đặt SDK Firebase và bắt đầu bản dựng webpack

Bạn cần chạy một số lệnh để bắt đầu bản dựng ứng dụng.

  1. Mở một cửa sổ dòng lệnh mới.
  2. Đảm bảo bạn đang ở thư mục gốc của thư mục web.
  3. Chạy npm install để tải Firebase SDK xuống.
  4. Chạy npm update để cập nhật mọi phần phụ thuộc.
  5. Chạy npm run start để khởi động webpack.

Trong phần còn lại của lớp học lập trình, webpack sẽ liên tục tạo lại mã nguồn của bạn.

Thêm cấu hình Firebase vào ứng dụng

Bạn cũng cần thêm cấu hình Firebase vào ứng dụng để các SDK Firebase biết dự án Firebase mà bạn muốn chúng sử dụng.

Trong lớp học lập trình này, bạn có 2 lựa chọn để lấy cấu hình Firebase:

  • Lựa chọn 1: Lấy cấu hình Firebase từ bảng điều khiển của Firebase.
  • Cách 2: Lấy cấu hình Firebase thông qua Terraform.

Cách 1: Lấy cấu hình từ bảng điều khiển của Firebase rồi thêm vào cơ sở mã của bạn

  1. Trong bảng điều khiển của Firebase, hãy chuyển đến phần Cài đặt dự án.
  2. Di chuyển xuống thẻ Ứng dụng của bạn, rồi chọn ứng dụng web của bạn.
  3. Chọn Config (Cấu hình) trong ngăn đoạn mã Firebase SDK, rồi sao chép đoạn mã cấu hình.
  4. Dán cấu hình vào tệp web/src/firebase-config.js của ứng dụng, như sau:

    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>",
    };
    
    ...
    

Cách 2: Lấy cấu hình thông qua Terraform và thêm cấu hình đó vào cơ sở mã của bạn

Ngoài ra, bạn có thể nhận cấu hình Firebase thông qua Terraform dưới dạng một giá trị đầu ra trong CLI.

  1. Trong tệp main.tf, hãy tìm khối tài nguyên google_firebase_web_app (khối đã đăng ký một ứng dụng web với dự án của bạn).
  2. Ngay sau khối đó, hãy thêm các khối sau:

    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. Vì khối data và khối output không nhằm mục đích sửa đổi cơ sở hạ tầng theo bất kỳ cách nào, nên bạn chỉ cần chạy các lệnh sau.
    1. Để tải cấu hình Firebase của ứng dụng web vào trạng thái Terraform của thư mục, hãy chạy lệnh sau:
      terraform refresh
      
    2. Để in các giá trị cấu hình Firebase, hãy chạy lệnh sau:
      terraform output –json
      
      Sau đây là ví dụ về kết quả đầu ra của một cấu hình. Đầu ra in sẽ chứa các giá trị của dự án và ứng dụng.
      {
        "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. Sao chép các giá trị trong bản đồ value.
  5. Dán các giá trị này (cấu hình của bạn) vào tệp web/src/firebase-config.js của ứng dụng, như sau:

    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",
    };
    
    ...
    

Khởi động Firebase trong ứng dụng của bạn

Cuối cùng, để khởi động Firebase, hãy thêm nội dung sau vào tệp web/src/index.js của ứng dụng:

index.js

...

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

Dùng thử ứng dụng

Giờ đây, khi mọi thứ đã được định cấu hình cho Firebase, bạn có thể dùng thử ứng dụng web chức năng của mình.

  1. Làm mới trình duyệt đang phân phát ứng dụng của bạn.
  2. Giờ đây, bạn có thể đăng nhập bằng Google và bắt đầu đăng tin nhắn vào cuộc trò chuyện. Nếu có tệp hình ảnh, bạn thậm chí có thể tải chúng lên!

11. Sao chép cấu hình trên các môi trường

Terraform có khả năng quản lý nhiều cơ sở hạ tầng có cấu hình tương tự (ví dụ: thiết lập một dự án Firebase dàn dựng tương tự như một dự án sản xuất).

Trong lớp học lập trình này, bạn sẽ tạo một dự án Firebase thứ hai để làm môi trường dàn dựng.

Để sao chép một cấu hình hiện có nhằm tạo dự án dàn dựng này, bạn có 2 lựa chọn:

  • Cách 1: Sao chép cấu hình Terraform.
    Tuỳ chọn này mang lại sự linh hoạt cao nhất về mức độ khác biệt giữa dự án được sao chép và dự án nguồn.
  • Lựa chọn 2: Sử dụng lại cấu hình bằng for_each.
    Lựa chọn này giúp bạn sử dụng lại mã nhiều hơn nếu mỗi dự án không có nhiều điểm khác biệt và bạn muốn truyền các thay đổi đến tất cả dự án cùng một lúc.

Cách 1: Tạo bản sao của cấu hình Terraform

Lựa chọn này mang lại sự linh hoạt cao nhất về mức độ khác biệt giữa dự án được sao chép và dự án nguồn, chẳng hạn như có các ứng dụng với tên hiển thị và quy trình phát hành theo giai đoạn khác nhau.

  1. Ở thư mục gốc web, hãy tạo một tệp cấu hình Terraform mới có tên là main_staging.tf.
  2. Sao chép tất cả các khối tài nguyên trong tệp main.tf (ngoại trừ các khối terraformprovider), sau đó dán các khối đó vào tệp main_staging.tf.
  3. Sau đó, bạn cần sửa đổi từng khối tài nguyên được sao chép trong main_staging.tf để chúng hoạt động với dự án dàn dựng của bạn:
    • Nhãn tài nguyên: Sử dụng tên mới để tránh xung đột. Ví dụ: đổi tên resource "google_project" "default" thành resource "google_project" "staging".
    • Tài liệu tham khảo về tài nguyên: Cập nhật từng tài liệu. Ví dụ: cập nhật google_firebase_project.default.project thành google_firebase_project.staging.project.
    Bạn có thể tìm thấy cấu hình hoàn chỉnh của tệp main_staging.tf trong kho lưu trữ GitHub của lớp học lập trình này:

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

    Nếu bạn muốn sử dụng cấu hình này, hãy nhớ làm như sau:
    1. Sao chép cấu hình từ main_staging-copypaste.tf, rồi dán vào tệp main_staging.tf.
    2. Trong tệp main_staging.tf, hãy làm như sau:
      • Trong khối tài nguyên google_project, hãy cập nhật thuộc tính name, thuộc tính project-id và (nếu bạn thiết lập Xác thực qua Terraform) thuộc tính billing_account bằng các giá trị của riêng bạn.
      • Trong khối tài nguyên google_firebase_web_app, hãy cập nhật thuộc tính display_name bằng giá trị của riêng bạn.
      • Trong các khối tài nguyên google_firestore_databasegoogle_app_engine_application, hãy cập nhật các thuộc tính location_id bằng giá trị của riêng bạn.
    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. Chạy terraform apply để cung cấp dự án Firebase "đang dàn dựng" mới và tất cả tài nguyên của dự án, đồng thời bật các dịch vụ của dự án.
  5. Xác minh rằng mọi thứ đã được cấp phép và bật như dự kiến bằng cách kiểm tra trong bảng điều khiển của Firebase như trước.

Cách 2: Sử dụng lại cấu hình bằng for_each

Lựa chọn này giúp bạn sử dụng lại mã nhiều hơn nếu mỗi dự án không có sự khác biệt đáng kể và bạn muốn truyền các thay đổi đến tất cả dự án cùng một lúc. Nó sử dụng siêu đối số for_each trong ngôn ngữ Terraform.

  1. Mở tệp main.tf.
  2. Vào mỗi khối tài nguyên mà bạn muốn sao chép, hãy thêm một đối số meta for_each, như sau:

    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.
    
    Bạn có thể tìm thấy cấu hình hoàn chỉnh của tệp main.tf sử dụng đối số meta for_each trong kho lưu trữ GitHub của lớp học lập trình này:

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

    Nếu muốn sử dụng cấu hình này, hãy nhớ làm những việc sau:
    1. Sao chép cấu hình từ main-foreach.tf, rồi dán vào tệp main.tf.
    2. Trong tệp main.tf, hãy làm như sau:
      • Trong khối tài nguyên google_project, hãy cập nhật thuộc tính name, thuộc tính project-id và (nếu bạn thiết lập Xác thực qua Terraform) thuộc tính billing_account bằng các giá trị của riêng bạn.
      • Trong khối tài nguyên google_firebase_web_app, hãy cập nhật thuộc tính display_name bằng giá trị của riêng bạn.
      • Trong các khối tài nguyên google_firestore_databasegoogle_app_engine_application, hãy cập nhật các thuộc tính location_id bằng giá trị của riêng bạn.
  3. Thay vì áp dụng ngay cấu hình này, bạn cần hiểu và khắc phục một số vấn đề về cách Terraform diễn giải cấu hình này so với cơ sở hạ tầng hiện có.
    1. Hiện tại, nếu bạn áp dụng cấu hình này bằng cách sử dụng for_each, thì địa chỉ tài nguyên sẽ có dạng như sau:
      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"]
      
      Tuy nhiên, dự án hiện có mà bạn đã tạo trong phần đầu tiên của lớp học lập trình này được Terraform biết đến như sau:
      google_project.default
      google_firebase_project.default
      google_firebase_android_app.default
      
    2. Chạy terraform plan để xem những thao tác mà Terraform sẽ thực hiện trong trạng thái hiện tại.

      Đầu ra sẽ cho thấy Terraform sẽ xoá dự án mà bạn đã tạo trong phần đầu tiên của lớp học lập trình này và tạo hai dự án mới. Điều này là do Terraform không biết rằng dự án tại địa chỉ google_project.default đã được chuyển đến địa chỉ mới google_project.default["prod"].
    3. Để khắc phục vấn đề này, hãy chạy lệnh terraform state mv:
      terraform state mv "google_project.default" "google_project.default[\"prod\"]"
      
    4. Tương tự, để sửa tất cả các khối tài nguyên khác, hãy chạy terraform state mv cho google_firebase_project, google_firebase_web_app và tất cả các khối tài nguyên khác trong tệp main.tf.
    5. Giờ đây, nếu bạn chạy lại terraform plan, thì lệnh này sẽ không cho thấy rằng Terraform sẽ xoá dự án mà bạn đã tạo trong phần đầu tiên của lớp học lập trình này.
  4. Chạy terraform apply để cung cấp dự án Firebase "đang dàn dựng" mới và tất cả tài nguyên của dự án, đồng thời bật các dịch vụ của dự án.
  5. Xác minh rằng mọi thứ đã được cấp phép và bật như dự kiến bằng cách kiểm tra trong bảng điều khiển của Firebase như trước.

12. Bước bổ sung: Triển khai ứng dụng dàn dựng và ứng dụng phát hành công khai

  1. Trong cơ sở mã của ứng dụng, hãy thay đổi firebase-config.js để sử dụng cấu hình Firebase từ dự án dàn dựng của bạn.

    Để nhắc bạn cách lấy cấu hình Firebase và thêm cấu hình đó vào ứng dụng, hãy xem bước trước đó trong lớp học lập trình này: Thêm cấu hình Firebase vào ứng dụng.
  2. Ở gốc thư mục web, hãy chạy lệnh sau để triển khai ứng dụng của bạn vào dự án Firebase dàn dựng.
    firebase deploy --only hosting --project=<STAGING_PROJECT_ID>
    
  3. Mở ứng dụng dàn dựng trong trình duyệt thông qua URL được in trong đầu ra của firebase deploy. Hãy thử đăng nhập, gửi tin nhắn và tải hình ảnh lên.

    Khi bạn triển khai một ứng dụng cho dự án Firebase, ứng dụng đó sẽ sử dụng các tài nguyên Firebase thực, chứ không phải tài nguyên được mô phỏng. Khi tương tác với ứng dụng dàn dựng, bạn sẽ thấy dữ liệu và hình ảnh xuất hiện trong dự án dàn dựng của mình trong bảng điều khiển của Firebase.
  4. Sau khi kiểm thử ứng dụng trong giai đoạn dàn dựng, hãy thay đổi firebase-config.js để quay lại sử dụng cấu hình Firebase của dự án phát hành công khai (dự án đầu tiên mà bạn đã tạo trong lớp học lập trình này).
  5. Ở gốc thư mục web, hãy chạy lệnh sau để triển khai ứng dụng của bạn vào dự án Firebase phát hành công khai.
    firebase deploy --only hosting --project=<PRODUCTION_PROJECT_ID>
    
  6. Mở ứng dụng phát hành công khai trong trình duyệt thông qua URL được in trong đầu ra của firebase deploy. Hãy thử đăng nhập, gửi tin nhắn và tải hình ảnh lên.

    Bạn sẽ thấy dữ liệu và hình ảnh xuất hiện trong dự án phát hành của mình trong bảng điều khiển của Firebase.
  7. Khi hoàn tất việc tương tác với 2 ứng dụng trong lớp học lập trình này, bạn có thể dừng Firebase phân phát các ứng dụng đó. Chạy lệnh sau cho từng dự án của bạn:
    firebase hosting:disable --project=<STAGING_PROJECT_ID>
    
    firebase hosting:disable --project=<PRODUCTION_PROJECT_ID>
    

13. Xin chúc mừng!

Bạn đã sử dụng Terraform để định cấu hình một ứng dụng web trò chuyện theo thời gian thực! Bạn đã làm theo các phương pháp hay nhất cho môi trường phát triển bằng cách tạo các dự án Firebase riêng biệt cho giai đoạn thử nghiệm và giai đoạn phát hành công khai.

Nội dung đã đề cập

  • Sử dụng Terraform CLI để quản lý tài nguyên đám mây
  • Sử dụng Terraform để định cấu hình các sản phẩm của Firebase (Xác thực, Firestore, Cloud Storage và Quy tắc bảo mật)
  • Chạy và kiểm thử ứng dụng web cục bộ bằng Bộ công cụ mô phỏng cục bộ của Firebase
  • Nhập Firebase vào một ứng dụng web
  • Sử dụng Terraform để sao chép một cấu hình trên nhiều môi trường

Để biết thêm thông tin về Firebase và Terraform, hãy tham khảo tài liệu của chúng tôi. Bạn có thể tìm thấy danh sách tất cả các sản phẩm của Firebase có hỗ trợ Terraform, các cấu hình Terraform mẫu cho các trường hợp sử dụng phổ biến, cũng như thông tin khắc phục sự cố và câu hỏi thường gặp hữu ích.