Bắt đầu sử dụng Terraform và Firebase

Firebase đang bắt đầu hỗ trợ Terraform. Nếu bạn là thành viên của một nhóm muốn tự động hoá và chuẩn hoá việc tạo dự án Firebase bằng các tài nguyên và dịch vụ cụ thể được cung cấp, thì việc sử dụng Terraform với Firebase có thể phù hợp với bạn.

Quy trình làm việc cơ bản để sử dụng Terraform với Firebase bao gồm:

  • Tạo và tuỳ chỉnh tệp cấu hình Terraform (tệp .tf) chỉ định cơ sở hạ tầng mà bạn muốn cấp phép (tức là tài nguyên bạn muốn cấp phép và dịch vụ bạn muốn bật).

  • Sử dụng các lệnh gcloud CLI giao diện với Terraform để cấp cơ sở hạ tầng được chỉ định trong tệp .tf.

Bạn có thể làm gì với Terraform và Firebase?

Quy trình công việc tổng quát mẫu trong hướng dẫn này là tạo một dự án Firebase mới bằng ứng dụng Android. Tuy nhiên, bạn có thể làm được nhiều việc hơn nữa với Terraform, chẳng hạn như:

  • Xoá và sửa đổi cơ sở hạ tầng hiện có bằng Terraform.

  • Quản lý cấu hình và tác vụ theo sản phẩm cụ thể bằng Terraform, chẳng hạn như:

    • Bật trình cung cấp dịch vụ đăng nhập Firebase Authentication.
    • Tạo các bộ chứa Cloud Storage hoặc thực thể cơ sở dữ liệu và triển khai Firebase Security Rules cho các bộ chứa đó.

Bạn có thể sử dụng các tệp cấu hình và lệnh Terraform chuẩn để hoàn thành tất cả các nhiệm vụ này. Để giúp bạn thực hiện việc này, chúng tôi đã cung cấp các tệp cấu hình Terraform mẫu cho một số trường hợp sử dụng phổ biến.



Quy trình tổng quát để sử dụng Terraform với Firebase

Điều kiện tiên quyết

Hướng dẫn này là phần giới thiệu về cách sử dụng Terraform với Firebase, vì vậy, hướng dẫn này giả định rằng bạn đã có kiến thức cơ bản về Terraform. Hãy đảm bảo bạn đã hoàn tất các điều kiện tiên quyết sau đây trước khi bắt đầu quy trình công việc này.

  • 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ọ.

  • Cài đặt Google Cloud CLI (gcloud CLI). Đăng nhập bằng tài khoản người dùng hoặc tài khoản dịch vụ.

    • Nếu sử dụng tài khoản người dùng, bạn phải chấp nhận Điều khoản dịch vụ của Firebase. Bạn đã chấp nhận Điều khoản dịch vụ của Firebase nếu có thể xem một dự án Firebase trong bảng điều khiển Firebase
    • Để Terraform thực hiện một số hành động nhất định (ví dụ: tạo dự án), điều kiện sau phải đúng:
      • Người dùng hoặc tài khoản dịch vụ phải có quyền truy cập IAM hiện hành cho những hành động đó.
      • Nếu tài khoản người dùng hoặc tài khoản dịch vụ thuộc một tổ chức Google Cloud, thì chính sách của tổ chức phải cho phép tài khoản thực hiện những hành động đó.


Bước 1: Tạo và tuỳ chỉnh tệp cấu hình Terraform

Tệp cấu hình Terraform cần có hai phần chính (được mô tả chi tiết bên dưới):

Thiết lập provider

Bạn phải thiết lập provider bất kể sản phẩm hoặc dịch vụ Firebase nào liên quan.

  1. Tạo tệp cấu hình Terraform (chẳng hạn như tệp main.tf) trong thư mục cục bộ.

    Trong hướng dẫn này, bạn sẽ sử dụng tệp cấu hình này để chỉ định cả chế độ thiết lập provider và tất cả cơ sở hạ tầng mà bạn muốn Terraform tạo. Tuy nhiên, bạn có thể chọn cách đưa thông tin thiết lập nhà cung cấp vào.

    Bạn có các tuỳ chọn sau đây để đưa chế độ thiết lập provider vào phần cấu hình Terraform còn lại:

    • Cách 1: Thêm tệp này vào đầu một tệp cấu hình .tf Terraform (như minh hoạ trong hướng dẫn này).

      • Sử dụng tuỳ chọn này nếu bạn mới bắt đầu sử dụng Terraform hoặc chỉ mới thử Terraform với Firebase.
    • Cách 2: Thêm tệp này vào một tệp .tf riêng (chẳng hạn như tệp provider.tf), ngoài tệp .tf mà bạn chỉ định cơ sở hạ tầng để tạo (chẳng hạn như tệp main.tf).

      • Sử dụng tuỳ chọn này nếu bạn là thành viên của một nhóm lớn hơn cần chuẩn hoá chế độ thiết lập.
      • Khi chạy các lệnh Terraform, cả tệp provider.tf và tệp main.tf phải nằm trong cùng một thư mục.

  2. Thêm chế độ thiết lập provider sau đây vào đầu tệp main.tf.

    Bạn phải sử dụng trình cung cấp google-beta vì đây là bản phát hành beta của việc sử dụng Firebase với Terraform. Hãy thận trọng khi sử dụng trong môi trường phát hành chính thức.

    # Terraform configuration to set up providers by version.
    terraform {
      required_providers {
        google-beta = {
          source  = "hashicorp/google-beta"
          version = "~> 5.0"
        }
      }
    }
    
    # Configures the provider to use the resource block's specified project for quota checks.
    provider "google-beta" {
      user_project_override = true
    }
    
    # Configures the provider to not use the resource block's specified project for quota checks.
    # This provider should only be used during project creation and initializing services.
    provider "google-beta" {
      alias = "no_user_project_override"
      user_project_override = false
    }

    Tìm hiểu thêm về các loại thuộc tính liên quan đến dự án (bao gồm cả "dự án kiểm tra hạn mức" mà hướng dẫn này gọi là) khi sử dụng Terraform với Firebase.

  3. Tiếp tục chuyển sang phần tiếp theo để hoàn tất tệp cấu hình và chỉ định cơ sở hạ tầng cần tạo.

Chỉ định cơ sở hạ tầng cần tạo bằng các khối resource

