1. מבוא
מטרות עסקיות
אתם יכולים להשתמש ב-Terraform כדי להגדיר ולנהל פרויקט Firebase, כולל הגדרה פרוגרמטית של התשתית ומוצרי Firebase.
ב-codelab הזה מוסבר קודם איך ליצור קובץ הגדרות של Terraform כדי ליצור פרויקט Firebase חדש, ואחר כך איך להגדיר את האפליקציות ואת מוצרי Firebase שרוצים להשתמש בהם בפרויקט הזה. אנחנו גם מסבירים על הפקודות הבסיסיות בשורת הפקודה של Terraform, כמו תצוגה מקדימה של השינויים שרוצים לבצע ואז יישום שלהם.
אם רציתם ללמוד איך להגדיר ולנהל פרויקטים ומוצרים של Firebase באמצעות Terraform, ה-codelab הזה הוא בשבילכם.
מה תלמדו
- איך יוצרים קובץ הגדרה של Terraform (
*.tf) - איך משתמשים בפקודות Terraform CLI כדי לנהל את התשתית
 - איך משנים את ההגדרות כדי לעדכן את המשאבים והשירותים
 - איך להחיל את ההגדרה על אפליקציית אינטרנט אמיתית (שנקראת Friendly Chat)
 - איך מגדירים תצורות מקבילות (ובסנכרון) בסביבות שונות (ייצור, Staging וכו')
 
מה צריך להכין
- טרמינל או מסוף
 - סביבת פיתוח משולבת (IDE) או עורך טקסט לפי בחירתכם, כמו WebStorm, Atom, Sublime או VS Code
 - הדפדפן שבחרתם, למשל Chrome
 - Google Cloud CLI (gcloud CLI) – צריך להתקין את ה-CLI הזה ולהתחבר באמצעות חשבון משתמש או חשבון שירות.
 
כדי להצליח ב-Codelab הזה, אתם צריכים ידע בסיסי ב-Terraform ובטרמינולוגיה שלה, כולל הדרישות המוקדמות הבאות:
- מתקינים את Terraform ומתרגלים את השימוש ב-Terraform באמצעות המדריכים הרשמיים שלהם
 
בשיעור הזה מוצגת אפליקציה לדוגמה, כדי שתוכלו לבדוק את מה שאתם מקצים באמצעות Terraform ולבצע פעולות שונות. כדי לעשות את זה, תצטרכו:
- קוד לדוגמה לאפליקציית אינטרנט – אפשר להוריד את הקוד הזה בשלב הבא של ה-codelab
 - מנהל החבילות npm (שבדרך כלל מגיע עם Node.js) – להתקנת הכלים האלה
 -  Firebase CLI – מתקינים את ה-CLI הזה ומתחברים
 
2. קבלת קוד ההתחלה
בשיעור הזה תוכלו לבדוק את מה שהקציתם באמצעות Terraform עם אפליקציית אינטרנט אמיתית. מומלץ לעשות את זה כדי להבין את כל השלבים שנדרשים לשימוש במשאבים שהוקצו באמצעות Terraform.
משכפלים את מאגר הנתונים של GitHub של ה-codelab משורת הפקודה:
git clone https://github.com/firebase/codelab-friendlychat-web
לחלופין, אם לא התקנתם את git, אתם יכולים להוריד את המאגר כקובץ ZIP.
3. יצירת הגדרות אישיות ל-Terraform
הגדרת Terraform
- בבסיס הקוד של האפליקציה לדוגמה שהורדתם, עוברים לשורש של הספרייה 
web. - בתיקיית השורש, יוצרים קובץ תצורה של Terraform בשם 
main.tfעם ההגדרה הראשונית הבאה:
main.tf# Terraform configuration to set up providers by version. terraform { required_providers { google-beta = { source = "hashicorp/google-beta" version = "~> 4.0" } } } # Configure the provider not to use the specified project for quota check. # This provider should only be used during project creation and initializing services. provider "google-beta" { alias = "no_user_project_override" user_project_override = false } # Configure the provider that uses the new project's quota. provider "google-beta" { user_project_override = true } 
לכל אחד מהספקים google-beta יש מאפיין בשם user_project_override שקובע איך יתבצע אימות המכסה של הפעולות מ-Terraform. כדי להקצות את רוב המשאבים, צריך להשתמש ב-user_project_override = true, כלומר לבדוק את המכסה מול פרויקט Firebase שלכם. עם זאת, כדי להגדיר את הפרויקט החדש כך שיוכל לקבל בדיקות מכסה, קודם צריך להשתמש ב-user_project_override=false. התחביר של Terraform alias מאפשר להבחין בין שתי הגדרות הספק בשלבים הבאים של ה-Codelab הזה.
מפעילים את Terraform בספרייה
כשיוצרים הגדרה חדשה בפעם הראשונה, צריך להוריד את הספק שצוין בהגדרה.
כדי לבצע את האתחול הזה, מריצים את הפקודה הבאה מהשורש של אותה ספרייה שבה נמצא קובץ ההגדרות main.tf:
terraform init
4. יצירת פרויקט Firebase באמצעות Terraform
כשיוצרים פרויקט Firebase, חשוב לזכור שכל פרויקט Firebase הוא למעשה פרויקט Google Cloud, רק ששירותי Firebase מופעלים בו.
הוספת חסימות לפרויקט ולממשקי ה-API הבסיסיים ב-Google Cloud
- קודם צריך להקצות את פרויקט Google Cloud הבסיסי.
מוסיפים את בלוק המשאבים הבא לקובץ ההגדרותmain.tf.
צריך לציין שם פרויקט משלכם (למשל"Terraform FriendlyChat Codelab") ומזהה פרויקט משלכם (למשל"terraform-codelab-your-initials"). שימו לב שהערךnameמשמש רק בממשקי Firebase ולא מוצג למשתמשי הקצה. הערךproject_idמזהה את הפרויקט שלכם באופן ייחודי ב-Google, לכן חשוב לציין ערך ייחודי. main.tf... # Create a new Google Cloud project. resource "google_project" "default" { provider = google-beta.no_user_project_override name = "<PROJECT_NAME_OF_YOUR_PROJECT>" project_id = "<PROJECT_ID_OF_YOUR_PROJECT>" # Required for the project to display in any list of Firebase projects. labels = { "firebase" = "enabled" } } - בשלב הבא צריך להפעיל את ממשקי ה-API הבסיסיים הנדרשים: Service Usage API ו-Firebase Management API.
הפעלת ממשקי ה-API האלה מתבצעת בדרך כלל מאחורי הקלעים כשמשתמשים במסוף Firebase כדי ליצור פרויקט Firebase, אבל צריך להגדיר במפורש ל-Terraform לבצע את ההפעלה הזו.
לקובץ ההגדרותmain.tf(מתחת לבלוק שיוצר את פרויקט Cloud החדש), מוסיפים את בלוק המשאבים הבא:
main.tf אם מפעילים את Service Usage API, הפרויקט החדש יוכל לקבל בדיקות מכסה. לכן, לכל הקצאת משאבים והפעלת שירותים בהמשך, צריך להשתמש בספק עם... # Enable the required underlying Service Usage API. resource "google_project_service" "serviceusage" { provider = google-beta.no_user_project_override project = google_project.default.project_id service = "serviceusage.googleapis.com" # Don't disable the service if the resource block is removed by accident. disable_on_destroy = false } # Enable the required underlying Firebase Management API. resource "google_project_service" "firebase" { provider = google-beta.no_user_project_override project = google_project.default.project_id service = "firebase.googleapis.com" # Don't disable the service if the resource block is removed by accident. disable_on_destroy = false }user_project_override(אין צורך בכינוי). 
הוספת בלוק להפעלת שירותי Firebase
הדבר האחרון שנדרש כדי "ליצור פרויקט Firebase" הוא הפעלת שירותי Firebase בפרויקט.
ממשיכים בקובץ התצורה main.tf ומוסיפים את בלוק המשאבים הבא.
כמו שצוין למעלה, בלוק המשאבים הזה משתמש בספק עם user_project_override (לא נדרש כינוי).
main.tf
...
# Enable Firebase services for the new project created above.
resource "google_firebase_project" "default" {
  provider = google-beta
  project = google_project.default.project_id
  # Wait until the required APIs are enabled.
  depends_on = [
    google_project_service.firebase,
    google_project_service.serviceusage,
  ]
}
יכול להיות שתשימו לב לסעיף depends_on בבלוק המשאבים שלמעלה. הסעיף הזה אומר ל-Terraform לחכות עד שממשקי ה-API הבסיסיים יופעלו. בלי הסעיף הזה, Terraform לא יודע על התלות ועשוי להיתקל בשגיאות כשמבצע הקצאת משאבים במקביל.
שימוש בתצורה
- כדי להקצות את המשאבים החדשים ולהפעיל את ממשקי ה-API שצוינו בקובץ התצורה, מריצים את הפקודה הבאה מתיקיית השורש של אותה תיקייה שבה נמצא קובץ 
main.tf(שצריך להיותweb):terraform apply
 - בטרמינל, Terraform מדפיס תוכנית של פעולות שהוא יבצע.
אם הכול נראה כמו שציפיתם, מאשרים את הפעולות על ידי הקלדתyes.
main.tfTerraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # google_firebase_project.default will be created + resource "google_firebase_project" "default" { + display_name = (known after apply) + id = (known after apply) + project = "terraform-friendlychat-codelab" + project_number = (known after apply) } # google_project.default will be created + resource "google_project" "default" { + auto_create_network = true + id = (known after apply) + labels = { + "firebase" = "enabled" } + name = "Terraform FriendlyChat Codelab" + number = (known after apply) + project_id = "terraform-friendlychat-codelab" + skip_delete = (known after apply) } # google_project_service.firebase will be created + resource "google_project_service" "firebase" { + disable_on_destroy = false + id = (known after apply) + project = "terraform-friendlychat-codelab" + service = "firebase.googleapis.com" } # google_project_service.serviceusage will be created + resource "google_project_service" "serviceusage" { + disable_on_destroy = false + id = (known after apply) + project = "terraform-friendlychat-codelab" + service = "serviceusage.googleapis.com" } Plan: 4 to add, 0 to change, 0 to destroy. Do you want to perform these actions? Terraform will perform the actions described above. Only 'yes' will be accepted to approve. Enter a value: yes # <---- 
הערה: אם אתם רוצים רק לראות תצוגה מקדימה של השינויים בלי ליישם אותם, אתם יכולים להשתמש בפקודה terraform plan.
אימות השינויים
אחרי ש-Terraform מסיים את הריצה, אפשר לבדוק את המצב של כל המשאבים והשירותים שהוקצו על ידי Terraform והופעלו על ידי הרצת הפקודה הבאה:
terraform show
דוגמה למה שצריך להופיע בהדפסה. המצב יכיל ערכים ספציפיים לפרויקט שלכם.
# google_firebase_project.default:
resource "google_firebase_project" "default" {
    display_name   = "Terraform FriendlyChat Codelab"
    id             = "projects/terraform-friendlychat-codelab"
    project        = "terraform-friendlychat-codelab"
    project_number = "000000000"
}
# google_project.default:
resource "google_project" "default" {
    auto_create_network = true
    id                  = "projects/terraform-friendlychat-codelab"
    labels              = {
        "firebase" = "enabled"
    }
    name                = "Terraform FriendlyChat Codelab"
    number              = "000000000"
    project_id          = "terraform-friendlychat-codelab"
}
# google_project_service.firebase:
resource "google_project_service" "firebase" {
    disable_on_destroy = false
    id                 = "terraform-friendlychat-codelab/firebase.googleapis.com"
    project            = "terraform-friendlychat-codelab"
    service            = "firebase.googleapis.com"
}
# google_project_service.serviceusage:
resource "google_project_service" "serviceusage" {
    disable_on_destroy = false
    id                 = "terraform-friendlychat-codelab/serviceusage.googleapis.com"
    project            = "terraform-friendlychat-codelab"
    service            = "serviceusage.googleapis.com"
}
אפשר גם לבדוק שהפרויקט נוצר על ידי הצגתו במסוף Firebase.

5. רישום האפליקציה ב-Firebase באמצעות Terraform
כדי להשתמש ב-Firebase, צריך לרשום כל גרסה של האפליקציה לפלטפורמה בפרויקט Firebase. בשיעור הזה תשתמשו באפליקציה אמיתית כדי לבדוק את מה שאתם מקצים באמצעות Terraform ולבצע איתו אינטראקציה. האפליקציה הזו היא אפליקציית אינטרנט, ולכן צריך להגדיר ל-Terraform לרשום אפליקציית אינטרנט של Firebase בפרויקט Firebase החדש שיצרתם.
הוספת בלוק לרישום אפליקציית האינטרנט
כדי לרשום את אפליקציית האינטרנט בפרויקט Firebase, מוסיפים את בלוק המשאבים הבא לקובץ main.tf.
צריך לציין display_name משלכם לאפליקציית האינטרנט. שימו לב שהשם הזה משמש רק בממשקי Firebase ולא גלוי למשתמשי קצה.
main.tf
...
# Create a Firebase Web App in the new project created above.
resource "google_firebase_web_app" "default" {
  provider = google-beta
  project      = google_firebase_project.default.project
  display_name = "<DISPLAY_NAME_OF_YOUR_WEB_APP>"
  deletion_policy = "DELETE"
}
שימוש בתצורה
- כדי להקצות את המשאב החדש, מריצים את הפקודה הבאה מהרמה הבסיסית (root) של אותה ספרייה שבה נמצא הקובץ 
main.tf(שצריך להיותweb). הערה: הפקודה הזו לא יוצרת מחדש פרויקט חדש ב-Google Cloud. מערכת Terraform תזהה שפרויקט עם מזהה הפרויקט שצוין כבר קיים, תשווה את המצב הנוכחי של הפרויקט למה שמופיע בקובץterraform apply
.tfותבצע את השינויים שהיא תמצא. - בודקים את תוכנית הפעולה המודפסת. אם הכול נראה כמו שציפיתם, מקלידים 
yesולוחצים על Enter כדי לאשר את הפעולות. 
אימות השינויים
כדי לבדוק את המצב של המשאב החדש שהוקצה, מריצים את הפקודה הבאה:
terraform show
אפשר גם לבדוק שהאפליקציה נרשמה בהצלחה בפרויקט על ידי הצגתה במסוף Firebase. עוברים אל הגדרות הפרויקט וגוללים למטה אל הקטע האפליקציות שלך.
6. הגדרה של אימות ב-Firebase
אימות הוא חלק חשוב בכל אפליקציה. כדי לאפשר למשתמשי קצה להיכנס לאפליקציית האינטרנט באמצעות חשבונות Google שלהם, אתם יכולים להפעיל את Firebase Authentication ולהגדיר את שיטת הכניסה באמצעות Google.
שימו לב שב-codelab הזה אנחנו מספקים שתי אפשרויות שונות להגדרת אימות ב-Firebase:
- אפשרות 1 (מומלצת): מגדירים את Firebase Authentication במסוף, בלי שנדרש GCIP.
- אם תבחרו באפשרות הזו, לא תצטרכו לשייך את הפרויקט החדש לחשבון לחיוב ב-Cloud.
 
 - אפשרות 2: הגדרת אימות Firebase באמצעות Terraform דרך ממשקי Google Cloud Identity Platform  (GCIP) API.
- אם תבחרו באפשרות הזו, תצטרכו לשייך את הפרויקט החדש לחשבון לחיוב ב-Cloud, כי כדי להשתמש ב-GCIP הפרויקט צריך להיות בתוכנית התמחור Blaze.
 
 
אפשרות 1: הגדרת אימות באמצעות מסוף Firebase
כדי להגדיר אימות ב-Firebase באמצעות מסוף Firebase, לא צריך שהפרויקט יהיה בתוכנית התמחור Blaze.
כך מגדירים אימות ב-Firebase וכניסה באמצעות חשבון Google:
- במסוף Firebase, מאתרים את הקטע Build בחלונית הימנית.
 - לוחצים על אימות, על שנתחיל? ואז על הכרטיסייה שיטת כניסה (או לוחצים כאן כדי לעבור ישירות לשם).
 - לוחצים על הוספת ספק חדש ובקטע ספקים נוספים בוחרים באפשרות Google.
 - מפעילים את המתג הפעלה.
 - מגדירים לאפליקציה שם שגלוי לכולם, למשל 
FriendlyChat(השם לא צריך להיות ייחודי באופן גלובלי). - בוחרים כתובת אימייל לתמיכה בפרויקט מהתפריט הנפתח ולוחצים על שמירה.

 - Google אמורה להופיע כספק כניסה מופעל.

 
אפשרות 2: הגדרת אימות באמצעות Terraform באמצעות ממשקי Google Cloud Identity Platform  (GCIP) API
כדי להגדיר את Firebase Authentication באמצעות Terraform, צריך להשתמש בממשקי GCIP API, כלומר הפרויקט צריך להיות בתוכנית התמחור Blaze. כדי לשדרג את הפרויקט ב-Firebase לתוכנית Blaze, צריך לשייך לחשבון לחיוב ב-Cloud את הפרויקט.
הפעלת החיוב באמצעות Terraform
- אם עדיין אין לכם חשבון לחיוב ב-Cloud, השלב הראשון הוא ליצור חשבון חדש במסוף Google Cloud. במהלך התהליך, חשוב לשים לב למזהה החשבון לחיוב. אפשר למצוא את מזהה החשבון לחיוב בדף החיוב בשדה מזהה החשבון לחיוב שמשויך לפרויקט.

 - כדי להפעיל את החיוב בפרויקט באמצעות Terraform, מוסיפים מאפיין 
billing_accountלמשאבgoogle_projectהקיים בקובץmain.tf:
main.tf... # Create a new Google Cloud project. resource "google_project" "default" { provider = google-beta.no_user_project_override name = "<PROJECT_NAME_OF_YOUR_PROJECT>" project_id = "<PROJECT_ID_OF_YOUR_PROJECT>" billing_account = "<YOUR_BILLING_ACCOUNT_ID>" # Add this line with your Cloud Billing account ID # Required for the project to display in any list of Firebase projects. labels = { "firebase" = "enabled" } } ... 
הפעלת אימות ב-Firebase וכניסה באמצעות חשבון Google דרך Terraform
- כדי להקצות אימות ב-Firebase באמצעות GCIP, מוסיפים לקובץ 
main.tfאת בלוקי המשאבים הבאים:
main.tf... # Enable the Identity Toolkit API. resource "google_project_service" "auth" { provider = google-beta project = google_firebase_project.default.project service = "identitytoolkit.googleapis.com" # Don't disable the service if the resource block is removed by accident. disable_on_destroy = false } # Create an Identity Platform config. # Also, enable Firebase Authentication using Identity Platform (if Authentication isn't yet enabled). resource "google_identity_platform_config" "auth" { provider = google-beta project = google_firebase_project.default.project # For example, you can configure to auto-delete anonymous users. autodelete_anonymous_users = true # Wait for identitytoolkit.googleapis.com to be enabled before initializing Authentication. depends_on = [ google_project_service.auth, ] } - כדי להפעיל כניסה באמצעות חשבון Google, צריך שיהיה לכם לקוח OAuth. כדי לבצע את ההגדרה הזו, נכנסים אל APIs & Services במסוף Google Cloud.
 - זו הפעם הראשונה שאתם יוצרים מספר לקוח לפרויקט הזה, ולכן אתם צריכים להגדיר את מסך ההסכמה ל-OAuth.
- פותחים את הדף 'מסך ההסכמה ל-OAuth' ובוחרים את הפרויקט שיצרתם.
 - מגדירים את סוג המשתמש כחיצוני ולוחצים על יצירה.
 - במסך הבא, ממלאים את הפרטים הבאים ולוחצים על שמירה והמשך.
- מגדירים את שם האפליקציה שגלוי לכולם, למשל 
FriendlyChat(השם לא צריך להיות ייחודי באופן גלובלי). - בוחרים כתובת אימייל לתמיכה במשתמשים מהתפריט הנפתח.
 - מזינים כתובת אימייל בפרטים ליצירת קשר עם המפתח.
 
 - מגדירים את שם האפליקציה שגלוי לכולם, למשל 
 - במסכים הבאים, מבצעים את הפעולות הבאות:
- בדף Scopes (היקפים), מאשרים את אפשרויות ברירת המחדל ולוחצים על Save and Continue (שמירה והמשך).
 - בדף Test users (משתמשי בדיקה), מאשרים את אפשרויות ברירת המחדל ולוחצים על Save and Continue (שמירה והמשך).
 - בודקים את הסיכום ולוחצים על חזרה למרכז הבקרה.
 

 
 - כדי להגדיר לקוח OAuth בדף פרטי הכניסה, מבצעים את הפעולות הבאות:
- לוחצים על Create credentials ובוחרים באפשרות OAuth client ID.
 - בתפריט הנפתח Application type בוחרים באפשרות Web application.
 - בשדה שם, מזינים את שם האפליקציה, לדוגמה 
FriendlyChat(השם לא צריך להיות ייחודי גלובלית). - כדי לאפשר לכתובת ה-URL של האפליקציה להשתמש בלקוח OAuth הזה, צריך להגדיר את הפרטים הבאים:
- בקטע מקורות JavaScript מורשים, לוחצים על הוספת URI ומזינים 
https://<PROJECT_ID>.firebaseapp.com, כאשר<PROJECT_ID>הוא מזהה הפרויקט שהגדרתם ב-main.tf. - בקטע Authorized redirect URIs (כתובות URI מורשות להפניה אוטומטית), לוחצים על Add URI (הוספת כתובת URI) ומזינים 
https://<PROJECT_ID>.firebaseapp.com/__/auth/handler, כאשר<PROJECT_ID>הוא מזהה הפרויקט שהגדרתם ב-main.tf. 
 - בקטע מקורות JavaScript מורשים, לוחצים על הוספת URI ומזינים 
 - לוחצים על שמירה.
 

 - כדי להפעיל כניסה באמצעות חשבון Google באמצעות מזהה הלקוח ב-OAuth והסוד של הלקוח, מוסיפים את הבלוק הבא לקובץ 
main.tf:
main.tf... variable "oauth_client_secret" { type = string description = "OAuth client secret. For this codelab, you can pass in this secret through the environment variable TF_VAR_oauth_client_secret. In a real app, you should use a secret manager service." sensitive = true } resource "google_identity_platform_default_supported_idp_config" "google_sign_in" { provider = google-beta project = google_firebase_project.default.project enabled = true idp_id = "google.com" client_id = "<YOUR_OAUTH_CLIENT_ID>" client_secret = var.oauth_client_secret depends_on = [ google_identity_platform_config.auth ] } 
שימוש בתצורה
- כדי להגדיר אימות בהתאם להגדרות, מריצים את הפקודות הבאות מהרמה הבסיסית (root) של אותה תיקייה שבה נמצא הקובץ 
main.tf(שצריך להיותweb):export TF_VAR_oauth_client_secret="<YOUR_OAUTH_CLIENT_SECRET>"
 חשוב לזכור שהרצת הפקודהterraform apply
terraform applyלא תיצור מחדש פרויקט חדש ב-Google Cloud. מערכת Terraform תזהה שכבר קיים פרויקט עם מזהה הפרויקט שצוין, ותשווה את המצב הנוכחי של הפרויקט למה שמופיע בקובץ.tf. לאחר מכן המערכת תבצע את השינויים שהיא תמצא. - בודקים את תוכנית הפעולה המודפסת. אם הכול נראה כמו שציפיתם, מקלידים 
yesולוחצים על Enter כדי לאשר את הפעולות. 
אימות השינויים
- במסוף Firebase, מאתרים את הקטע Build בחלונית הימנית.
 - לוחצים על אימות ואז על הכרטיסייה שיטת כניסה (או לוחצים כאן כדי לעבור ישירות לשם).
 - Google אמורה להופיע כספק כניסה מופעל.

 
7. הגדרת מסד נתונים ב-Firestore וכללי האבטחה שלו
באפליקציית האינטרנט של ה-codelab הזה, תאחסנו הודעות בין משתמשי קצה במסד נתונים של Firestore.
- כדי להפעיל את ממשקי ה-API הנדרשים ולהקצות את מופע מסד הנתונים, מוסיפים את בלוקי המשאבים הבאים לקובץ 
main.tf:
main.tf... # Enable required APIs for Cloud Firestore. resource "google_project_service" "firestore" { provider = google-beta project = google_firebase_project.default.project for_each = toset([ "firestore.googleapis.com", "firebaserules.googleapis.com", ]) service = each.key # Don't disable the service if the resource block is removed by accident. disable_on_destroy = false } # Provision the Firestore database instance. resource "google_firestore_database" "default" { provider = google-beta project = google_firebase_project.default.project name = "(default)" # See available locations: # https://firebase.google.com/docs/firestore/locations location_id = "<NAME_OF_DESIRED_REGION>" # "FIRESTORE_NATIVE" is required to use Firestore with Firebase SDKs, # authentication, and Firebase Security Rules. type = "FIRESTORE_NATIVE" concurrency_mode = "OPTIMISTIC" depends_on = [ google_project_service.firestore ] } - מחליפים את 
<NAME_OF_DESIRED_REGION>באזור שבו רוצים שהמסד הנתונים יהיה ממוקם.
כשמפתחים אפליקציה לייצור, כדאי שהאזור יהיה קרוב לרוב המשתמשים ומשותף לשירותי Firebase אחרים, כמו Cloud Functions. ב-codelab הזה, אפשר להשתמש במיקוםus-east1(דרום קרוליינה) או באזור הקרוב ביותר למיקום שלכם (ראו מיקומים של Cloud Firestore). - כל מופע של מסד נתונים של Firestore שאפשר לגשת אליו מ-Firebase צריך להיות מוגן על ידי כללי אבטחה של Firebase.
קוד הדוגמה של ה-codelab הזה מספק קבוצה של כללי אבטחה של Firestore בקובץfirestore.rules, שאפשר למצוא בשורש של ספרייתweb. - מוסיפים לקובץ 
main.tfאת בלוקי המשאבים הבאים כדי לבצע את הפעולות הבאות:- יוצרים קבוצת כללים של כללי אבטחה של Firebase מקובץ 
firestore.rulesהמקומי. - משחררים את קבוצת הכללים עבור מופע Firestore.
 
firebase deploy --only firestore:rules.
main.tf... # Create a ruleset of Firestore Security Rules from a local file. resource "google_firebaserules_ruleset" "firestore" { provider = google-beta project = google_firebase_project.default.project source { files { name = "firestore.rules" # Write security rules in a local file named "firestore.rules". # Learn more: https://firebase.google.com/docs/firestore/security/get-started content = file("firestore.rules") } } # Wait for Firestore to be provisioned before creating this ruleset. depends_on = [ google_firestore_database.default, ] } # Release the ruleset for the Firestore instance. resource "google_firebaserules_release" "firestore" { provider = google-beta name = "cloud.firestore" # must be cloud.firestore ruleset_name = google_firebaserules_ruleset.firestore.name project = google_firebase_project.default.project # Wait for Firestore to be provisioned before releasing the ruleset. depends_on = [ google_firestore_database.default, ] lifecycle { replace_triggered_by = [ google_firebaserules_ruleset.firestore ] } } - יוצרים קבוצת כללים של כללי אבטחה של Firebase מקובץ 
 - מריצים את 
terraform applyכדי להקצות את מסד הנתונים של Firestore ולפרוס את כללי האבטחה שלו. - מוודאים שמסד הנתונים הוקצה ושכללי האבטחה שלו נפרסו:
- במסוף Firebase, מאתרים את הקטע Build בחלונית הימנית.
 - עוברים לקטע Firestore Database ולוחצים על הכרטיסייה Rules (כללים).
 

 
8. הגדרת קטגוריה של Cloud Storage וכללי האבטחה שלה
באפליקציית האינטרנט של ה-codelab הזה, תאחסנו תמונות שמשותפות בין משתמשי קצה בקטגוריה של Cloud Storage.
- כדי להפעיל את ממשקי ה-API הנדרשים ולהקצות את קטגוריית ברירת המחדל של Cloud Storage, מוסיפים את בלוקי המשאבים הבאים לקובץ 
main.tf.
שימו לב: קטגוריית ברירת המחדל של Cloud Storage לפרויקט מוקצית דרך Google App Engine, והיא חייבת להיות באותו מיקום כמו מסד הנתונים של Firestore. מידע נוסף זמין במאמר מיקומי App Engine.
אם רוצים כמה דליים בפרויקט, צריך להקצות אותם באמצעות משאבgoogle_storage_bucket(לא מוצג ב-codelab הזה).
main.tf... # Enable required APIs for Cloud Storage for Firebase. resource "google_project_service" "storage" { provider = google-beta project = google_firebase_project.default.project for_each = toset([ "firebasestorage.googleapis.com", "storage.googleapis.com", ]) service = each.key # Don't disable the service if the resource block is removed by accident. disable_on_destroy = false } # Provision the default Cloud Storage bucket for the project via Google App Engine. resource "google_app_engine_application" "default" { provider = google-beta project = google_firebase_project.default.project # See available locations: https://firebase.google.com/docs/projects/locations#default-cloud-location # This will set the location for the default Storage bucket and the App Engine App. location_id = "<NAME_OF_DESIRED_REGION_FOR_DEFAULT_BUCKET>" # Must be in the same location as Firestore (above) # Wait until Firestore is provisioned first. depends_on = [ google_firestore_database.default ] } # Make the default Storage bucket accessible for Firebase SDKs, authentication, and Firebase Security Rules. resource "google_firebase_storage_bucket" "default-bucket" { provider = google-beta project = google_firebase_project.default.project bucket_id = google_app_engine_application.default.default_bucket } - כל מאגר Cloud Storage שאפשר לגשת אליו מ-Firebase צריך להיות מוגן על ידי כללי אבטחה של Firebase.
דוגמת הקוד של ה-Codelab הזה מספקת קבוצה של כללי Firestore מאובטחים בקובץstorage.rules, שאפשר למצוא אותו בספריית הבסיס שלweb. - מוסיפים לקובץ 
main.tfאת בלוקי המשאבים הבאים כדי לבצע את הפעולות הבאות:- יוצרים קבוצת כללים של כללי אבטחה של Firebase מהקובץ המקומי.
 - משחררים את קבוצת הכללים לקטגוריית האחסון.
 
firebase deploy --only storage.
main.tf... # Create a ruleset of Cloud Storage Security Rules from a local file. resource "google_firebaserules_ruleset" "storage" { provider = google-beta project = google_firebase_project.default.project source { files { # Write security rules in a local file named "storage.rules". # Learn more: https://firebase.google.com/docs/storage/security/get-started name = "storage.rules" content = file("storage.rules") } } # Wait for the default Storage bucket to be provisioned before creating this ruleset. depends_on = [ google_firebase_storage_bucket.default-bucket, ] } # Release the ruleset to the default Storage bucket. resource "google_firebaserules_release" "default-bucket" { provider = google-beta name = "firebase.storage/${google_app_engine_application.default.default_bucket}" ruleset_name = "projects/${google_firebase_project.default.project}/rulesets/${google_firebaserules_ruleset.storage.name}" project = google_firebase_project.default.project lifecycle { replace_triggered_by = [ google_firebaserules_ruleset.storage ] } } - מריצים את הפקודה 
terraform applyכדי להקצות את קטגוריית ברירת המחדל של Cloud Storage ולפרוס את כללי האבטחה שלה. - מוודאים שה-bucket הוקצה וכללי האבטחה שלו נפרסו:
- במסוף Firebase, מאתרים את הקטע Build בחלונית הימנית.
 - עוברים לקטע אחסון ולוחצים על הכרטיסייה כללים.
 

 
9. הפעלת האפליקציה באופן מקומי
עכשיו אפשר להפעיל את אפליקציית האינטרנט בפעם הראשונה. תשתמשו באמולטור של Firebase Hosting כדי להפעיל את האפליקציה באופן מקומי.
- פותחים חלון טרמינל חדש ומריצים את פקודת Firebase CLI הבאה מהספרייה 
webכדי להפעיל את האמולטור:firebase emulators:start --project=<PROJECT_ID>
 - בדפדפן, פותחים את אפליקציית האינטרנט בכתובת ה-URL המקומית שמוחזרת על ידי ה-CLI (בדרך כלל 
http://localhost:5000). 
אמור להופיע ממשק המשתמש של אפליקציית FriendlyChat, שלא פועל (עדיין!). האפליקציה עדיין לא מקושרת ל-Firebase, אבל אם תבצעו את השלבים הבאים ב-codelab הזה, היא תקושר!
שימו לב: בכל פעם שתבצעו שינויים באפליקציית האינטרנט (כמו שתעשו בשלבים הבאים של ה-codelab הזה), תצטרכו לרענן את הדפדפן כדי לעדכן את כתובת ה-URL המקומית עם השינויים האלה.
10. התקנה, הגדרה והפעלה של Firebase
כדי שאפליקציה תפעל עם Firebase, צריך להוסיף לה את Firebase SDK ואת ההגדרה של Firebase לפרויקט Firebase.
קוד הדוגמה של ה-codelab הזה הוא כבר אפליקציה פעילה עם כל התלויות והפונקציות הנדרשות לשימוש במוצרי Firebase שונים באפליקציה. אפשר לעיין ב-web/package.json וב-web/src/index.js כדי לראות מה כבר נעשה.
למרות שקוד הדוגמה כמעט מלא, עדיין צריך לבצע כמה פעולות כדי שהאפליקציה תפעל, כולל: התקנת Firebase SDK, הפעלת הבנייה, הוספת הגדרות Firebase לאפליקציה ואתחול Firebase.
התקנה של Firebase SDK והתחלה של בניית webpack
כדי להתחיל את בניית האפליקציה, צריך להריץ כמה פקודות.
- פותחים חלון טרמינל חדש.
 - מוודאים שאתם נמצאים בספריית השורש של 
web. - מריצים את הפקודה 
npm installכדי להוריד את Firebase SDK. - מריצים את הפקודה 
npm updateכדי לעדכן את כל התלויות. - מריצים את הפקודה 
npm run startכדי להפעיל את webpack. 
מעכשיו, webpack יבנה מחדש את קוד המקור באופן רציף למשך שאר ה-codelab.
הוספת התצורה של Firebase לאפליקציה
צריך גם להוסיף את ההגדרה של Firebase לאפליקציה כדי שערכות ה-SDK של Firebase ידעו באיזה פרויקט Firebase אתם רוצים להשתמש.
יש שתי אפשרויות שונות לקבלת הגדרת Firebase עבור ה-codelab הזה:
- אפשרות 1: מקבלים את התצורה של Firebase ממסוף Firebase.
 - אפשרות 2: קבלת הגדרות Firebase באמצעות Terraform.
 
אפשרות 1: מקבלים את התצורה ממסוף Firebase ומוסיפים אותה לבסיס הקוד
- במסוף Firebase, עוברים אל Project settings (הגדרות הפרויקט).
 - גוללים למטה אל הכרטיס האפליקציות שלך ובוחרים את אפליקציית האינטרנט.
 - בוחרים באפשרות Config (הגדרה) בחלונית של קטע הקוד של Firebase SDK, ואז מעתיקים את קטע ההגדרה.
 - מדביקים את ההגדרה בקובץ 
web/src/firebase-config.jsשל האפליקציה, כך:
firebase-config.js... const config = { apiKey: "<API_KEY>", authDomain: "<PROJECT_ID>.firebaseapp.com", projectId: "<PROJECT_ID>", storageBucket: "<PROJECT_ID>.appspot.com", messagingSenderId: "<SENDER_ID>", appId: "<APP_ID>", measurementId: "<G-MEASUREMENT_ID>", }; ... 
אפשרות 2: מקבלים את התצורה דרך Terraform ומוסיפים אותה לבסיס הקוד
לחלופין, אפשר לקבל את ההגדרה של Firebase דרך Terraform כערך פלט בממשק ה-CLI.
- בקובץ 
main.tf, מחפשים את בלוק המשאביםgoogle_firebase_web_app(הבלוק שרשם אפליקציית אינטרנט בפרויקט). - מיד אחרי הבלוק הזה, מוסיפים את הבלוקים הבאים:
main.tf... data "google_firebase_web_app_config" "default" { provider = google-beta project = google_firebase_project.default.project web_app_id = google_firebase_web_app.default.app_id } output "friendlychat_web_app_config" { value = { projectId = google_firebase_project.default.project appId = google_firebase_web_app.default.app_id apiKey = data.google_firebase_web_app_config.default.api_key authDomain = data.google_firebase_web_app_config.default.auth_domain storageBucket = lookup(data.google_firebase_web_app_config.default, "storage_bucket", "") messagingSenderId = lookup(data.google_firebase_web_app_config.default, "messaging_sender_id", "") measurementId = lookup(data.google_firebase_web_app_config.default, "measurement_id", "") } } ... - הבלוקים 
dataו-outputלא מיועדים לשינוי התשתית בשום צורה, ולכן צריך להריץ רק את הפקודות הבאות.- כדי לטעון את ההגדרות של Firebase של אפליקציית האינטרנט למצב Terraform של הספרייה, מריצים את הפקודה הבאה:
terraform refresh
 - כדי להדפיס את ערכי ההגדרה של Firebase, מריצים את הפקודה הבאה:
 הדוגמה הבאה היא של פלט של הגדרה. הפלט המודפס יכיל את הערכים של הפרויקט והאפליקציה.terraform output –json
{ "friendlychat_web_app_config": { "sensitive": false, "type": [ "object", { "apiKey": "string", "appId": "string", "authDomain": "string", "measurementId": "string", "messagingSenderId": "string", "projectId": "string", "storageBucket": "string" } ], "value": { "apiKey": "<API_KEY>", "appId": "<APP_ID>", "authDomain": "<PROJECT_ID>.firebaseapp.com", "measurementId": "<G-MEASUREMENT_ID>", "messagingSenderId": "<SENDER_ID>", "projectId": "<PROJECT_ID>", "storageBucket": "<PROJECT_ID>.appspot.com" } } } 
 - כדי לטעון את ההגדרות של Firebase של אפליקציית האינטרנט למצב Terraform של הספרייה, מריצים את הפקודה הבאה:
 - מעתיקים את הערכים מתוך המפה 
value. - מדביקים את הערכים האלה (ההגדרות) בקובץ 
web/src/firebase-config.jsשל האפליקציה, כך:
firebase-config.js... const config = { apiKey: "<API_KEY>", appId: "<APP_ID>", authDomain: "<PROJECT_ID>.firebaseapp.com", measurementId: "<G-MEASUREMENT_ID>", messagingSenderId: "<SENDER_ID>", projectId: "<PROJECT_ID>", storageBucket: "<PROJECT_ID>.appspot.com", }; ... 
הפעלת Firebase באפליקציה
לבסוף, כדי לאתחל את Firebase, מוסיפים את השורות הבאות לקובץ web/src/index.js של האפליקציה:
...
const firebaseAppConfig = getFirebaseConfig();
initializeApp(firebaseAppConfig);
ניסיון השימוש באפליקציה
אחרי שסיימתם להגדיר הכול ל-Firebase, אתם יכולים לנסות את אפליקציית האינטרנט הפונקציונלית שלכם.
- מרעננים את הדפדפן שבו האפליקציה פועלת.
 - עכשיו אמורה להיות לכם אפשרות להיכנס באמצעות Google ולהתחיל לפרסם הודעות בצ'אט. אם יש לכם קבצים של תמונות, אתם יכולים גם להעלות אותם.
 
11. שכפול ההגדרה בסביבות שונות
Terraform מצטיין בניהול של תשתית מרובה עם הגדרות דומות (לדוגמה, הגדרת פרויקט Staging ב-Firebase שדומה לפרויקט Prod).
ב-codelab הזה תיצרו פרויקט שני ב-Firebase שיהיה סביבת Staging.
כדי לשכפל הגדרה קיימת וליצור את פרויקט ההכנה, יש שתי אפשרויות:
- אפשרות 1: יוצרים עותק של הגדרת Terraform.
האפשרות הזו מציעה את הגמישות הגבוהה ביותר לגבי מידת השוני בין הפרויקט המשוכפל לבין פרויקט המקור. - אפשרות 2: שימוש חוזר בהגדרות באמצעות 
for_each.
האפשרות הזו מאפשרת שימוש חוזר בקוד אם לא אמורים להיות הבדלים משמעותיים בין הפרויקטים, ואם רוצים להפיץ שינויים לכל הפרויקטים בבת אחת. 
אפשרות 1: יצירת עותק של הגדרות Terraform
האפשרות הזו מציעה את הגמישות הגבוהה ביותר לגבי מידת השוני בין הפרויקט המשוכפל לבין פרויקט המקור. לדוגמה, אפשר להשתמש באפליקציות עם שמות תצוגה שונים ובפריסות מדורגות.
- בשורש של הספרייה 
web, יוצרים קובץ תצורה חדש של Terraform בשםmain_staging.tf. - מעתיקים את כל בלוקי המשאבים מקובץ 
main.tf(חוץ מהבלוקיםterraformו-provider), ואז מדביקים אותם בקובץmain_staging.tf. - לאחר מכן צריך לשנות כל אחד מבלוקי המשאבים המשוכפלים ב-
main_staging.tfכדי שהם יפעלו עם פרויקט ההכנה:- תוויות משאבים: צריך להשתמש בשם חדש כדי למנוע התנגשות. לדוגמה, משנים את השם של 
resource "google_project" "default"ל-resource "google_project" "staging". - הפניות למשאבים: צריך לעדכן כל אחת מהן. לדוגמה, מעדכנים את 
google_firebase_project.default.projectל-google_firebase_project.staging.project. 
main_staging.tfבמאגר GitHub של ה-codelab הזה:web/terraform-checkpoints/replicate-config/main_staging-copypaste.tf
אם רוצים להשתמש בהגדרה הזו, צריך לוודא שמבצעים את הפעולות הבאות:- מעתיקים את ההגדרות מ-
main_staging-copypaste.tfומדביקים אותן בקובץmain_staging.tf. - בקובץ 
main_staging.tf, מבצעים את הפעולות הבאות:- בבלוק המשאבים 
google_project, מעדכנים את המאפייןname, את המאפייןproject-idואת המאפייןbilling_account(אם הגדרתם אימות באמצעות Terraform) עם הערכים שלכם. - בבלוק המשאבים 
google_firebase_web_app, מעדכנים את המאפייןdisplay_nameעם הערך שלכם. - בבלוקי המשאבים 
google_firestore_databaseו-google_app_engine_application, מעדכנים את מאפייניlocation_idעם הערך שלכם. 
 - בבלוק המשאבים 
 
# Create a new Google Cloud project. resource "google_project" "staging" { provider = google-beta.no_user_project_override name = "<PROJECT_NAME_OF_STAGING_PROJECT>" project_id = "<PROJECT_ID_OF_STAGING_PROJECT" # Required if you want to set up Authentication via Terraform billing_account = "<YOUR_BILLING_ACCOUNT_ID>" # Required for the project to display in any list of Firebase projects. labels = { "firebase" = "enabled" } } # Enable the required underlying Service Usage API. resource "google_project_service" "staging_serviceusage" { provider = google-beta.no_user_project_override project = google_project.staging.project_id service = "serviceusage.googleapis.com" # Don't disable the service if the resource block is removed by accident. disable_on_destroy = false } # Enable the required underlying Firebase Management API. resource "google_project_service" "staging_firebase" { provider = google-beta.no_user_project_override project = google_project.staging.project_id service = "firebase.googleapis.com" # Don't disable the service if the resource block is removed by accident. disable_on_destroy = false } # Enable Firebase services for the new project created above. resource "google_firebase_project" "staging" { provider = google-beta project = google_project.staging.project_id # Wait until the required APIs are enabled. depends_on = [ google_project_service.staging_serviceusage, google_project_service.staging_firebase, ] } # Create a Firebase Web App in the new project created above. resource "google_firebase_web_app" "staging" { provider = google-beta project = google_firebase_project.staging.project display_name = "<DISPLAY_NAME_OF_YOUR_WEB_APP>" deletion_policy = "DELETE" } - תוויות משאבים: צריך להשתמש בשם חדש כדי למנוע התנגשות. לדוגמה, משנים את השם של 
 - מריצים את הפקודה 
terraform applyכדי להקצות את פרויקט Firebase החדש 'staging' ואת כל המשאבים שלו, ולהפעיל את השירותים שלו. - כדי לוודא שהקצאת ההרשאות וההפעלה בוצעו כצפוי, בודקים אותן במסוף Firebase כמו קודם.
 
אפשרות 2: שימוש חוזר בהגדרות באמצעות for_each
האפשרות הזו מאפשרת שימוש חוזר בקוד, אם לא אמורים להיות הבדלים משמעותיים בין הפרויקטים ואתם רוצים להפיץ את השינויים לכל הפרויקטים בבת אחת. הוא משתמש במטא-ארגומנט for_each בשפת Terraform.
- פותחים את קובץ ה-
main.tf. - לכל בלוק משאבים שרוצים לשכפל, מוסיפים מטא-ארגומנט 
for_each, כך:
main.tf במאגר GitHub של ה-codelab הזה אפשר למצוא את ההגדרה המלאה של קובץ# Create new Google Cloud projects. resource "google_project" "default" { provider = google-beta.no_user_project_override name = each.value # Create a unique project ID for each project, with each ID starting with <PROJECT_ID>. project_id = "<PROJECT_ID>-${each.key}" # Required if you want to set up Authentication via Terraform billing_account = "<YOUR_BILLING_ACCOUNT_ID>" # Required for the projects to display in any list of Firebase projects. labels = { "firebase" = "enabled" } for_each = { prod = "<PROJECT_NAME_OF_PROD_PROJECT>" staging = "<PROJECT_NAME_OF_STAGING_PROJECT>" } } # Enable the required underlying Service Usage API. resource "google_project_service" "serviceusage" { provider = google-beta.no_user_project_override for_each = google_project.default project = each.value.project_id service = "serviceusage.googleapis.com" # Don't disable the service if the resource block is removed by accident. disable_on_destroy = false } # Enable the required underlying Firebase Management API. resource "google_project_service" "firebase" { provider = google-beta.no_user_project_override for_each = google_project.default project = each.value.project_id service = "firebase.googleapis.com" # Don't disable the service if the resource block is removed by accident. disable_on_destroy = false } # Enable Firebase services for each of the new projects created above. resource "google_firebase_project" "default" { provider = google-beta for_each = google_project.default project = each.value.project_id depends_on = [ google_project_service.serviceusage, google_project_service.firebase, ] } # Create a Firebase Web App in each of the new projects created above. resource "google_firebase_web_app" "default" { provider = google-beta for_each = google_firebase_project.default project = each.value.project # The Firebase Web App created in each project will have the same display name. display_name = "<DISPLAY_NAME_OF_YOUR_WEB_APP>" deletion_policy = "DELETE" } # NOTE: For this codelab, we recommend setting up Firebase Authentication # using the Firebase console. However, if you set up Firebase Authentication # using Terraform, copy-paste from your main.tf the applicable blocks. # Make sure to add the `for_each` meta-argument into each block. # Copy-paste from your main.tf file the applicable resource blocks # for setting up Cloud Firestore (including rules) and # for setting up Cloud Storage for Firebase (including rules). # Make sure to add the `for_each` meta-argument into each block.main.tfשמשתמש בארגומנט המטאfor_each:web/terraform-checkpoints/replicate-config/main-foreach.tf
אם רוצים להשתמש בהגדרה הזו, צריך לבצע את הפעולות הבאות:- מעתיקים את ההגדרות מ-
main-foreach.tfומדביקים אותן בקובץmain.tf. - בקובץ 
main.tf, מבצעים את הפעולות הבאות:- בבלוק המשאבים 
google_project, מעדכנים את המאפייןname, את המאפייןproject-idואת המאפייןbilling_account(אם הגדרתם אימות באמצעות Terraform) עם הערכים שלכם. - בבלוק המשאבים 
google_firebase_web_app, מעדכנים את המאפייןdisplay_nameעם הערך שלכם. - בבלוקי המשאבים 
google_firestore_databaseו-google_app_engine_application, מעדכנים את מאפייניlocation_idעם הערך שלכם. 
 - בבלוק המשאבים 
 
 - מעתיקים את ההגדרות מ-
 - במקום להחיל את ההגדרה הזו באופן מיידי, חשוב להבין ולתקן כמה דברים לגבי האופן שבו Terraform מפרש את ההגדרה הזו בהשוואה לתשתית הקיימת.
- אם תפעילו עכשיו את ההגדרה הזו שמשתמשת ב-
for_each, כתובות המשאבים ייראו כך: עם זאת, הפרויקט הקיים שיצרתם בחלק הראשון של ה-codelab הזה מוכר ל-Terraform בתור:google_project.default["prod"] google_project.default["staging"] google_firebase_project.default["prod"] google_firebase_project.default["staging"] google_firebase_web_app.default["prod"] google_firebase_web_app.default["staging"]google_project.default google_firebase_project.default google_firebase_android_app.default - מריצים את הפקודה 
terraform planכדי לראות אילו פעולות Terraform יבצע בהינתן המצב הנוכחי.
הפלט צריך להראות ש-Terraform ימחק את הפרויקט שיצרתם בחלק הראשון של ה-Codelab הזה וייצור שני פרויקטים חדשים. הסיבה לכך היא ש-Terraform לא יודע שהפרויקט בכתובתgoogle_project.defaultהועבר לכתובת החדשהgoogle_project.default["prod"]. - כדי לפתור את הבעיה, מריצים את הפקודה 
terraform state mv:terraform state mv "google_project.default" "google_project.default[\"prod\"]"
 - באופן דומה, כדי לתקן את כל בלוקי המשאבים האחרים, מריצים את הפקודה 
terraform state mvעבורgoogle_firebase_project,google_firebase_web_appוכל בלוקי המשאבים האחרים בקובץmain.tf. - עכשיו, אם מריצים שוב את הפקודה 
terraform plan, לא אמורה להופיע הודעה של Terraform על מחיקת הפרויקט שיצרתם בחלק הראשון של ה-Codelab הזה. 
 - אם תפעילו עכשיו את ההגדרה הזו שמשתמשת ב-
 - מריצים את הפקודה 
terraform applyכדי להקצות את פרויקט Firebase החדש 'staging' ואת כל המשאבים שלו, ולהפעיל את השירותים שלו. - כדי לוודא שהקצאת ההרשאות וההפעלה בוצעו כצפוי, בודקים אותן במסוף Firebase כמו קודם.
 
12. שלב בונוס: פריסת אפליקציות בסביבת פיתוח ובסביבת ייצור
- בבסיס הקוד של האפליקציה, משנים את 
firebase-config.jsכך שישתמש בהגדרות של Firebase מפרויקט ההכנה במקום זאת.
כדי להיזכר איך מקבלים את ההגדרות של Firebase ומוסיפים אותן לאפליקציה, אפשר לעיין בשלב הקודם של ה-codelab הזה, הוספת ההגדרות של Firebase לאפליקציה. - בשורש של ספריית 
web, מריצים את הפקודה הבאה כדי לפרוס את האפליקציה לפרויקט Firebase של שלב ההכנה.firebase deploy --only hosting --project=<STAGING_PROJECT_ID>
 - פותחים את אפליקציית הסביבה הזמנית בדפדפן באמצעות כתובת ה-URL שמופיעה בפלט של 
firebase deploy. נסו להיכנס, לשלוח הודעות ולהעלות תמונות.
כשפורסים אפליקציה בפרויקט Firebase, היא משתמשת במשאבים אמיתיים של Firebase, ולא במשאבים מדומיים. במהלך האינטראקציה עם אפליקציית הסביבה שלכם, אמורים להופיע נתונים ותמונות בפרויקט הסביבה במסוף Firebase. - אחרי שבודקים את האפליקציה בסביבת הפיתוח, משנים את 
firebase-config.jsבחזרה לשימוש בהגדרות Firebase של פרויקט הייצור (הפרויקט הראשון שיצרתם ב-codelab הזה). - בספריית 
web, מריצים את הפקודה הבאה כדי לפרוס את האפליקציה לפרויקט Firebase בסביבת הייצור.firebase deploy --only hosting --project=<PRODUCTION_PROJECT_ID>
 - פותחים את אפליקציית ההפקה בדפדפן באמצעות כתובת ה-URL שמופיעה בפלט של 
firebase deploy. נסו להיכנס, לשלוח הודעות ולהעלות תמונות.
אחרי שתעשו את זה, תוכלו לראות את הנתונים והתמונות בפרויקט הפרודקשן במסוף Firebase. - אחרי שתסיימו את האינטראקציה עם שתי האפליקציות ב-codelab הזה, תוכלו להפסיק את ההצגה שלהן ב-Firebase. מריצים את הפקודה הבאה לכל אחד מהפרויקטים:
firebase hosting:disable --project=<STAGING_PROJECT_ID>
firebase hosting:disable --project=<PRODUCTION_PROJECT_ID>
 
13. כל הכבוד!
השתמשתם ב-Terraform כדי להגדיר אפליקציית אינטרנט של צ'אט בזמן אמת. בנוסף, פעלתם לפי השיטות המומלצות לסביבות פיתוח ויצרתם פרויקטים נפרדים ב-Firebase ל-Staging ולייצור.
מה נכלל
- שימוש ב-Terraform CLI לניהול משאבי ענן
 - שימוש ב-Terraform כדי להגדיר מוצרים של Firebase (אימות, Firestore, Cloud Storage וכללי אבטחה)
 - הפעלה ובדיקה של אפליקציית אינטרנט באופן מקומי באמצעות Firebase Local Emulator Suite
 - ייבוא של Firebase לאפליקציית אינטרנט
 - שימוש ב-Terraform כדי לשכפל הגדרה בכמה סביבות
 
מידע נוסף על Firebase ו-Terraform זמין במסמכי העזרה שלנו. תוכלו למצוא רשימה של כל מוצרי Firebase עם תמיכה ב-Terraform, דוגמאות להגדרות Terraform לתרחישי שימוש נפוצים, ופתרון בעיות ושאלות נפוצות שיעזרו לכם.