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ý dự án Firebase, bao gồm cả cấu hình có lập 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 sẽ mô tả cách tạo tệp cấu hình Terraform để tạo một dự án Firebase mới, tiếp theo là cách định cấu hình các ứng dụng và sản phẩm của Firebase mà bạn muốn sử dụng trong dự án đó. Học viên cũng sẽ tìm hiểu thông tin cơ bản về dòng lệnh Terraform, chẳng hạn như xem trước các thay đổi sẽ thực hiện rồi triển khai các thay đổi đó.

Nếu bạn muốn tìm hiểu cách thiết lập cũng như quản lý các dự án và 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 CLI của Terraform để quản lý cơ sở hạ tầng của bạn
  • Cách sửa đổi cấu hình để cập nhật tài nguyên và dịch vụ của bạn
  • Cách áp dụng cấu hình của bạn trên một ứng dụng web thực (có tên là Thân thiện với Chat)
  • Cách xác định cấu hình song song (và không đồng bộ) trong các môi trường khác nhau (sản xuất, thử nghiệm, v.v.)

Bạn cần có

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

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

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. Để thực hiện việc này, bạn sẽ cần:

  • 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 đoạn mã khởi đầu

Trong lớp học lập trình này, bạn có thể thử nghiệm nội dung bạn cung cấp qua Terraform bằng một ứng dụng web thực. Bạn nên thực hiện việc này để nắm được tất cả các bước cần thiết để sử dụng các tài nguyên được 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 thư mục gốc của thư mục web.
  2. Ở 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 như sau:

    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 trì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 kiểm tra hạn mức đối với các hoạt động trong Terraform. Để cấp phép hầu hết các tài nguyên, bạn nên sử dụng user_project_override = true, nghĩa là kiểm tra hạn mức so 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 việc 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 giúp bạn phân biệt cách thiết lập 2 trì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

Để tạo cấu hình mới lần đầu tiên, bạn phải 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 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 dự án Firebase", bạn cần nhớ rằng mỗi dự án Firebase thực sự là một dự án Google Cloud, chỉ với các dịch vụ Firebase được bật cho dự án đó.