Trong tệp cấu hình Terraform (đối với hướng dẫn này là tệp main.tf), bạn cần chỉ định tất cả cơ sở hạ tầng mà bạn muốn Terraform tạo (nghĩa là tất cả tài nguyên bạn muốn cấp và tất cả dịch vụ bạn muốn bật). Trong hướng dẫn này, hãy xem danh sách đầy đủ tất cả tài nguyên Firebase hỗ trợ Terraform.

  1. Mở tệp main.tf.

  2. Trong phần thiết lập provider, hãy thêm cấu hình sau của các khối resource.

    Ví dụ cơ bản này tạo một dự án Firebase mới, sau đó tạo một ứng dụng Firebase cho Android trong dự án đó.

    # Terraform configuration to set up providers by version.
    ...
    
    # Configures the provider to use the resource block's specified project for quota checks.
    ...
    
    # Configures the provider to not use the resource block's specified project for quota checks.
    ...
    
    # Creates a new Google Cloud project.
    resource "google_project" "default" {
      provider   = google-beta.no_user_project_override
    
      name       = "Project Display Name"
      project_id = "project-id-for-new-project"
      # Required for any service that requires the Blaze pricing plan
      # (like Firebase Authentication with GCIP)
      billing_account = "000000-000000-000000"
    
      # Required for the project to display in any list of Firebase projects.
      labels = {
        "firebase" = "enabled"
      }
    }
    
    # Enables required APIs.
    resource "google_project_service" "default" {
      provider = google-beta.no_user_project_override
      project  = google_project.default.project_id
      for_each = toset([
        "cloudbilling.googleapis.com",
        "cloudresourcemanager.googleapis.com",
        "firebase.googleapis.com",
        # Enabling the ServiceUsage API allows the new project to be quota checked from now on.
        "serviceusage.googleapis.com",
      ])
      service = each.key
    
      # Don't disable the service if the resource block is removed by accident.
      disable_on_destroy = false
    }
    
    # Enables Firebase services for the new project created above.
    resource "google_firebase_project" "default" {
      provider = google-beta
      project  = google_project.default.project_id
    
      # Waits for the required APIs to be enabled.
      depends_on = [
        google_project_service.default
      ]
    }
    
    # Creates a Firebase Android App in the new project created above.
    resource "google_firebase_android_app" "default" {
      provider = google-beta
    
      project      = google_project.default.project_id
      display_name = "My Awesome Android app"
      package_name = "awesome.package.name"
    
      # Wait for Firebase to be enabled in the Google Cloud project before creating this App.
      depends_on = [
        google_firebase_project.default,
      ]
    }

Nếu bạn chưa quen với cơ sở hạ tầng của các dự án và ứng dụng dưới dạng tài nguyên, hãy xem lại tài liệu sau:

# Terraform configuration to set up providers by version.
...

# Configures the provider to use the resource block's specified project for quota checks.
...

# Configures the provider to not use the resource block's specified project for quota checks.
...

# Creates a new Google Cloud project.
resource "google_project" "default" {
  # Use the provider that enables the setup of quota checks for a new project
  provider   = google-beta.no_user_project_override

  name            = "Project Display Name"        // learn more about the project name
  project_id      = "project-id-for-new-project"  // learn more about the project ID
  # Required for any service that requires the Blaze pricing plan
  # (like Firebase Authentication with GCIP)
  billing_account = "000000-000000-000000"

  # Required for the project to display in any list of Firebase projects.
  labels = {
    "firebase" = "enabled"  // learn more about the Firebase-enabled label
  }
}

# Enables required APIs.
resource "google_project_service" "default" {
  # Use the provider without quota checks for enabling APIS
  provider = google-beta.no_user_project_override
  project  = google_project.default.project_id
  for_each = toset([
    "cloudbilling.googleapis.com",
    "cloudresourcemanager.googleapis.com",
    "firebase.googleapis.com",
    # Enabling the ServiceUsage API allows the new project to be quota checked from now on.
    "serviceusage.googleapis.com",
  ])
  service = each.key

  # Don't disable the service if the resource block is removed by accident.
  disable_on_destroy = false
}

# Enables Firebase services for the new project created above.
# This action essentially "creates a Firebase project" and allows the project to use
# Firebase services (like Firebase Authentication) and
# Firebase tooling (like the Firebase console).
# Learn more about the relationship between Firebase projects and Google Cloud.
resource "google_firebase_project" "default" {
  # Use the provider that performs quota checks from now on
  provider = google-beta

  project  = google_project.default.project_id

  # Waits for the required APIs to be enabled.
  depends_on = [
    google_project_service.default
  ]
}

# Creates a Firebase Android App in the new project created above.
# Learn more about the relationship between Firebase Apps and Firebase projects.
resource "google_firebase_android_app" "default" {
  provider = google-beta

  project      = google_project.default.project_id
  display_name = "My Awesome Android app"  # learn more about an app's display name
  package_name = "awesome.package.name"    # learn more about an app's package name

  # Wait for Firebase to be enabled in the Google Cloud project before creating this App.
  depends_on = [
    google_firebase_project.default,
  ]
}


Bước 2: Chạy các lệnh Terraform để tạo cơ sở hạ tầng đã chỉ định

Để phân bổ tài nguyên và bật các dịch vụ được chỉ định trong tệp main.tf, hãy chạy các lệnh sau trong cùng thư mục với tệp main.tf. Để biết thông tin chi tiết về các lệnh này, hãy xem tài liệu về Terraform.

  1. Nếu đây là lần đầu tiên bạn chạy các lệnh Terraform trong thư mục, bạn cần khởi chạy thư mục cấu hình và cài đặt trình cung cấp Terraform của Google. Bạn có thể thực hiện việc này bằng cách chạy lệnh sau:

    terraform init
  2. Tạo cơ sở hạ tầng được chỉ định trong tệp main.tf bằng cách chạy lệnh sau:

    terraform apply
  3. Xác nhận rằng mọi thứ đã được cấp phép hoặc bật như mong đợi:

    • Cách 1: Xem cấu hình được in trong thiết bị đầu cuối bằng cách chạy lệnh sau:

      terraform show
    • Cách 2: Xem dự án Firebase trong bảng điều khiển Firebase.



Tài nguyên Firebase có hỗ trợ Terraform

Các tài nguyên sau đây của Firebase và Google có hỗ trợ Terraform. Chúng tôi luôn bổ sung thêm tài nguyên! Vì vậy, nếu bạn không thấy tài nguyên mà mình muốn quản lý bằng Terraform, hãy kiểm tra lại sớm để xem tài nguyên đó có sẵn hay không hoặc yêu cầu tài nguyên đó bằng cách gửi vấn đề trong kho lưu trữ GitHub.


Quản lý dự án và ứng dụng Firebase

  • google_firebase_project – bật các dịch vụ Firebase trên dự án Google Cloud hiện có

  • Ứng dụng Firebase


