אנחנו מתחילים להוסיף תמיכה ב-Terraform ל-Firebase.
אם אתם עובדים בצוות שרוצה להפוך את תהליך היצירה של פרויקטים ב-Firebase לאוטומטי ולסטנדרטי, עם הקצאה של משאבים ספציפיים והפעלה של שירותים, השימוש ב-Terraform עם Firebase יכול להתאים לכם.
תהליך העבודה הבסיסי לשימוש ב-Terraform עם Firebase כולל את השלבים הבאים:
יצירת קובץ תצורה של Terraform (קובץ .tf) בהתאמה אישית, שמציין את התשתית שרוצים להקצות (כלומר, המשאבים שרוצים להקצות והשירותים שרוצים להפעיל).
באמצעות פקודות gcloud CLI שמתחברות ל-Terraform כדי להקצות את התשתית שצוינה בקובץ .tf.
ניהול הגדרות ומשימות ספציפיות למוצר באמצעות Terraform, כמו:
הפעלת ספקי כניסה של Firebase Authentication.
יצירה של קטגוריות או מכונות של מסדי נתונים ב-Cloud Storage ופריסה של Firebase Security Rules בשבילן.
אפשר להשתמש בקובצי תצורה ובפקודות רגילים של Terraform כדי לבצע את כל המשימות האלה. כדי לעזור לכם בכך, סיפקנו דוגמאות לקובצי תצורה של Terraform לכמה תרחישים נפוצים.
תהליך עבודה כללי לשימוש ב-Terraform עם Firebase
דרישות מוקדמות
המדריך הזה הוא מבוא לשימוש ב-Terraform עם Firebase, ולכן הוא מבוסס על היכרות בסיסית עם Terraform. לפני שמתחילים בתהליך העבודה הזה, חשוב לוודא שהתנאים המוקדמים הבאים מתקיימים.
אם אתם משתמשים בחשבון משתמש, עליכם לאשר את התנאים וההגבלות של Firebase. אם אתם יכולים לראות פרויקט Firebase במסוף Firebase, סימן שאישרתם את התנאים וההגבלות של Firebase.
כדי ש-Terraform יבצע פעולות מסוימות (לדוגמה, יצירה של פרויקטים), צריכים להתקיים התנאים הבאים:
לחשבון המשתמש או לחשבון השירות צריכה להיות הרשאת הגישה הרלוונטית ב-IAM לביצוע הפעולות האלה.
אם חשבון המשתמש או חשבון השירות שייכים לארגון Google Cloud, מדיניות הארגון חייבת לאפשר לחשבון לבצע את הפעולות האלה.
שלב 1: יוצרים קובץ תצורה של Terraform ומתאימים אותו אישית
קובץ תצורה של Terraform צריך לכלול שני קטעים עיקריים (שמתוארים בפירוט בהמשך):
צריך להגדיר את provider, לא משנה אילו מוצרים או שירותים של Firebase מעורבים.
יוצרים קובץ תצורה של Terraform (כמו קובץ main.tf) בספרייה המקומית.
במדריך הזה, תשתמשו בקובץ התצורה הזה כדי לציין גם את ההגדרה של provider וגם את כל התשתית שתרצו ש-Terraform תיצור. עם זאת, חשוב לזכור שיש לכם אפשרויות שונות להכללת הגדרת הספק.
הצגת האפשרויות להכללת ההגדרה של provider
יש לכם את האפשרויות הבאות כדי לכלול הגדרה של provider בשאר התצורה של Terraform:
אפשרות 1: כוללים אותו בחלק העליון של קובץ תצורה יחיד של .tf ב-Terraform (כפי שמתואר במדריך הזה).
כדאי להשתמש באפשרות הזו אם אתם רק מתחילים לעבוד עם Terraform או אם אתם רק רוצים לנסות את Terraform עם Firebase.
אפשרות 2: כוללים אותו בקובץ .tf נפרד (כמו קובץ provider.tf), בנפרד מהקובץ .tf שבו מציינים את התשתית שרוצים ליצור (כמו קובץ main.tf).
כדאי להשתמש באפשרות הזו אם אתם חלק מצוות גדול יותר שצריך לבצע הגדרה סטנדרטית.
כשמריצים פקודות של Terraform, גם הקובץ provider.tf וגם הקובץ main.tf צריכים להיות באותה ספרייה.
מוסיפים את ההגדרה הבאה של provider בחלק העליון של הקובץ main.tf.
צריך להשתמש בספק google-beta כי זוהי גרסה בטא של השימוש ב-Firebase עם Terraform. חשוב להפעיל שיקול דעת כשמשתמשים ב-Cloud Functions בסביבת ייצור.
# 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}
ממשיכים לקטע הבא כדי להשלים את קובץ התצורה ולציין את התשתית שרוצים ליצור.
ציון התשתית שרוצים ליצור באמצעות בלוקים של resource
בקובץ התצורה של Terraform (בקובץ main.tf במדריך הזה), צריך לציין את כל התשתית שרוצים ש-Terraform תיצור (כלומר, את כל המשאבים שרוצים להקצות ואת כל השירותים שרוצים להפעיל). במדריך הזה מופיעה רשימה מלאה של כל משאבי Firebase שתומכים ב-Terraform.
פותחים את קובץ ה-main.tf.
בהגדרה של provider, כוללים את הגדרת הבלוק הבאה של resource.
בדוגמה הבסיסית הזו נוצר פרויקט חדש ב-Firebase, ולאחר מכן נוצרת אפליקציית Firebase ל-Android בתוך הפרויקט הזה.
# 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_overridename="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_overrideproject=google_project.default.project_idfor_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-betaproject=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-betaproject=google_project.default.project_iddisplay_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,]}
גרסה עם הערות רבות של קובץ התצורה לדוגמה
אם אתם לא מכירים את התשתית של פרויקטים ואפליקציות כמשאבים, כדאי לעיין במסמכים הבאים:
# 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 projectprovider=google-beta.no_user_project_overridename="Project Display Name" // learn more about the project nameproject_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 APISprovider=google-beta.no_user_project_overrideproject=google_project.default.project_idfor_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 onprovider=google-betaproject=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-betaproject=google_project.default.project_iddisplay_name="My Awesome Android app" # learn more about an app's display namepackage_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,]}
שלב 2: מריצים פקודות של Terraform כדי ליצור את התשתית שצוינה
כדי להקצות את המשאבים ולהפעיל את השירותים שצוינו בקובץ main.tf, מריצים את הפקודות הבאות מאותה ספרייה שבה נמצא קובץ main.tf.
מידע מפורט על הפקודות האלה זמין במסמכי העזרה של Terraform.
אם זו הפעם הראשונה שאתם מריצים פקודות של Terraform בספרייה, עליכם לאתחל את ספריית התצורה ולהתקין את הספק של Google Terraform. כדי לעשות זאת, מריצים את הפקודה הבאה:
terraform init
יוצרים את התשתית שצוינה בקובץ main.tf על ידי הפעלת הפקודה הבאה:
terraform apply
מוודאים שכל ההקצאות בוצעו או שהכל הופעל כצפוי:
אפשרות 1: כדי להדפיס את ההגדרות במסוף, מריצים את הפקודה הבאה:
למשאבים הבאים של Firebase ו-Google יש תמיכה ב-Terraform. אנחנו מוסיפים כל הזמן מקורות מידע נוספים. לכן, אם המשאב שאתם רוצים לנהל באמצעות Terraform לא מופיע, כדאי לבדוק שוב בקרוב כדי לראות אם הוא זמין, או לשלוח בקשה במאגר GitHub.
google_identity_platform_config — מפעילים את Google Cloud Identity Platform (GCIP) (הקצה העורפי של Firebase Authentication) ומספקים הגדרות אימות ברמת הפרויקט
הפרויקט שבו Terraform תפעיל את GCIP ו/או את Firebase Authentication חייב להיות בתוכנית התמחור Blaze (כלומר, לפרויקט צריך להיות חשבון Cloud Billing משויך). אפשר לעשות זאת באופן פרוגרמטי על ידי הגדרת המאפיין billing_account במשאב google_project.
המשאב הזה מאפשר גם הגדרות נוספות, כמו שיטות כניסה מקומיות, כמו אימות אנונימי, אימות באמצעות אימייל/סיסמה ואימות באמצעות טלפון, וגם פונקציות חסימה ודומיינים מורשים.
ההגדרה הזו יוצרת פרויקט Google Cloud חדש, משייכת את הפרויקט לחשבון Cloud Billing (תוכנית התמחור Blaze נדרשת ל-Firebase Authentication עם GCIP), מפעילה את שירותי Firebase בפרויקט, מגדירה את Firebase Authentication עם GCIP ומרשמת שלושה סוגים שונים של אפליקציות בפרויקט.
חשוב לזכור שצריך להפעיל את GCIP כדי להגדיר את Firebase Authentication דרך Terraform.
# Creates a new Google Cloud project.resource"google_project""auth"{provider=google-beta.no_user_project_overridefolder_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_overrideproject=google_project.auth.project_idfor_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-betaproject=google_project.auth.project_iddepends_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-betaproject=google_project.auth.project_id # Auto-deletes anonymous usersautodelete_anonymous_users=true # Configures local sign-in methods, like anonymous, email/password, and phone authentication.sign_in{allow_duplicate_emails=trueanonymous{enabled=true}email{enabled=truepassword_required=false}phone_number{enabled=truetest_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=trueaccess_token=trueid_token=true}} # Configures a temporary quota for new signups for anonymous, email/password, and phone number.quota{sign_up_quota_config{quota=1000start_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-betaproject=google_project.auth.project_iddisplay_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-betaproject=google_project.auth.project_iddisplay_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-betaproject=google_project.auth.project_iddisplay_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,]}
הקצאת שירות Firebase Data Connect
ההגדרה הזו יוצרת פרויקט Google Cloud חדש, מפעילה את שירותי Firebase בפרויקט ומקצה שירות Data Connect.
# Creates a new Google Cloud project.resource"google_project""dataconnect"{provider=google-beta.no_user_project_overridefolder_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_overrideproject=google_project.dataconnect.project_idfor_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-betaproject=google_project.dataconnect.project_iddepends_on=[google_project_service.services]}# Create a Firebase Data Connect serviceresource"google_firebase_data_connect_service""dataconnect-default"{project=google_firebase_project.dataconnect.projectlocation="name-of-region-for-service"service_id="${google_firebase_project.dataconnect.project}-default-fdc"deletion_policy="DEFAULT"}
הקצאת מכונה Firebase Realtime Database שמוגדרת כברירת מחדל
ההגדרה הזו יוצרת פרויקט Google Cloud חדש, מפעילה את שירותי Firebase בפרויקט, מקצה את מכונה Realtime Database שמוגדרת כברירת מחדל בפרויקט ומרשמת שלושה סוגים שונים של אפליקציות בפרויקט.
# Creates a new Google Cloud project.resource"google_project""rtdb"{provider=google-beta.no_user_project_overridefolder_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_overrideproject=google_project.rtdb.project_idfor_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-betaproject=google_project.rtdb.project_id}# Provisions the default Realtime Database default instance.resource"google_firebase_database_instance""database"{provider=google-betaproject=google_project.rtdb.project_id # See available locations: https://firebase.google.com/docs/database/locationsregion="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-betaproject=google_project.rtdb.project_iddisplay_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-betaproject=google_project.rtdb.project_iddisplay_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-betaproject=google_project.rtdb.project_iddisplay_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,]}
הקצאת מכונות Firebase Realtime Database מרובות
ההגדרה הזו יוצרת פרויקט Google Cloud חדש, משייכת את הפרויקט לחשבון Cloud Billing (תוכנית התמחור Blaze נדרשת לכמה מכונות Realtime Database), מפעילה את שירותי Firebase בפרויקט, מקצה כמה מכונות Realtime Database (כולל מכונה Realtime Database שמוגדרת כברירת מחדל בפרויקט) ומרשמת בפרויקט שלושה סוגים שונים של אפליקציות.
# Creates a new Google Cloud project.resource"google_project""rtdb-multi"{provider=google-beta.no_user_project_overridefolder_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_overrideproject=google_project.rtdb-multi.project_idfor_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-betaproject=google_project.rtdb-multi.project_id}# Provisions the default Realtime Database default instance.resource"google_firebase_database_instance""database-default"{provider=google-betaproject=google_project.rtdb-multi.project_id # See available locations: https://firebase.google.com/docs/database/locationsregion="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-betaproject=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-betaproject=google_project.rtdb-multi.project_iddisplay_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-betaproject=google_project.rtdb-multi.project_iddisplay_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-betaproject=google_project.rtdb-multi.project_iddisplay_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,]}
הקצאת מכונה Cloud Firestore שמוגדרת כברירת מחדל
ההגדרה הזו יוצרת פרויקט Google Cloud חדש, מפעילה את שירותי Firebase בפרויקט, מקצה את מכונה Cloud Firestore שמוגדרת כברירת מחדל בפרויקט ומרשמת שלושה סוגים שונים של אפליקציות בפרויקט.
הוא גם מקצה את Firebase Security Rules למכונה Cloud Firestore שמוגדרת כברירת מחדל, יוצר אינדקס Cloud Firestore ומוסיף מסמך Cloud Firestore עם נתוני זרע.
# Creates a new Google Cloud project.resource"google_project""firestore"{provider=google-beta.no_user_project_overridefolder_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_overrideproject=google_project.firestore.project_idfor_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-betaproject=google_project.firestore.project_id}# Provisions the Firestore database instance.resource"google_firestore_database""firestore"{provider=google-betaproject=google_project.firestore.project_idname="(default)" # See available locations: https://firebase.google.com/docs/firestore/locationslocation_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-betaproject=google_project.firestore.project_idsource{files{name="firestore.rules" # Write security rules in a local file named "firestore.rules". # Learn more: https://firebase.google.com/docs/firestore/security/get-startedcontent=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-betaname="cloud.firestore" # must be cloud.firestoreruleset_name=google_firebaserules_ruleset.firestore.nameproject=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-betaproject=google_project.firestore.project_idcollection="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-betaproject=google_project.firestore.project_idcollection="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-betaproject=google_project.firestore.project_iddisplay_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-betaproject=google_project.firestore.project_iddisplay_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-betaproject=google_project.firestore.project_iddisplay_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,]}
זוהי מערכת הכללים של Cloud Firestore Security Rules, שצריכה להיות בקובץ מקומי בשם firestore.rules.
ההגדרה הזו יוצרת פרויקט Google Cloud חדש, משייכת את הפרויקט לחשבון Cloud Billing (תוכנית התמחור Blaze נדרשת לקטגוריות נוספות), מפעילה את שירותי Firebase בפרויקט, מקצה קטגוריות Cloud Storage נוספות שאינן ברירת המחדל ומרשמת בפרויקט שלושה סוגים שונים של אפליקציות.
הוא גם מקצה Firebase Security Rules לכל קטגוריה Cloud Storage, ומעלה קובץ לאחת מהקטגוריות Cloud Storage.
# Creates a new Google Cloud project.resource"google_project""storage-multi"{provider=google-beta.no_user_project_overridefolder_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_overrideproject=google_project.storage-multi.project_idfor_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-betaproject=google_project.storage-multi.project_id}# Provisions a Cloud Storage bucket.resource"google_storage_bucket""bucket-1"{provider=google-betaproject=google_project.storage-multi.project_idname="name-of-storage-bucket" # See available locations: https://cloud.google.com/storage/docs/locations#available-locationslocation="name-of-region-for-bucket"}# Provisions an additional Cloud Storage bucket.resource"google_storage_bucket""bucket-2"{provider=google-betaproject=google_project.storage-multi.project_idname="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-betaproject=google_project.storage-multi.project_idbucket_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-betaproject=google_project.storage-multi.project_idbucket_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-betaproject=google_project.storage-multi.project_idsource{files{ # Write security rules in a local file named "storage.rules" # Learn more: https://firebase.google.com/docs/storage/security/get-startedname="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-betaname="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-betaname="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-betaname="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-betaproject=google_project.storage-multi.project_iddisplay_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-betaproject=google_project.storage-multi.project_iddisplay_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-betaproject=google_project.storage-multi.project_iddisplay_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,]}
זוהי מערכת הכללים של Cloud Storage Security Rules, שצריכה להיות בקובץ מקומי בשם storage.rules.
ההגדרה הזו יוצרת פרויקט Google Cloud חדש, מפעילה את שירותי Firebase בפרויקט ומגדירה ומפעילה אכיפה של Firebase App Check עבור Cloud Firestore, כך שאפשר לגשת אליו רק מהאפליקציה ל-Android.
# Creates a new Google Cloud project.resource"google_project""appcheck"{provider=google-beta.no_user_project_overridefolder_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_overrideproject=google_project.appcheck.project_idfor_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-betaproject=google_project.appcheck.project_iddepends_on=[google_project_service.services]}# Provisions the Firestore database instance.resource"google_firestore_database""database"{provider=google-betaproject=google_firebase_project.appcheck.projectname="(default)" # See available locations: https://firebase.google.com/docs/projects/locations#default-cloud-locationlocation_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-betaproject=google_firebase_project.appcheck.projectdisplay_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 providerresource"google_firebase_app_check_play_integrity_config""appcheck"{provider=google-betaproject=google_firebase_project.appcheck.projectapp_id=google_firebase_android_app.appcheck.app_iddepends_on=[time_sleep.wait_30s,google_firestore_database.database]lifecycle{precondition{condition=length(google_firebase_android_app.appcheck.sha256_hashes)>0error_message="Provide a SHA-256 certificate on the Android App to use App Check"}}}# Enable enforcement of App Check for Firestoreresource"google_firebase_app_check_service_config""firestore"{provider=google-betaproject=google_firebase_project.appcheck.projectservice_id="firestore.googleapis.com"depends_on=[google_project_service.services]}
התקנה של מכונה של Firebase Extension
ההגדרה הזו יוצרת פרויקט Google Cloud חדש, מפעילה את שירותי Firebase בפרויקט ומתקינה מכונה חדשה של Firebase Extension בפרויקט. אם המכונה כבר קיימת, הפרמטרים שלה מתעדכנים על סמך הערכים שצוינו בתצורה.
# Creates a new Google Cloud project.resource"google_project""extensions"{provider=google-beta.no_user_project_overridefolder_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_overrideproject=google_project.extensions.project_idfor_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-betaproject=google_project.extensions.project_iddepends_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-betaproject=google_project.extensions.project_idinstance_id="translate-text-in-firestore"config{extension_ref="firebase/firestore-translate-text"params={COLLECTION_PATH="posts/comments/translations"DO_BACKFILL=trueLANGUAGES="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"}}}
פתרון בעיות ושאלות נפוצות
אתם רוצים לקבל מידע נוסף על כל המאפיינים השונים שקשורים לפרויקט (כמו project ו-user_project_override)
במדריך הזה נעשה שימוש במאפייני Terraform הבאים כשעובדים עם 'projects'.
project בתוך בלוק resource
מומלץ: ככל האפשר, כדאי לכלול את המאפיין project בכל בלוק resource
אם תכללו מאפיין פרויקט, Terraform תיצור את התשתית שצוינה בבלוק המשאבים בתוך הפרויקט שצוין. המדריך הזה וקובצי התצורה לדוגמה שלנו מבוססים על השיטה הזו.
מידע נוסף זמין במסמכי התיעוד הרשמיים של Terraform בנושא project.
user_project_override בתוך הבלוק provider
כדי להקצות את רוב המשאבים, צריך להשתמש ב-user_project_override = true, כלומר לבדוק את המכסה בפרויקט Firebase שלכם. עם זאת, כדי להגדיר את הפרויקט החדש כך שיוכל לקבל בדיקות מכסות, קודם צריך להשתמש ב-user_project_override = false.
מופיעה השגיאה הבאה:
generic::permission_denied: Firebase Tos Not Accepted.
חשוב לוודא שחשבון המשתמש שבו אתם משתמשים להרצת הפקודות gcloud CLI אישר את התנאים וההגבלות של Firebase (TOS של Firebase).
כדי לבצע את הבדיקה הזו, צריך להיכנס לחשבון המשתמש בדפדפן ולנסות להציג פרויקט Firebase קיים במסוף Firebase. אם אתם יכולים לראות פרויקט קיים ב-Firebase, סימן שחשבון המשתמש אישר את התנאים וההגבלות של Firebase.
אם אתם לא מצליחים לראות פרויקטים קיימים ב-Firebase, סביר להניח שחשבון המשתמש לא אישר את התנאים וההגבלות של Firebase. כדי לפתור את הבעיה, צריך ליצור פרויקט חדש ב-Firebase דרך מסוף Firebase ולאשר את התנאים וההגבלות של Firebase כחלק מתהליך יצירת הפרויקט. אפשר למחוק את הפרויקט הזה באופן מיידי דרך Project Settings במסוף.
אחרי שמריצים את terraform apply, מופיעה השגיאה generic::permission_denied: IAM authority does not have the
permission.
מחכים כמה דקות ומנסים להריץ את terraform apply שוב.
יצירת המשאב נכשלה, אבל כשמריצים שוב את terraform apply מופיעה ההודעה ALREADY_EXISTS.
יכול להיות שהסיבה לכך היא עיכוב בהפצה במערכות שונות. כדי לפתור את הבעיה, אפשר לייבא את המשאב למצב של Terraform באמצעות הפקודה terraform import. לאחר מכן מנסים להריץ שוב את terraform apply.
כשעובדים עם Cloud Firestore, מופיעה השגיאה הבאה: Error creating Index: googleapi:
Error 409;...Concurrent access -- try again
כפי שצוין בשגיאה, יכול להיות ש-Terraform מנסה להקצות כמה אינדקסים ו/או ליצור מסמך בו-זמנית, ונתקלה בשגיאה של בו-זמניות.
נסו להריץ שוב את terraform apply.
מופיעה השגיאה הבאה:
"you may need to specify 'X-Goog-User-Project' HTTP header for quota and
billing purposes".
משמעות השגיאה הזו היא ש-Terraform לא יודע באיזה פרויקט לבדוק את המכסה. כדי לפתור את הבעיה, בודקים את הפרטים הבאים בבלוק resource:
מוודאים שציינתם ערך למאפיין project.
חשוב לוודא שאתם משתמשים בספק עם user_project_override = true
(ללא כתובת אימייל חלופית), שמופיע בדוגמאות של Firebase בתור google-beta.
כשיוצרים פרויקט Google Cloud חדש, מופיעה השגיאה שמזהה הפרויקט שצוין לפרויקט החדש כבר קיים.
אלה הסיבות האפשריות לכך שמזהה הפרויקט כבר קיים:
הפרויקט שמשויך למזהה הזה שייך למישהו אחר.
הפתרון: בוחרים מזהה פרויקט אחר.
הפרויקט שמשויך למזהה הזה נמחק לאחרונה (במצב מחיקה רכה).
הפתרון: אם לדעתכם הפרויקט שמשויך למזהה שייך לכם, עליכם לבדוק את מצב הפרויקט באמצעות projects.get API ל-REST.
הפרויקט שמשויך למזהה הזה קיים כראוי אצל המשתמש הנוכחי. יכול להיות שהסיבה לשגיאה היא שקריאה קודמת של terraform apply הופסקה.
כדי לפתור את הבעיה: מריצים את הפקודות הבאות: terraform import google_project.default PROJECT_ID
ואז terraform import google_firebase_project.default PROJECT_ID
למה צריך להקצות את המכונה Cloud Firestore שמוגדרת כברירת מחדל לפני הקטגוריה Cloud Storage שמוגדרת כברירת מחדל?
אם הקצית את הקטגוריה Cloud Storage שמוגדרת כברירת מחדל (דרך google_app_engine_application) לפני שניסיתם להקצות את המכונה Cloud Firestore שמוגדרת כברירת מחדל, תגלו שהמכונה Cloud Firestore שמוגדרת כברירת מחדל כבר הוקצה. לתשומת ליבכם: מכונה של מסד נתונים שהוקצה נמצאת במצב Datastore, כלומר אין גישה אליה ל-Firebase SDK, לאימות או ל-Firebase Security Rules. אם רוצים להשתמש ב-Cloud Firestore עם שירותי Firebase האלה, צריך לרוקן את מסד הנתונים ואז לשנות את סוג מסד הנתונים במסוף Google Cloud.
כשמנסים להקצות את Cloud Storage (דרך google_app_engine_application) ואז את מכונה Cloud Firestore שמוגדרת כברירת מחדל, מופיעה השגיאה הבאה: Error: Error creating Database: googleapi: Error 409: Database already
exists. Please use another database_id.
כשמקצים את הקטגוריה Cloud Storage שמוגדרת כברירת מחדל לפרויקט (דרך google_app_engine_application) ולפרויקט עדיין אין מכונה Cloud Firestore שמוגדרת כברירת מחדל, המערכת מקצה את המכונה Cloud Firestore שמוגדרת כברירת מחדל לפרויקט באופן אוטומטי באמצעות google_app_engine_application.
מכיוון שמכונה Cloud Firestore שמוגדרת כברירת המחדל בפרויקט כבר הוקצה, תופיע שגיאה ב-google_firestore_database אם תנסו להקצות אותה שוב באופן מפורש.
אחרי שמקצים את המכונה Cloud Firestore שמוגדרת כברירת מחדל בפרויקט, אי אפשר להקצות אותה מחדש או לשנות את המיקום שלה. חשוב לזכור שמכונה של מסד נתונים שהוקצתה נמצאת במצב Datastore, כלומר לא ניתן לגשת אליה באמצעות Firebase SDK, אימות או Firebase Security Rules. אם רוצים להשתמש ב-Cloud Firestore עם שירותי Firebase האלה, צריך לרוקן את מסד הנתונים ואז לשנות את סוג מסד הנתונים במסוף Google Cloud.