Thêm các quy tắc chặn cho dự án và API cơ bản trên Google Cloud

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

    Đối với tệp cấu hình main.tf, hãy thêm khối tài nguyên dưới đây.

    Bạn cần chỉ định tên dự án (như "Terraform FriendlyChat Codelab") và mã dự án của riêng mình (như "terraform-codelab-your-initials"). Xin lưu ý rằng giá trị name chỉ được dùng trong giao diện Firebase và không hiển thị với người dùng cuối. Tuy nhiên, giá trị project_id giúp Google nhận dạng duy nhất dự án của bạn, vì vậy, hãy nhớ 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 của Firebase để tạo dự án Firebase. Tuy nhiên, bạn cần phải thông báo rõ ràng cho Terraform để thực hiện việc này.

    Đối với tệp cấu hình main.tf (ngay trong 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 kiểm tra hạn mức! Vì vậy, để bật dịch vụ và cấp phép tài nguyên sau này, bạn nên sử dụng nhà cung cấp này cùng user_project_override (không cần email đại diện).

Thêm một quy tắc chặn để bật các dịch vụ Firebase

Điều cuối cùng cần thiết để "tạo dự án Firebase" đang bật 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 trình cung cấp với user_project_override (không cần email đại diện).

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ể thấy mệnh đề depends_on yêu cầu Terraform phải chờ các API cơ bản được bật. Nếu không có mệnh đề này, Terraform không biết về phần phụ thuộc và có thể gặp lỗi khi cấp phép song song các tài nguyên.

Á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ừ thư mục gốc của cùng một thư mục với tệp main.tf (bạn phải là web):
    terraform apply
    
  2. Trong cửa sổ dòng lệnh, Terraform 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 áp dụng, thì bạn có thể 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ả tài nguyên và dịch vụ được cấp phép của Terraform được bật bằng cách chạy lệnh sau:

terraform show

Dưới đây là ví dụ về nội dung bạn sẽ thấy khi in ra. Tiểu bang 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 dự án được tạo bằng cách xem dự án trong bảng điều khiển của Firebase.

Dự án lớp học lập trình Terraform CompatChat trên bảng điều khiển của Firebase

5. Đăng ký ứng dụng Firebase của bạn 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ẽ 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. Ứng dụng này là một ứng dụng web, vì vậy, bạn cần yêu cầu Terraform đăng ký Ứ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 tệp main.tf với khối tài nguyên sau đây.

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 giao diện Firebase và không hiển thị với người dùng cuối.

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. Để cấp phép tài nguyên mới, hãy chạy lệnh sau từ gốc của cùng thư mục với tệp main.tf (bạn phải là web).
    terraform apply
    
    Xin lưu ý rằng lệnh này sẽ không tạo lại dự án mới trên Google Cloud. Terraform sẽ phát hiện rằng 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 nội dung trong tệp .tf, đồng thời thực hiện mọi thay đổi tìm thấy.
  2. Xem lại kế hoạch hành động được in. Nếu mọi thứ đều diễn ra như dự kiến, hãy nhập yes rồi nhấn Enter để phê duyệt các hành động.

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 mới đượ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 Project settings (Cài đặt dự án) rồi di chuyển xuống phần Your apps (Ứ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 bất kỳ ứng dụng nào. Để cho phép người dùng cuối đăng nhập vào ứng dụng web của bạn bằng Tài khoản Google của họ, bạn có thể bật tính năng 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 tuỳ chọn để thiết lập tính năng Xác thực Firebase:

  • Cách 1 (Nên dùng): Thiết lập tính năng Xác thực Firebase trong bảng điều khiển mà không cần đến GCIP.
    • Khi sử dụng cách này, bạn không phải liên kết dự án mới với tài khoản thanh toán Cloud.
  • Cách 2: Thiết lập phương thức xác thực Firebase qua Terraform bằng các API của Google Cloud Identity Platform (GCIP).
    • Khi 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 nằm trong 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 tính năng 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, 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 đó).
  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 bổ sung.
  4. Bật nút chuyển Bật.
  5. Đặt tên công khai của ứng dụng thành FriendlyChat (không nhất thiết phải là tên duy nhất trên toàn cầu).
  6. Chọn một Email hỗ trợ dự án trong trình đơn thả xuống, sau đó nhấp vào Save (Lưu).Định cấu hình tính năng Xác thực Firebase trên bảng điều khiển của Firebase
  7. Bạn sẽ thấy Google là nhà cung cấp dịch vụ đăng nhập được bật.Trang Xác thực bảng điều khiển của Firebase: Đã bật tính năng đăng nhập bằng Google

Lựa chọn 2: Thiết lập phương thức xác thực qua Terraform bằng các API Google Cloud Identity Platform (GCIP)

Để thiết lập tính năng Xác thực Firebase qua Terraform, bạn phải sử dụng API GCIP, tức là dự án phải nằm trong Gói giá linh hoạt. Bạn nâng cấp dự án Firebase của mình để sử dụng Gói linh hoạt bằng cách liên kết một tài khoản thanh toán Cloud với dự án.

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

  1. Nếu bạn chưa có tài khoản thanh toán Cloud, thì trước tiên, bạn cần tạo một tài khoản mới trong Google Cloud Console. Khi bạn thực hiện việc này, hãy ghi lại Mã tài khoản thanh toán. Bạn có thể tìm 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 mình.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 qua Terraform, hãy thêm thuộc tính billing_account vào tài nguyên google_project hiện có trong tệp main.tf của bạn:

    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 tính năng Xác thực Firebase bằng GCIP, hãy thêm tệp main.tf cùng với các khối tài nguyên sau:

    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 phải có ứng dụng OAuth. Chuyển đến API & Dịch vụ của Google Cloud Console để thiết lập.
  3. Vì đây là lần đầu tiên bạ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 xin phép bằng OAuth.
    1. Mở trang màn hình xin phép OAuth rồi chọn dự án bạn vừa tạo.
    2. Đặt User Type (Kiểu người dùng) thành External (Bên ngoài), rồi nhấp vào Tạo.
    3. Trong màn hình tiếp theo, hãy hoàn thành các bước sau, sau đó nhấp vào Lưu và tiếp tục.
      • Đặt Tên ứng dụng công khai của ứng dụng thành FriendlyChat (không nhất thiết phải là duy nhất trên toàn hệ thống).
      • Chọn Email hỗ trợ người dùng từ trình đơn thả xuống.
      • Nhập một email cho Thông tin liên hệ của nhà phát triển.
    4. Trong các màn hình tiếp theo, hãy hoàn thành 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 thử nghiệm, sau đó nhấp vào Lưu và tiếp tục.
      • Xem lại thông tin tóm tắt, sau đó nhấp vào Quay lại trang tổng quan.
      Định cấu hình ứng dụng OAuth2 bằng bảng điều khiển Google Cloud
  4. Thiết lập ứng dụng OAuth trong trang Thông tin xác thực 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 khách OAuth.
    2. Trong trình đơn thả xuống Application type (Loại ứng dụng), hãy chọn Web application (Ứng dụng web).
    3. Trong trường Name (Tên), hãy nhập tên ứng dụng của bạn, ví dụ: FriendlyChat (không nhất thiết phải là tên duy nhất trên toàn hệ thống).
    4. Cho phép URL ứng dụng của bạn dùng ứng dụng OAuth này bằng cách thiết lập như sau:
      • Trong phần Nguồn gốc JavaScript được cho phép, 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 ủy 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 khách OAuth2 và mã bí mật từ trang Thông tin đăng nhập 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 khách OAuth và mật khẩu ứng dụng khách, hãy thêm tệp main.tf với khối sau:

    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 tính năng Xác thực theo cấu hình của bạn, hãy chạy các lệnh sau từ gốc của cùng một thư mục với tệp main.tf (bạn 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 dự án Google Cloud mới. Terraform sẽ phát hiện rằng 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 tìm được.
  2. Xem lại kế hoạch hành động được in. Nếu mọi thứ đều diễn ra như dự kiến, hãy nhập yes rồi nhấn Enter để phê duyệt các hành động.

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 đó).
  3. Bạn sẽ thấy Google là nhà cung cấp dịch vụ đăng nhập được bật.Trang Xác thực bảng điều khiển của 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 này

Đố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 thực thể cơ sở dữ liệu, hãy thêm tệp main.tf cùng với các khối tài nguyên sau:

    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 lưu trữ cơ sở dữ liệu.

    Khi phát triển một ứng dụng chính thức, bạn nên đặt khu vực này ở khu vực gần với phần lớn người dùng và giống với các dịch vụ khác của Firebase, như Cloud Functions. Đối với 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í trong Cloud Firestore).
  3. Mọi thực thể cơ sở dữ liệu Firestore có thể truy cập vào Firebase đề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 Firestore an toàn trong tệp firestore.rules mà bạn có thể tìm thấy ở gốc thư mục web.
  4. Thêm tệp main.tf với các khối tài nguyên sau để thực hiện những việc sau:
    • Tạo một bộ quy tắc cho 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 thực thể Firestore.
    Xin lưu ý rằng các khối tài nguyên này hoàn thành tương đương với việc nhấp vào nút Xuất bản trong bảng điều khiển của 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 này.
  6. Xác minh rằng cơ sở dữ liệu đã được cấp phé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 phần Firestore Database (Cơ sở dữ liệu khôi phục) rồi nhấp vào thẻ Rules (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 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 vào một bộ chứa Cloud Storage.

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

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

    Nếu bạn muốn có nhiều bộ chứa trong dự án của mình, hãy cấp phép cho các bộ chứa đó bằng tài nguyên google_storage_bucket (không có 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 có thể truy cập vào Firebase đề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 Firestore bảo mật trong tệp storage.rules mà bạn có thể tìm thấy ở gốc của thư mục web.
  3. Thêm tệp main.tf với các khối tài nguyên sau để thực hiện những việc sau:
    • Tạo một bộ quy tắc cho 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 bộ chứa Storage.
    Xin lưu ý rằng các khối tài nguyên này hoàn thành tương đương với việc nhấp vào nút Xuất bản trong bảng điều khiển của 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 bộ chứa đã được cấp phép và các quy tắc bảo mật của bộ 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 tới phần Bộ nhớ rồi nhấp vào tab Quy tắc.
    Xác minh quy tắc bảo mật bằng bảng điều khiển của Firebase

9. Chạy ứng dụng trên máy

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 cục bộ.

  1. Mở một cửa sổ dòng lệnh mới và từ thư mục web, hãy chạy lệnh CLI của Firebase sau đây để 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 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 BestChat chưa hoạt động. Ứng dụng chưa được kết nối với Firebase, nhưng bằng cách hoàn thành 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!

Lưu ý rằng bất cứ khi nào bạn thay đổi ứng dụng web của mình (như bạn sẽ thực hiện 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ộ với 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 đang hoạt động với tất cả các phần phụ thuộc và hàm 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 việc đã làm.

Mặc dù mã mẫu gần như đã hoàn tất, nhưng bạn vẫn cần làm một vài việc để ứng dụng của mình chạy, 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 Firebase SDK và bắt đầu tạo bản dựng webpack

Bạn cần chạy một vài lệnh để khởi động bản dựng của ứng dụng.

  1. Mở một cửa sổ dòng lệnh mới.
  2. Đảm bảo bạn đang ở gốc của thư mục web.
  3. Chạy npm install để tải SDK Firebase 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 gói web.

Trong phần còn lại của lớp học lập trình, giờ đây, webpack sẽ liên tục xây dựng 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ủa mình để Firebase SDK biết bạn muốn họ sử dụng dự án Firebase nào.

Đối với lớp học lập trình này, bạn có hai cách để thiết lập cấu hình Firebase:

  • Cách 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 và thêm cấu hình đó 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, sau đó chọn ứng dụng web.
  3. Chọn 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 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>",
      authDomain: "<PROJECT_ID>.firebaseapp.com",
      projectId: "<PROJECT_ID>",
      storageBucket: "<PROJECT_ID>.appspot.com",
      messagingSenderId: "<SENDER_ID>",
      appId: "<APP_ID>",
      measurementId: "<G-MEASUREMENT_ID>",
    };
    
    ...
    

Lựa chọn 2: Lấy cấu hình 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ể lấy cấu hình Firebase thông qua Terraform dưới dạng 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 dùng để 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ả của một cấu hình. Bản in ra sẽ chứa các giá trị của dự án và ứng dụng của bạn.
      {
        "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ị từ bên 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 chạy Firebase trong ứng dụng của bạn

Cuối cùng, để khởi chạy Firebase, hãy thêm tệp web/src/index.js của ứng dụng như sau:

index.js

...

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

Dùng thử ứng dụng của bạn

Giờ đây, 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 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 của bạn trên các môi trường

Terraform có hiệu quả vượt trội trong việc quản lý nhiều cơ sở hạ tầng có cấu hình tương tự nhau (ví dụ: thiết lập một dự án Firebase thử nghiệm tương tự như dự án sản phẩm).

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 thử nghiệm.

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

  • Cách 1: Tạo bản sao của cấu hình Terraform.
    Lựa chọn này giúp bạn linh hoạt nhất khi xác định mức chênh lệch 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 với for_each.
    Lựa chọn này cho phép bạn sử dụng lại mã nhiều hơn nếu mỗi dự án không có gì khác biệt đáng kể và bạn muốn áp dụng các thay đổi cho 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ư việc có các ứng dụng có tên hiển thị khác nhau và phát hành theo giai đoạn.

  1. Ở gốc của thư mụ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ả khối tài nguyên từ tệp main.tf (ngoại trừ các khối terraformprovider), sau đó dán 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 của mình trong main_staging.tf để chúng hoạt động với dự án thử nghiệm 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 nguyên tham khảo: Cập nhật từng tài nguyên. 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 đầy đủ 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 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à thuộc tính billing_account bằng các giá trị của riêng bạn (nếu bạn thiết lập tính năng Xác thực qua Terraform).
      • 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 giá trị của riêng bạn cho các thuộc tính 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. Chạy terraform apply để cung cấp "thử nghiệm" mới Dự án Firebase 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 chúng trong bảng điều khiển của Firebase như trước đây.

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

Lựa chọn này cho phép bạn sử dụng lại mã nhiều hơn nếu mỗi dự án không có gì khác biệt đáng kể và bạn muốn áp dụng các thay đổi cho tất cả dự án cùng một lúc. Tính năng này sử dụng đối số meta for_each bằng ngôn ngữ Terraform.

  1. Mở tệp main.tf của bạn.
  2. Trong 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 đầy đủ 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ư 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à thuộc tính billing_account bằng các giá trị của riêng bạn (nếu bạn thiết lập tính năng Xác thực qua Terraform).
      • 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 giá trị của riêng bạn cho các thuộc tính location_id.
  3. Thay vì áp dụng cấu hình này ngay lập tức, 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 sử dụng for_each này, 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 của lớp học lập trình này có tên là Terraform như sau:
      google_project.default
      google_firebase_project.default
      google_firebase_android_app.default
      
    2. Chạy terraform plan để xem những hành động mà Terraform sẽ thực hiện với trạng thái hiện tại.

      Kết quả sẽ cho thấy Terraform sẽ xoá dự án 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. Nguyên nhân là do Terraform không biết rằng dự án tại địa chỉ google_project.default đã được chuyển sang đị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ự như vậy, để sửa tất 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ả khối tài nguyên khác trong tệp main.tf.
    5. Bây giờ, nếu chạy lại terraform plan, bạn sẽ không thấy Terraform sẽ xoá dự án 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 "thử nghiệm" mới Dự án Firebase 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 chúng trong bảng điều khiển của Firebase như trước đây.

12. Bước thêm: Triển khai các ứng dụng thử nghiệm và ứng dụng sản phẩm

  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 thử nghiệm.

    Để tự nhắc về cách nhận và thêm cấu hình Firebase vào ứng dụng, hãy xem bước trước của lớp học lập trình này, thêm cấu hình Firebase vào ứng dụng của bạn.
  2. Ở gốc thư mục web, hãy chạy lệnh sau để triển khai ứng dụng cho dự án Firebase thử nghiệm của bạn.
    firebase deploy --only hosting --project=<STAGING_PROJECT_ID>
    
  3. Mở ứng dụng thử nghiệm trong trình duyệt thông qua URL được in trong kết quả của firebase deploy. Hãy thử đăng nhập, gửi thông báo 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 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 thử nghiệm, bạn sẽ thấy dữ liệu và hình ảnh xuất hiện trong dự án thử nghiệm trong bảng điều khiển của Firebase.
  4. Sau khi kiểm thử ứng dụng trong giai đoạn thử nghiệm, hãy thay đổi firebase-config.js về bằng cấu hình Firebase của dự án chính thức (dự án đầu tiên 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 cho dự án Firebase chính thức của bạn.
    firebase deploy --only hosting --project=<PRODUCTION_PROJECT_ID>
    
  6. Mở ứng dụng chính thức trong trình duyệt thông qua URL được in trong kết quả 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 chính thức của mình trong bảng điều khiển của Firebase.
  7. Khi tương tác xong 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 những ứng dụng này. 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 ứng dụng web trò chuyện trong thời gian thực! Và 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à sản phẩm.

Nội dung đã đề cập

  • Sử dụng Terraform CLI để quản lý tài nguyên trê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ộ Firebase
  • Nhập Firebase vào ứng dụng web
  • Sử dụng Terraform để sao chép 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 truy cập và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ả sản phẩm của Firebase có hỗ trợ Terraform, cấu hình Terraform mẫu cho các trường hợp sử dụng phổ biến cũng như câu hỏi thường gặp và khắc phục sự cố hữu ích.