Firebase Authentication

  • google_identity_platform_config – bật Google Cloud Identity Platform (GCIP) (phần phụ trợ cho Firebase Authentication) và cung cấp chế độ cài đặt xác thực cấp dự án

    • Bạn cần bật GCIP để định cấu hình Firebase Authentication thông qua Terraform. Hãy nhớ xem lại tệp .tf mẫu để biết cách thiết lập Firebase Authentication.

    • Dự án mà Terraform sẽ bật GCIP và/hoặc Firebase Authentication phải thuộc gói giá Blaze (tức là dự án phải có tài khoản Cloud Billing được liên kết). Bạn có thể thực hiện việc này theo phương thức lập trình bằng cách đặt thuộc tính billing_account trong tài nguyên google_project.

    • Tài nguyên này cũng cho phép nhiều cấu hình hơn, chẳng hạn như các phương thức đăng nhập cục bộ, chẳng hạn như xác thực ẩn danh, email/mật khẩu và xác thực qua điện thoại, cũng như chặn các hàm và miền được uỷ quyền.

  • google_identity_platform_default_supported_idp_config – định cấu hình các Nhà cung cấp danh tính liên kết phổ biến, chẳng hạn như Google, Facebook hoặc Apple

  • identity_platform_oauth_idp_config – định cấu hình các nguồn Nhà cung cấp danh tính (IdP) OAuth tuỳ ý

  • google_identity_platform_inbound_saml_config – định cấu hình các chế độ tích hợp SAML

Chưa được hỗ trợ:

  • Định cấu hình tính năng xác thực đa yếu tố (MFA) thông qua Terraform

Firebase Data Connect


Firebase Realtime Database

Chưa được hỗ trợ:

  • Triển khai Firebase Realtime Database Security Rules thông qua Terraform (tìm hiểu cách triển khai các Rules này bằng các công cụ khác, bao gồm cả các tuỳ chọn có lập trình)

Cloud Firestore

  • google_firestore_database – tạo một thực thể Cloud Firestore

  • google_firestore_index – bật các truy vấn hiệu quả cho Cloud Firestore

  • google_firestore_document – tạo một thực thể Cloud Firestore bằng một tài liệu cụ thể trong một bộ sưu tập

    Lưu ý quan trọng: Không sử dụng dữ liệu người dùng cuối thực hoặc dữ liệu sản xuất trong tài liệu hạt giống này.


Cloud Storage for Firebase

  • google_firebase_storage_bucket – cho phép truy cập vào một bộ chứa Cloud Storage hiện có cho SDK Firebase, xác thực và Firebase Security Rules

  • google_storage_bucket_object – thêm một đối tượng vào bộ chứa Cloud Storage

    Lưu ý quan trọng: Không sử dụng dữ liệu thực tế của người dùng cuối hoặc dữ liệu sản xuất trong tệp này.


Firebase Security Rules (dành cho Cloud FirestoreCloud Storage)

Xin lưu ý rằng Firebase Realtime Database sử dụng một hệ thống cấp phép khác cho Firebase Security Rules.

  • google_firebaserules_ruleset – xác định Firebase Security Rules áp dụng cho một thực thể Cloud Firestore hoặc một bộ chứa Cloud Storage

  • google_firebaserules_release – triển khai các bộ quy tắc cụ thể cho một thực thể Cloud Firestore hoặc một bộ chứa Cloud Storage


Firebase App Check


Firebase Extensions



Tệp cấu hình Terraform mẫu cho các trường hợp sử dụng phổ biến

Cấu hình này tạo một dự án Google Cloud mới, liên kết dự án với tài khoản Cloud Billing (bạn phải có gói giá Blaze cho Firebase Authentication với GCIP), bật các dịch vụ Firebase cho dự án, thiết lập Firebase Authentication với GCIP và đăng ký ba loại ứng dụng khác nhau với dự án.

Xin lưu ý rằng bạn phải bật GCIP để thiết lập Firebase Authentication thông qua Terraform.

# Creates a new Google Cloud project.
resource "google_project" "auth" {
  provider  = google-beta.no_user_project_override
  folder_id = "folder-id-for-new-project"
  name            = "Project Display Name"
  project_id      = "project-id-for-new-project"

  # Associates the project with a Cloud Billing account
  # (required for Firebase Authentication with GCIP).
  billing_account = "000000-000000-000000"

  # Required for the project to display in a list of Firebase projects.
  labels = {
    "firebase" = "enabled"
  }
}

# Enables required APIs.
resource "google_project_service" "auth" {
  provider = google-beta.no_user_project_override
  project  = google_project.auth.project_id
  for_each = toset([
    "cloudbilling.googleapis.com",
    "cloudresourcemanager.googleapis.com",
    "serviceusage.googleapis.com",
    "identitytoolkit.googleapis.com",
  ])
  service = each.key

  # Don't disable the service if the resource block is removed by accident.
  disable_on_destroy = false
}

# Enables Firebase services for the new project created above.
resource "google_firebase_project" "auth" {
  provider = google-beta
  project  = google_project.auth.project_id

  depends_on = [
    google_project_service.auth,
  ]
}

# Creates an Identity Platform config.
# Also enables Firebase Authentication with Identity Platform in the project if not.
resource "google_identity_platform_config" "auth" {
  provider = google-beta
  project  = google_project.auth.project_id

  # Auto-deletes anonymous users
  autodelete_anonymous_users = true

  # Configures local sign-in methods, like anonymous, email/password, and phone authentication.
  sign_in {
    allow_duplicate_emails = true

    anonymous {
      enabled = true
    }

    email {
      enabled = true
      password_required = false
    }

    phone_number {
      enabled = true
      test_phone_numbers = {
        "+11231231234" = "000000"
      }
    }
  }

  # Sets an SMS region policy.
  sms_region_config {
    allowlist_only {
      allowed_regions = [
        "US",
        "CA",
      ]
    }
  }

  # Configures blocking functions.
  blocking_functions {
    triggers {
      event_type = "beforeSignIn"
      function_uri = "https://us-east1-${google_project.auth.project_id}.cloudfunctions.net/before-sign-in"
    }
    forward_inbound_credentials {
      refresh_token = true
      access_token = true
      id_token = true
    }
  }

  # Configures a temporary quota for new signups for anonymous, email/password, and phone number.
  quota {
    sign_up_quota_config {
      quota = 1000
      start_time = ""
      quota_duration = "7200s"
    }
  }

  # Configures authorized domains.
  authorized_domains = [
    "localhost",
    "${google_project.auth.project_id}.firebaseapp.com",
    "${google_project.auth.project_id}.web.app",
  ]

  # Wait for identitytoolkit.googleapis.com to be enabled before initializing Authentication.
  depends_on = [
    google_project_service.auth,
  ]
}

# Creates a Firebase Android App in the new project created above.
resource "google_firebase_android_app" "auth" {
  provider     = google-beta
  project      = google_project.auth.project_id
  display_name = "My Android app"
  package_name = "android.package.name"

  # Wait for Firebase to be enabled in the Google Cloud project before creating this App.
  depends_on = [
    google_firebase_project.auth,
  ]
}

# Creates a Firebase Apple-platforms App in the new project created above.
resource "google_firebase_apple_app" "auth" {
  provider     = google-beta
  project      = google_project.auth.project_id
  display_name = "My Apple app"
  bundle_id    = "apple.app.12345"

  # Wait for Firebase to be enabled in the Google Cloud project before creating this App.
  depends_on = [
    google_firebase_project.auth,
  ]
}

# Creates a Firebase Web App in the new project created above.
resource "google_firebase_web_app" "auth" {
  provider     = google-beta
  project      = google_project.auth.project_id
  display_name = "My Web app"

  # The other App types (Android and Apple) use "DELETE" by default.
  # Web apps don't use "DELETE" by default due to backward-compatibility.
  deletion_policy = "DELETE"

  # Wait for Firebase to be enabled in the Google Cloud project before creating this App.
  depends_on = [
    google_firebase_project.auth,
  ]
}

Cấu hình này tạo một dự án Google Cloud mới, bật các dịch vụ Firebase cho dự án và cung cấp dịch vụ Data Connect.

# Creates a new Google Cloud project.
resource "google_project" "dataconnect" {
  provider   = google-beta.no_user_project_override
  folder_id  = "folder-id-for-new-project"
  name       = "Project Display Name"
  project_id = "project-id-for-new-project"

  # Associates the project with a Cloud Billing account
  # (required to use Firebase Data Connect).
  billing_account = "000000-000000-000000"

  # Required for the project to display in a list of Firebase projects.
  labels = {
    "firebase" = "enabled"
  }
}

# Enables required APIs.
resource "google_project_service" "services" {
  provider = google-beta.no_user_project_override
  project  = google_project.dataconnect.project_id
  for_each = toset([
    "serviceusage.googleapis.com",
    "cloudresourcemanager.googleapis.com",
    "firebasedataconnect.googleapis.com",
  ])
  service = each.key

  # Don't disable the service if the resource block is removed by accident.
  disable_on_destroy = false
}

# Enables Firebase services for the new project created earlier.
resource "google_firebase_project" "dataconnect" {
  provider = google-beta
  project  = google_project.dataconnect.project_id

  depends_on = [google_project_service.services]
}

# Create a Firebase Data Connect service
resource "google_firebase_data_connect_service" "dataconnect-default" {
  project         = google_firebase_project.dataconnect.project
  location        = "name-of-region-for-service"
  service_id      = "${google_firebase_project.dataconnect.project}-default-fdc"
  deletion_policy = "DEFAULT"
}

Cấu hình này tạo một dự án Google Cloud mới, bật các dịch vụ Firebase cho dự án, cung cấp thực thể Realtime Database mặc định của dự án và đăng ký ba loại ứng dụng khác nhau với dự án.

# Creates a new Google Cloud project.
resource "google_project" "rtdb" {
  provider   = google-beta.no_user_project_override
  folder_id  = "folder-id-for-new-project"
  name       = "Project Display Name"
  project_id = "project-id-for-new-project"

  # Required for the project to display in a list of Firebase projects.
  labels = {
    "firebase" = "enabled"
  }
}

# Enables required APIs.
resource "google_project_service" "rtdb" {
  provider = google-beta.no_user_project_override
  project  = google_project.rtdb.project_id
  for_each = toset([
    "serviceusage.googleapis.com",
    "cloudresourcemanager.googleapis.com",
    "firebasedatabase.googleapis.com",
  ])
  service = each.key

  # Don't disable the service if the resource block is removed by accident.
  disable_on_destroy = false
}

# Enables Firebase services for the new project created above.
resource "google_firebase_project" "rtdb" {
  provider = google-beta
  project  = google_project.rtdb.project_id
}

# Provisions the default Realtime Database default instance.
resource "google_firebase_database_instance" "database" {
  provider    = google-beta
  project     = google_project.rtdb.project_id
  # See available locations: https://firebase.google.com/docs/database/locations
  region      = "name-of-region"
  # This value will become the first segment of the database's URL.
  instance_id = "${google_project.rtdb.project_id}-default-rtdb"
  type        = "DEFAULT_DATABASE"

  # Wait for Firebase to be enabled in the Google Cloud project before initializing Realtime Database.
  depends_on = [
    google_firebase_project.rtdb,
  ]
}

# Creates a Firebase Android App in the new project created above.
resource "google_firebase_android_app" "rtdb" {
  provider     = google-beta
  project      = google_project.rtdb.project_id
  display_name = "My Android app"
  package_name = "android.package.name"

  # Wait for Firebase to be enabled in the Google Cloud project before creating this App.
  depends_on = [
    google_firebase_project.rtdb,
  ]
}

# Creates a Firebase Apple-platforms App in the new project created above.
resource "google_firebase_apple_app" "rtdb" {
  provider     = google-beta
  project      = google_project.rtdb.project_id
  display_name = "My Apple app"
  bundle_id    = "apple.app.12345"

  # Wait for Firebase to be enabled in the Google Cloud project before creating this App.
  depends_on = [
    google_firebase_project.rtdb,
  ]
}

# Creates a Firebase Web App in the new project created above.
resource "google_firebase_web_app" "rtdb" {
  provider     = google-beta
  project      = google_project.rtdb.project_id
  display_name = "My Web app"

  # The other App types (Android and Apple) use "DELETE" by default.
  # Web apps don't use "DELETE" by default due to backward-compatibility.
  deletion_policy = "DELETE"

  # Wait for Firebase to be enabled in the Google Cloud project before creating this App.
  depends_on = [
    google_firebase_project.rtdb,
  ]
}

Cấu hình này tạo một dự án Google Cloud mới, liên kết dự án với tài khoản Cloud Billing (bạn phải có gói giá Blaze cho nhiều phiên bản Realtime Database), bật các dịch vụ Firebase cho dự án, cung cấp nhiều phiên bản Realtime Database (bao gồm cả phiên bản Realtime Database mặc định của dự án) và đăng ký ba loại ứng dụng khác nhau với dự án.

# Creates a new Google Cloud project.
resource "google_project" "rtdb-multi" {
  provider   = google-beta.no_user_project_override
  folder_id  = "folder-id-for-new-project"
  name       = "Project Display Name"
  project_id = "project-id-for-new-project"

  # Associate the project with a Cloud Billing account
  # (required for multiple Realtime Database instances).
  billing_account = "000000-000000-000000"

  # Required for the project to display in a list of Firebase projects.
  labels = {
    "firebase" = "enabled"
  }
}

# Enables required APIs.
resource "google_project_service" "rtdb-multi" {
  provider = google-beta.no_user_project_override
  project  = google_project.rtdb-multi.project_id
  for_each = toset([
    "cloudbilling.googleapis.com",
    "serviceusage.googleapis.com",
    "cloudresourcemanager.googleapis.com",
    "firebasedatabase.googleapis.com",
  ])
  service = each.key

  # Don't disable the service if the resource block is removed by accident.
  disable_on_destroy = false
}

# Enables Firebase services for the new project created above.
resource "google_firebase_project" "rtdb-multi" {
  provider = google-beta
  project  = google_project.rtdb-multi.project_id
}

# Provisions the default Realtime Database default instance.
resource "google_firebase_database_instance" "database-default" {
  provider    = google-beta
  project     = google_project.rtdb-multi.project_id
  # See available locations: https://firebase.google.com/docs/database/locations
  region      = "name-of-region"
  # This value will become the first segment of the database's URL.
  instance_id = "${google_project.rtdb-multi.project_id}-default-rtdb"
  type        = "DEFAULT_DATABASE"

  # Wait for Firebase to be enabled in the Google Cloud project before initializing Realtime Database.
  depends_on = [
    google_firebase_project.rtdb-multi,
  ]
}

# Provisions an additional Realtime Database instance.
resource "google_firebase_database_instance" "database-additional" {
  provider    = google-beta
  project     = google_project.rtdb-multi.project_id
  # See available locations: https://firebase.google.com/docs/projects/locations#rtdb-locations
  # This location doesn't need to be the same as the default database instance.
  region      = "name-of-region"
  # This value will become the first segment of the database's URL.
  instance_id = "name-of-additional-database-instance"
  type        = "USER_DATABASE"

  # Wait for Firebase to be enabled in the Google Cloud project before initializing Realtime Database.
  depends_on = [
    google_firebase_project.rtdb-multi,
  ]
}

# Creates a Firebase Android App in the new project created above.
resource "google_firebase_android_app" "rtdb-multi" {
  provider     = google-beta
  project      = google_project.rtdb-multi.project_id
  display_name = "My Android app"
  package_name = "android.package.name"

  # Wait for Firebase to be enabled in the Google Cloud project before creating this App.
  depends_on = [
    google_firebase_project.rtdb-multi,
  ]
}

# Creates a Firebase Apple-platforms App in the new project created above.
resource "google_firebase_apple_app" "rtdb-multi" {
  provider     = google-beta
  project      = google_project.rtdb-multi.project_id
  display_name = "My Apple app"
  bundle_id    = "apple.app.12345"

  # Wait for Firebase to be enabled in the Google Cloud project before creating this App.
  depends_on = [
    google_firebase_project.rtdb-multi,
  ]
}

# Creates a Firebase Web App in the new project created above.
resource "google_firebase_web_app" "rtdb-multi" {
  provider     = google-beta
  project      = google_project.rtdb-multi.project_id
  display_name = "My Web app"

  # The other App types (Android and Apple) use "DELETE" by default.
  # Web apps don't use "DELETE" by default due to backward-compatibility.
  deletion_policy = "DELETE"

  # Wait for Firebase to be enabled in the Google Cloud project before creating this App.
  depends_on = [
    google_firebase_project.rtdb-multi,
  ]
}

Cấu hình này tạo một dự án Google Cloud mới, bật các dịch vụ Firebase cho dự án, cung cấp thực thể Cloud Firestore mặc định của dự án và đăng ký ba loại ứng dụng khác nhau với dự án.

Lớp này cũng cấp Firebase Security Rules cho thực thể Cloud Firestore mặc định, tạo chỉ mục Cloud Firestore và thêm tài liệu Cloud Firestore có dữ liệu hạt giống.

# Creates a new Google Cloud project.
resource "google_project" "firestore" {
  provider   = google-beta.no_user_project_override
  folder_id  = "folder-id-for-new-project"
  name       = "Project Display Name"
  project_id = "project-id-for-new-project"

  # Required for the project to display in a list of Firebase projects.
  labels = {
    "firebase" = "enabled"
  }
}

# Enables required APIs.
resource "google_project_service" "firestore" {
  provider = google-beta.no_user_project_override
  project  = google_project.firestore.project_id
  for_each = toset([
    "cloudresourcemanager.googleapis.com",
    "serviceusage.googleapis.com",
    "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
}

# Enables Firebase services for the new project created above.
resource "google_firebase_project" "firestore" {
  provider = google-beta
  project  = google_project.firestore.project_id
}

# Provisions the Firestore database instance.
resource "google_firestore_database" "firestore" {
  provider                    = google-beta
  project                     = google_project.firestore.project_id
  name                        = "(default)"
  # See available locations: https://firebase.google.com/docs/firestore/locations
  location_id                 = "name-of-region"
  # "FIRESTORE_NATIVE" is required to use Firestore with Firebase SDKs, authentication, and Firebase Security Rules.
  type                        = "FIRESTORE_NATIVE"
  concurrency_mode            = "OPTIMISTIC"

  # Wait for Firebase to be enabled in the Google Cloud project before initializing Firestore.
  depends_on = [
    google_firebase_project.firestore,
  ]
}

# Creates a ruleset of Firestore Security Rules from a local file.
resource "google_firebaserules_ruleset" "firestore" {
  provider = google-beta
  project  = google_project.firestore.project_id
  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.firestore,
  ]
}

# Releases 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_project.firestore.project_id

  # Wait for Firestore to be provisioned before releasing the ruleset.
  depends_on = [
    google_firestore_database.firestore,
  ]
}

# Adds a new Firestore index.
resource "google_firestore_index" "indexes" {
  provider = google-beta
  project  = google_project.firestore.project_id

  collection  = "quiz"
  query_scope = "COLLECTION"

  fields {
    field_path = "question"
    order      = "ASCENDING"
  }

  fields {
    field_path = "answer"
    order      = "ASCENDING"
  }

  # Wait for Firestore to be provisioned before adding this index.
  depends_on = [
    google_firestore_database.firestore,
  ]
}

# Adds a new Firestore document with seed data.
# Don't use real end-user or production data in this seed document.
resource "google_firestore_document" "doc" {
  provider    = google-beta
  project     = google_project.firestore.project_id
  collection  = "quiz"
  document_id = "question-1"
  fields      = "{\"question\":{\"stringValue\":\"Favorite Database\"},\"answer\":{\"stringValue\":\"Firestore\"}}"

  # Wait for Firestore to be provisioned before adding this document.
  depends_on = [
    google_firestore_database.firestore,
  ]
}

# Creates a Firebase Android App in the new project created above.
resource "google_firebase_android_app" "firestore" {
  provider     = google-beta
  project      = google_project.firestore.project_id
  display_name = "My Android app"
  package_name = "android.package.name"

  # Wait for Firebase to be enabled in the Google Cloud project before creating this App.
  depends_on = [
    google_firebase_project.firestore,
  ]
}

# Creates a Firebase Apple-platforms App in the new project created above.
resource "google_firebase_apple_app" "firestore" {
  provider     = google-beta
  project      = google_project.firestore.project_id
  display_name = "My Apple app"
  bundle_id    = "apple.app.12345"

  # Wait for Firebase to be enabled in the Google Cloud project before creating this App.
  depends_on = [
    google_firebase_project.firestore,
  ]
}

# Creates a Firebase Web App in the new project created above.
resource "google_firebase_web_app" "firestore" {
  provider     = google-beta
  project      = google_project.firestore.project_id
  display_name = "My Web app"

  # The other App types (Android and Apple) use "DELETE" by default.
  # Web apps don't use "DELETE" by default due to backward-compatibility.
  deletion_policy = "DELETE"

  # Wait for Firebase to be enabled in the Google Cloud project before creating this App.
  depends_on = [
    google_firebase_project.firestore,
  ]
}

Đây là bộ quy tắc của Cloud Firestore Security Rules, nằm trong tệp cục bộ có tên là firestore.rules.

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /some_collection/{document} {
      allow read, create, update: if request.auth != null;
    }
  }
}

Cấu hình này tạo một dự án Google Cloud mới, liên kết dự án với tài khoản Cloud Billing (bạn phải sử dụng gói giá linh hoạt cho các bộ chứa bổ sung), bật các dịch vụ Firebase cho dự án, cung cấp các bộ chứa Cloud Storage bổ sung, không phải mặc định và đăng ký ba loại ứng dụng khác nhau với dự án.

Ứng dụng này cũng cung cấp Firebase Security Rules cho mỗi bộ chứa Cloud Storage và tải một tệp lên một trong các bộ chứa Cloud Storage.

# Creates a new Google Cloud project.
resource "google_project" "storage-multi" {
  provider  = google-beta.no_user_project_override
  folder_id = "folder-id-for-new-project"
  name            = "Project Display Name"
  project_id      = "project-id-for-new-project"

  # Associates the project with a Cloud Billing account
  # (required for multiple Cloud Storage buckets).
  billing_account = "000000-000000-000000"

  # Required for the project to display in a list of Firebase projects.
  labels = {
    "firebase" = "enabled"
  }
}

# Enables required APIs.
resource "google_project_service" "storage-multi" {
  provider = google-beta.no_user_project_override
  project  = google_project.storage-multi.project_id
  for_each = toset([
    "cloudbilling.googleapis.com",
    "serviceusage.googleapis.com",
    "cloudresourcemanager.googleapis.com",
    "firebaserules.googleapis.com",
    "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
}

# Enables Firebase services for the new project created above.
resource "google_firebase_project" "storage-multi" {
  provider = google-beta
  project  = google_project.storage-multi.project_id
}

# Provisions a Cloud Storage bucket.
resource "google_storage_bucket" "bucket-1" {
  provider = google-beta
  project  = google_project.storage-multi.project_id
  name     = "name-of-storage-bucket"
  # See available locations: https://cloud.google.com/storage/docs/locations#available-locations
  location = "name-of-region-for-bucket"
}

# Provisions an additional Cloud Storage bucket.
resource "google_storage_bucket" "bucket-2" {
  provider = google-beta
  project  = google_project.storage-multi.project_id
  name     = "name-of-additional-storage-bucket"
  # See available locations: https://cloud.google.com/storage/docs/locations#available-locations
  # This location does not need to be the same as the existing Storage bucket.
  location = "name-of-region-for-additional-bucket"
}

# Makes the first Storage bucket accessible for Firebase SDKs, authentication, and Firebase Security Rules.
resource "google_firebase_storage_bucket" "bucket-1" {
  provider  = google-beta
  project   = google_project.storage-multi.project_id
  bucket_id = google_storage_bucket.bucket-1.name
}

# Makes the additional Storage bucket accessible for Firebase SDKs, authentication, and Firebase Security Rules.
resource "google_firebase_storage_bucket" "bucket-2" {
  provider  = google-beta
  project   = google_project.storage-multi.project_id
  bucket_id = google_storage_bucket.bucket-2.name
}

# Creates a ruleset of Firebase Security Rules from a local file.
resource "google_firebaserules_ruleset" "storage-multi" {
  provider = google-beta
  project  = google_project.storage-multi.project_id
  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 Storage buckets to be provisioned before creating this ruleset.
  depends_on = [
    google_firebase_project.storage-multi,
  ]
}

# Releases the ruleset to the first Storage bucket.
resource "google_firebaserules_release" "bucket-1" {
  provider     = google-beta
  name         = "firebase.storage/${google_storage_bucket.bucket-1.name}"
  ruleset_name = "projects/${google_project.storage-multi.project_id}/rulesets/${google_firebaserules_ruleset.storage-multi.name}"
  project      = google_project.storage-multi.project_id
}

# Releases the ruleset to the additional Storage bucket.
resource "google_firebaserules_release" "bucket-2" {
  provider     = google-beta
  name         = "firebase.storage/${google_storage_bucket.bucket-2.name}"
  ruleset_name = "projects/${google_project.storage-multi.project_id}/rulesets/${google_firebaserules_ruleset.storage-multi.name}"
  project      = google_project.storage-multi.project_id
}

# Uploads a new file to the first Storage bucket.
# Do not use real end-user or production data in this file.
resource "google_storage_bucket_object" "cat-picture-multi" {
  provider = google-beta
  name     = "cat.png"
  source   = "path/to/cat.png"
  bucket   = google_storage_bucket.bucket-1.name
}

# Creates a Firebase Android App in the new project created above.
resource "google_firebase_android_app" "storage-multi" {
  provider     = google-beta
  project      = google_project.storage-multi.project_id
  display_name = "My Android app"
  package_name = "android.package.name"

  # Wait for Firebase to be enabled in the Google Cloud project before creating this App.
  depends_on = [
    google_firebase_project.storage-multi,
  ]
}

# Creates a Firebase Apple-platforms App in the new project created above.
resource "google_firebase_apple_app" "storage-multi" {
  provider     = google-beta
  project      = google_project.storage-multi.project_id
  display_name = "My Apple app"
  bundle_id    = "apple.app.12345"

  # Wait for Firebase to be enabled in the Google Cloud project before creating this App.
  depends_on = [
    google_firebase_project.storage-multi,
  ]
}

# Creates a Firebase Web App in the new project created above.
resource "google_firebase_web_app" "storage-multi" {
  provider     = google-beta
  project      = google_project.storage-multi.project_id
  display_name = "My Web app"

  # Wait for Firebase to be enabled in the Google Cloud project before creating this App.
  depends_on = [
    google_firebase_project.storage-multi,
  ]
}

Đây là bộ quy tắc của Cloud Storage Security Rules, nằm trong tệp cục bộ có tên là storage.rules.

rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    match /some_folder/{fileName} {
      allow read, write: if request.auth != null;
    }
  }
}

Cấu hình này tạo một dự án Google Cloud mới, bật các dịch vụ Firebase cho dự án, đồng thời thiết lập và bật tính năng thực thi Firebase App Check cho Cloud Firestore để chỉ có thể truy cập vào dự án này từ ứng dụng Android.

# Creates a new Google Cloud project.
resource "google_project" "appcheck" {
  provider   = google-beta.no_user_project_override
  folder_id  = "folder-id-for-new-project"
  name       = "Project Display Name"
  project_id = "project-id-for-new-project"

  # Required for the project to display in a list of Firebase projects.
  labels = {
    "firebase" = "enabled"
  }
}

# Enables required APIs.
resource "google_project_service" "services" {
  provider = google-beta.no_user_project_override
  project  = google_project.appcheck.project_id
  for_each = toset([
    "cloudresourcemanager.googleapis.com",
    "firebase.googleapis.com",
    "firebaseappcheck.googleapis.com",
    "firestore.googleapis.com",
    "serviceusage.googleapis.com",
  ])
  service = each.key

  # Don't disable the service if the resource block is removed by accident.
  disable_on_destroy = false
}

# Enables Firebase services for the new project created earlier.
resource "google_firebase_project" "appcheck" {
  provider = google-beta
  project  = google_project.appcheck.project_id

  depends_on = [google_project_service.services]
}

# Provisions the Firestore database instance.
resource "google_firestore_database" "database" {
  provider = google-beta
  project  = google_firebase_project.appcheck.project
  name     = "(default)"
  # See available locations: https://firebase.google.com/docs/projects/locations#default-cloud-location
  location_id = "name-of-region"
  # "FIRESTORE_NATIVE" is required to use Firestore with Firebase SDKs, authentication, and Firebase Security Rules.
  type             = "FIRESTORE_NATIVE"
  concurrency_mode = "OPTIMISTIC"

  # Wait for Firebase to be enabled in the Google Cloud project before initializing Firestore.
  depends_on = [
    google_firebase_project.appcheck,
  ]
}

# Creates a Firebase Android App in the new project created earlier.
resource "google_firebase_android_app" "appcheck" {
  provider     = google-beta
  project      = google_firebase_project.appcheck.project
  display_name = "Play Integrity app"
  package_name = "package.name.playintegrity"
  sha256_hashes = [
    # TODO: insert your Android app's SHA256 certificate
  ]
}

# It takes a while for App Check to recognize the new app
# If your app already exists, you don't have to wait 30 seconds.
resource "time_sleep" "wait_30s" {
  depends_on      = [google_firebase_android_app.appcheck]
  create_duration = "30s"
}

# Register the Android app with the Play Integrity provider
resource "google_firebase_app_check_play_integrity_config" "appcheck" {
  provider = google-beta
  project  = google_firebase_project.appcheck.project
  app_id   = google_firebase_android_app.appcheck.app_id

  depends_on = [time_sleep.wait_30s, google_firestore_database.database]

  lifecycle {
    precondition {
      condition     = length(google_firebase_android_app.appcheck.sha256_hashes) > 0
      error_message = "Provide a SHA-256 certificate on the Android App to use App Check"
    }
  }
}

# Enable enforcement of App Check for Firestore
resource "google_firebase_app_check_service_config" "firestore" {
  provider = google-beta

  project    = google_firebase_project.appcheck.project
  service_id = "firestore.googleapis.com"

  depends_on = [google_project_service.services]
}

Cấu hình này tạo một dự án Google Cloud mới, bật các dịch vụ Firebase cho dự án và cài đặt một thực thể mới của Firebase Extension trong dự án. Nếu thực thể đã tồn tại, thì các tham số của thực thể đó sẽ được cập nhật dựa trên các giá trị được cung cấp trong cấu hình.

# Creates a new Google Cloud project.
resource "google_project" "extensions" {
  provider   = google-beta.no_user_project_override
  folder_id  = "folder-id-for-new-project"
  name       = "Project Display Name"
  project_id = "project-id-for-new-project"

  # Associates the project with a Cloud Billing account
  # (required to use Firebase Extensions).
  billing_account = "000000-000000-000000"

  # Required for the project to display in a list of Firebase projects.
  labels = {
    "firebase" = "enabled"
  }
}

# Enables required APIs.
resource "google_project_service" "extensions" {
  provider = google-beta.no_user_project_override
  project  = google_project.extensions.project_id
  for_each = toset([
    "cloudbilling.googleapis.com",
    "cloudresourcemanager.googleapis.com",
    "serviceusage.googleapis.com",
    "firebase.googleapis.com",
    "firebaseextensions.googleapis.com",
  ])
  service = each.key

  # Don't disable the service if the resource block is removed by accident.
  disable_on_destroy = false
}

# Enables Firebase services for the new project created above.
resource "google_firebase_project" "extensions" {
  provider = google-beta
  project  = google_project.extensions.project_id

  depends_on = [
    google_project_service.extensions,
  ]
}

# Installs an instance of the "Translate Text in Firestore" extension.
# Or updates the extension if the specified instance already exists.
resource "google_firebase_extensions_instance" "translation" {
  provider = google-beta
  project = google_project.extensions.project_id

  instance_id = "translate-text-in-firestore"
  config {
    extension_ref = "firebase/firestore-translate-text"

    params = {
      COLLECTION_PATH      = "posts/comments/translations"
      DO_BACKFILL          = true
      LANGUAGES            = "ar,en,es,de,fr"
      INPUT_FIELD_NAME     = "input"
      LANGUAGES_FIELD_NAME = "languages"
      OUTPUT_FIELD_NAME    = "translated"
    }

    system_params = {
      "firebaseextensions.v1beta.function/location"                   = "us-central1"
      "firebaseextensions.v1beta.function/memory"                     = "256"
      "firebaseextensions.v1beta.function/minInstances"               = "0"
      "firebaseextensions.v1beta.function/vpcConnectorEgressSettings" = "VPC_CONNECTOR_EGRESS_SETTINGS_UNSPECIFIED"
    }
  }
}



Khắc phục sự cố và câu hỏi thường gặp

Hướng dẫn này sử dụng các thuộc tính Terraform sau đây khi làm việc với "dự án".

project trong khối resource

Đề xuất: bất cứ khi nào có thể, hãy đưa thuộc tính project vào trong mỗi khối resource

Bằng cách thêm một thuộc tính dự án, Terraform sẽ tạo cơ sở hạ tầng được chỉ định trong khối tài nguyên trong dự án đã chỉ định. Hướng dẫn này và các tệp cấu hình mẫu của chúng tôi đều sử dụng phương pháp này.

Xem tài liệu chính thức của Terraform về project.

user_project_override trong khối provider

Để cấp phát hầu hết 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 theo dự án Firebase của riêng bạn. Tuy nhiên, để thiết lập dự án mới để có thể chấp nhận các yêu cầu kiểm tra hạn mức, trước tiên, bạn cần sử dụng user_project_override = false.

Xem tài liệu chính thức của Terraform về user_project_override.

Đảm bảo rằng tài khoản người dùng mà bạn đang sử dụng để chạy các lệnh gcloud CLI đã chấp nhận Điều khoản dịch vụ của Firebase (Điều khoản dịch vụ của Firebase).

  • Bạn có thể kiểm tra việc này bằng cách sử dụng một trình duyệt đã đăng nhập vào tài khoản người dùng và cố gắng xem một dự án Firebase hiện có trong bảng điều khiển Firebase. Nếu bạn có thể xem một dự án Firebase hiện có, thì tài khoản người dùng đó đã chấp nhận Điều khoản dịch vụ của Firebase.

  • Nếu bạn không thể xem bất kỳ dự án Firebase nào hiện có, thì tài khoản người dùng có thể chưa chấp nhận Điều khoản dịch vụ của Firebase. Để khắc phục vấn đề này, hãy tạo một dự án Firebase mới thông qua bảng điều khiển Firebase và chấp nhận Điều khoản dịch vụ của Firebase trong quá trình tạo dự án. Bạn có thể xoá ngay dự án này thông qua phần Project Settings (Cài đặt dự án) trong bảng điều khiển.

Đợi vài phút rồi thử chạy lại terraform apply.

Điều này có thể là do độ trễ truyền tải trong nhiều hệ thống. Hãy thử giải quyết vấn đề này bằng cách nhập tài nguyên vào trạng thái Terraform bằng cách chạy terraform import. Sau đó, hãy thử chạy lại terraform apply.

Bạn có thể tìm hiểu cách nhập từng tài nguyên trong phần "Nhập" của tài liệu Terraform (ví dụ: tài liệu"Nhập" cho Cloud Firestore).

Như lỗi cho thấy, Terraform có thể đang cố gắng phân bổ nhiều chỉ mục và/hoặc tạo một tài liệu cùng một lúc và gặp lỗi đồng thời. Hãy thử chạy lại terraform apply.

Lỗi này có nghĩa là Terraform không biết dự án nào sẽ kiểm tra hạn mức. Để khắc phục sự cố, hãy kiểm tra những nội dung sau trong khối resource:

  • Đảm bảo rằng bạn đã chỉ định giá trị cho thuộc tính project.
  • Đảm bảo rằng bạn đang sử dụng trình cung cấp bằng user_project_override = true (không có bí danh), trong các mẫu Firebase là google-beta.

Sau đây là một số lý do có thể khiến mã dự án đã tồn tại:

  • Dự án được liên kết với mã nhận dạng đó thuộc quyền sở hữu của người khác.

    • Cách giải quyết: Chọn một mã dự án khác.
  • Gần đây, dự án được liên kết với mã đó đã bị xoá (ở trạng thái xoá mềm).

    • Cách giải quyết: Nếu bạn cho rằng dự án được liên kết với mã nhận dạng này thuộc về bạn, hãy kiểm tra trạng thái của dự án bằng projects.get REST API.
  • Dự án được liên kết với mã nhận dạng đó tồn tại chính xác trong người dùng hiện tại. Một nguyên nhân có thể gây ra lỗi là terraform apply trước đó bị gián đoạn.

    • Cách giải quyết: Chạy các lệnh sau:
      terraform import google_project.default PROJECT_ID rồi
      terraform import google_firebase_project.default PROJECT_ID

Nếu bạn đã cấp phép cho bộ chứa Cloud Storage mặc định (thông qua google_app_engine_application) trước khi bạn cố gắng cấp phép cho thực thể Cloud Firestore mặc định, thì bạn sẽ thấy rằng thực thể Cloud Firestore mặc định đã được cấp phép. Xin lưu ý rằng phiên bản cơ sở dữ liệu được cấp phép đang ở chế độ Datastore, nghĩa là các SDK Firebase, quy trình xác thực hoặc Firebase Security Rules không truy cập được vào phiên bản này. Nếu muốn sử dụng Cloud Firestore với các dịch vụ Firebase này, bạn cần phải làm trống cơ sở dữ liệu rồi thay đổi loại cơ sở dữ liệu trong bảng điều khiển Google Cloud.

Khi bạn cấp vùng chứa Cloud Storage mặc định của dự án (thông qua google_app_engine_application) và dự án chưa có thực thể Cloud Firestore mặc định, thì google_app_engine_application sẽ tự động cấp thực thể Cloud Firestore mặc định của dự án.

Vì thực thể Cloud Firestore mặc định của dự án đã được cấp phép, nên google_firestore_database sẽ gặp lỗi nếu bạn cố gắng cấp phép lại thực thể mặc định đó một cách rõ ràng.

Sau khi thực thể Cloud Firestore mặc định của dự án được cấp phép, bạn không thể "cấp phép lại" thực thể đó hoặc thay đổi vị trí của thực thể đó. Xin lưu ý rằng thực thể cơ sở dữ liệu đã được cấp phép đang ở chế độ Datastore, tức là các SDK Firebase, quy trình xác thực hoặc Firebase Security Rules không truy cập được vào thực thể này. Nếu muốn sử dụng Cloud Firestore với các dịch vụ Firebase này, bạn cần phải làm trống cơ sở dữ liệu rồi thay đổi loại cơ sở dữ liệu trong bảng điều khiển Google Cloud.