הגדרה וניהול של פרויקטים ומוצרים ב-Firebase באמצעות Terraform

1. מבוא

מטרות עסקיות

אתם יכולים להשתמש ב-Terraform כדי להגדיר ולנהל פרויקט Firebase, כולל הגדרה פרוגרמטית של התשתית ומוצרי Firebase.

ב-codelab הזה מוסבר קודם איך ליצור קובץ הגדרות של Terraform כדי ליצור פרויקט Firebase חדש, ואחר כך איך להגדיר את האפליקציות ואת מוצרי Firebase שרוצים להשתמש בהם בפרויקט הזה. אנחנו גם מסבירים על הפקודות הבסיסיות בשורת הפקודה של Terraform, כמו תצוגה מקדימה של השינויים שרוצים לבצע ואז יישום שלהם.

אם רציתם ללמוד איך להגדיר ולנהל פרויקטים ומוצרים של Firebase באמצעות Terraform, ה-codelab הזה הוא בשבילכם.

מה תלמדו

  • איך יוצרים קובץ הגדרה של Terraform (*.tf)
  • איך משתמשים בפקודות Terraform CLI כדי לנהל את התשתית
  • איך משנים את ההגדרות כדי לעדכן את המשאבים והשירותים
  • איך להחיל את ההגדרה על אפליקציית אינטרנט אמיתית (שנקראת Friendly Chat)
  • איך מגדירים תצורות מקבילות (ובסנכרון) בסביבות שונות (ייצור, Staging וכו')

מה צריך להכין

כדי להצליח ב-Codelab הזה, אתם צריכים ידע בסיסי ב-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

  1. בבסיס הקוד של האפליקציה לדוגמה שהורדתם, עוברים אל השורש של הספרייה web.
  2. בתיקיית השורש, יוצרים קובץ תצורה של 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

  1. קודם צריך להקצות את פרויקט 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"
      }
    }
    
  2. בשלב הבא צריך להפעיל את ממשקי ה-API הבסיסיים הנדרשים: Service Usage API ו-Firebase Management API.

    הפעלת ממשקי ה-API האלה מתבצעת בדרך כלל מאחורי הקלעים כשמשתמשים במסוף Firebase כדי ליצור פרויקט Firebase, אבל צריך להגדיר במפורש ל-Terraform לבצע את ההפעלה הזו.

    לקובץ ההגדרות main.tf (מתחת לבלוק שיוצר את פרויקט Cloud החדש), מוסיפים את בלוק המשאבים הבא:

    main.tf
    ...
    
    # Enable the required underlying Service Usage API.
    resource "google_project_service" "serviceusage" {
      provider = google-beta.no_user_project_override
    
      project = google_project.default.project_id
      service = "serviceusage.googleapis.com"
    
      # Don't disable the service if the resource block is removed by accident.
      disable_on_destroy = false
    }
    
    # Enable the required underlying Firebase Management API.
    resource "google_project_service" "firebase" {
      provider = google-beta.no_user_project_override
    
      project = google_project.default.project_id
      service = "firebase.googleapis.com"
    
      # Don't disable the service if the resource block is removed by accident.
      disable_on_destroy = false
    }
    
    אם מפעילים את Service Usage API, הפרויקט החדש יוכל לקבל בדיקות מכסה. לכן, לכל הקצאת משאבים והפעלת שירותים בהמשך, צריך להשתמש בספק עם 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 לא יודע על התלות ועשוי להיתקל בשגיאות כשמבצע הקצאת משאבים במקביל.

שימוש בתצורה

  1. כדי להקצות את המשאבים החדשים ולהפעיל את ממשקי ה-API שצוינו בקובץ ההגדרות, מריצים את הפקודה הבאה מתיקיית השורש של אותה תיקייה שבה נמצא קובץ main.tf (שצריך להיות web):
    terraform apply
    
  2. בטרמינל, Terraform מדפיס תוכנית של פעולות שהוא יבצע.

    אם הכול נראה כמו שציפיתם, מאשרים את הפעולות על ידי הקלדת yes.

    main.tf
    Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
      + create
    
    Terraform will perform the following actions:
    
      # google_firebase_project.default will be created
      + resource "google_firebase_project" "default" {
          + display_name   = (known after apply)
          + id             = (known after apply)
          + project        = "terraform-friendlychat-codelab"
          + project_number = (known after apply)
        }
    
      # google_project.default will be created
      + resource "google_project" "default" {
          + auto_create_network = true
          + id                  = (known after apply)
          + labels              = {
              + "firebase" = "enabled"
            }
          + name                = "Terraform FriendlyChat Codelab"
          + number              = (known after apply)
          + project_id          = "terraform-friendlychat-codelab"
          + skip_delete         = (known after apply)
        }
    
      # google_project_service.firebase will be created
      + resource "google_project_service" "firebase" {
          + disable_on_destroy = false
          + id                 = (known after apply)
          + project            = "terraform-friendlychat-codelab"
          + service            = "firebase.googleapis.com"
        }
    
      # google_project_service.serviceusage will be created
      + resource "google_project_service" "serviceusage" {
          + disable_on_destroy = false
          + id                 = (known after apply)
          + project            = "terraform-friendlychat-codelab"
          + service            = "serviceusage.googleapis.com"
        }
    
    Plan: 4 to add, 0 to change, 0 to destroy.
    
    Do you want to perform these actions?
      Terraform will perform the actions described above.
      Only 'yes' will be accepted to approve.
    
      Enter a value: yes # <----
    

הערה: אם אתם רוצים רק לראות תצוגה מקדימה של השינויים בלי ליישם אותם, אתם יכולים להשתמש בפקודה 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.

הפרויקט של Terraform FriendlyChat Codelab שנבחר במסוף 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"
}

שימוש בתצורה

  1. כדי להקצות את המשאב החדש, מריצים את הפקודה הבאה מהרמה הבסיסית (root) של אותה ספרייה שבה נמצא הקובץ main.tf (שצריך להיות web).
    terraform apply
    
    הערה: הפקודה הזו לא יוצרת מחדש פרויקט חדש ב-Google Cloud. מערכת Terraform תזהה שפרויקט עם מזהה הפרויקט שצוין כבר קיים, תשווה את המצב הנוכחי של הפרויקט למה שמופיע בקובץ .tf ותבצע את כל השינויים שהיא תמצא.
  2. בודקים את תוכנית הפעולה המודפסת. אם הכול נראה כמו שציפיתם, מקלידים 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:

  1. במסוף Firebase, מאתרים את הקטע Build בחלונית הימנית.
  2. לוחצים על אימות, על שנתחיל? ואז על הכרטיסייה שיטת כניסה (או לוחצים כאן כדי לעבור ישירות לשם).
  3. לוחצים על הוספת ספק חדש ובקטע ספקים נוספים בוחרים באפשרות Google.
  4. מפעילים את המתג הפעלה.
  5. מגדירים לאפליקציה שם שגלוי לכולם, למשל FriendlyChat (השם לא צריך להיות ייחודי באופן גלובלי).
  6. בוחרים כתובת אימייל לתמיכה בפרויקט מהתפריט הנפתח ולוחצים על שמירה.הגדרת Firebase Auth במסוף Firebase
  7. Google אמורה להופיע כספק כניסה מופעל.דף האימות במסוף Firebase: כניסה באמצעות חשבון Google מופעלת

אפשרות 2: הגדרת אימות באמצעות Terraform באמצעות ממשקי Google Cloud Identity Platform ‏ (GCIP) API

כדי להגדיר את Firebase Authentication באמצעות Terraform, צריך להשתמש בממשקי GCIP API, כלומר הפרויקט צריך להיות בתוכנית התמחור Blaze. כדי לשדרג את הפרויקט ב-Firebase לתוכנית Blaze, צריך לשייך לחשבון לחיוב ב-Cloud את הפרויקט.

הפעלת החיוב באמצעות Terraform

  1. אם עדיין אין לכם חשבון לחיוב ב-Cloud, השלב הראשון הוא ליצור חשבון חדש במסוף Google Cloud. במהלך התהליך, חשוב לשים לב למזהה החשבון לחיוב. אפשר למצוא את מזהה החשבון לחיוב בדף החיוב בשדה מזהה החשבון לחיוב שמשויך לפרויקט.הפעלת חשבון לחיוב באמצעות מסוף Google Cloud
  2. כדי להפעיל את החיוב בפרויקט באמצעות 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

  1. כדי להקצות אימות ב-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,
      ]
    }
    
  2. כדי להפעיל כניסה באמצעות חשבון Google, צריך שיהיה לכם לקוח OAuth. כדי לבצע את ההגדרה הזו, נכנסים אל APIs & Services במסוף Google Cloud.
  3. זו הפעם הראשונה שאתם יוצרים מספר לקוח לפרויקט הזה, ולכן אתם צריכים להגדיר את מסך ההסכמה ל-OAuth.
    1. פותחים את הדף 'מסך ההסכמה ל-OAuth' ובוחרים את הפרויקט שיצרתם.
    2. מגדירים את סוג המשתמש כחיצוני ולוחצים על יצירה.
    3. במסך הבא, ממלאים את הפרטים הבאים ולוחצים על שמירה והמשך.
      • מגדירים את שם האפליקציה שגלוי לכולם, למשל FriendlyChat (השם לא צריך להיות ייחודי באופן גלובלי).
      • בוחרים כתובת אימייל לתמיכה במשתמשים מהתפריט הנפתח.
      • מזינים כתובת אימייל בפרטים ליצירת קשר עם המפתח.
    4. במסכים הבאים, מבצעים את הפעולות הבאות:
      • בדף Scopes (היקפים), מאשרים את אפשרויות ברירת המחדל ולוחצים על Save and Continue (שמירה והמשך).
      • בדף Test users (משתמשי בדיקה), מאשרים את אפשרויות ברירת המחדל ולוחצים על Save and Continue (שמירה והמשך).
      • בודקים את הסיכום ולוחצים על חזרה למרכז הבקרה.
      הגדרת לקוח OAuth2 באמצעות מסוף Google Cloud
  4. כדי להגדיר לקוח OAuth בדף פרטי הכניסה, מבצעים את הפעולות הבאות:
    1. לוחצים על Create credentials ובוחרים באפשרות OAuth client ID.
    2. בתפריט הנפתח Application type בוחרים באפשרות Web application.
    3. בשדה Name (שם), מזינים את שם האפליקציה, למשל FriendlyChat (השם לא צריך להיות ייחודי גלובלית).
    4. כדי לאפשר לכתובת ה-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.
    5. לוחצים על שמירה.
    איך מקבלים את מזהה הלקוח ואת הסוד של OAuth2 מדף פרטי הכניסה במסוף Google Cloud
  5. כדי להפעיל כניסה באמצעות חשבון 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
      ]
    }
    

שימוש בתצורה

  1. כדי להגדיר אימות בהתאם להגדרות, מריצים את הפקודות הבאות מהרמה הבסיסית (root) של אותה תיקייה שבה נמצא הקובץ main.tf (שצריך להיות web):
    export TF_VAR_oauth_client_secret="<YOUR_OAUTH_CLIENT_SECRET>"
    
    terraform apply
    
    שימו לב שהרצת הפקודה terraform apply לא תיצור מחדש פרויקט חדש ב-Google Cloud. מערכת Terraform תזהה שכבר קיים פרויקט עם מזהה הפרויקט שצוין, ותשווה את המצב הנוכחי של הפרויקט למה שמופיע בקובץ .tf. לאחר מכן המערכת תבצע את השינויים שהיא תמצא.
  2. בודקים את תוכנית הפעולה המודפסת. אם הכול נראה כמו שציפיתם, מקלידים yes ולוחצים על Enter כדי לאשר את הפעולות.

אימות השינויים

  1. במסוף Firebase, מאתרים את הקטע Build בחלונית הימנית.
  2. לוחצים על אימות ואז על הכרטיסייה שיטת כניסה (או לוחצים כאן כדי לעבור ישירות לשם).
  3. Google אמורה להופיע כספק כניסה מופעל.דף האימות במסוף Firebase: כניסה באמצעות חשבון Google מופעלת

7. הגדרת מסד נתונים ב-Firestore וכללי האבטחה שלו

באפליקציית האינטרנט של ה-codelab הזה, תאחסנו הודעות בין משתמשי קצה במסד נתונים של Firestore.

  1. כדי להפעיל את ממשקי ה-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
      ]
    }
    
  2. מחליפים את <NAME_OF_DESIRED_REGION> באזור שבו רוצים שהמסד הנתונים יהיה ממוקם.

    כשמפתחים אפליקציה לייצור, כדאי שהמיקום יהיה באזור שקרוב לרוב המשתמשים ומשותף לשירותי Firebase אחרים, כמו Cloud Functions. ב-codelab הזה, אפשר להשתמש במיקום us-east1 (דרום קרוליינה) או באזור הקרוב ביותר למיקום שלכם (ראו מיקומים של Cloud Firestore).
  3. כל מופע של מסד נתונים של Firestore שאפשר לגשת אליו מ-Firebase צריך להיות מוגן על ידי כללי אבטחה של Firebase.

    קוד הדוגמה של ה-codelab הזה מספק קבוצה של כללי אבטחה של Firestore בקובץ firestore.rules, שאפשר למצוא אותו בספריית הבסיס של web.
  4. מוסיפים לקובץ main.tf את בלוקי המשאבים הבאים כדי לבצע את הפעולות הבאות:
    • יוצרים קבוצת כללים של כללי אבטחה של Firebase מקובץ firestore.rules המקומי.
    • משחררים את קבוצת הכללים עבור מופע Firestore.
    שימו לב שבלוקי המשאבים האלה מבצעים פעולה ששווה לקליק על הלחצן Publish במסוף Firebase או להרצת firebase deploy --only firestore:rules.

    main.tf
    ...
    
    # Create a ruleset of Firestore Security Rules from a local file.
    resource "google_firebaserules_ruleset" "firestore" {
      provider = google-beta
    
      project  = google_firebase_project.default.project
      source {
        files {
          name = "firestore.rules"
          # Write security rules in a local file named "firestore.rules".
          # Learn more: https://firebase.google.com/docs/firestore/security/get-started
          content = file("firestore.rules")
        }
      }
    
      # Wait for Firestore to be provisioned before creating this ruleset.
      depends_on = [
        google_firestore_database.default,
      ]
    }
    
    # Release the ruleset for the Firestore instance.
    resource "google_firebaserules_release" "firestore" {
      provider     = google-beta
    
      name         = "cloud.firestore"  # must be cloud.firestore
      ruleset_name = google_firebaserules_ruleset.firestore.name
      project      = google_firebase_project.default.project
    
      # Wait for Firestore to be provisioned before releasing the ruleset.
      depends_on = [
        google_firestore_database.default,
      ]
    
      lifecycle {
        replace_triggered_by = [
          google_firebaserules_ruleset.firestore
        ]
      }
    }
    
  5. מריצים את הפקודה terraform apply כדי להקצות את מסד הנתונים של Firestore ולפרוס את כללי האבטחה שלו.
  6. מוודאים שמסד הנתונים הוקצה ושכללי האבטחה שלו נפרסו:
    1. במסוף Firebase, מאתרים את הקטע Build בחלונית הימנית.
    2. עוברים לקטע Firestore Database ולוחצים על הכרטיסייה Rules (כללים).
    אימות כללי Cloud Firestore באמצעות מסוף Firebase

8. הגדרת קטגוריה של Cloud Storage וכללי האבטחה שלה

באפליקציית האינטרנט של ה-codelab הזה, תאחסנו תמונות שמשותפות בין משתמשי קצה בקטגוריה של Cloud Storage.

  1. כדי להפעיל את ממשקי ה-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
    }
    
  2. כל מאגר Cloud Storage שאפשר לגשת אליו מ-Firebase צריך להיות מוגן על ידי כללי אבטחה של Firebase.

    דוגמת הקוד של ה-codelab הזה מספקת קבוצה של כללי Firestore מאובטחים בקובץ storage.rules, שאפשר למצוא אותו בספריית הבסיס של web.
  3. מוסיפים לקובץ main.tf את בלוקי המשאבים הבאים כדי לבצע את הפעולות הבאות:
    • יוצרים קבוצת כללים של כללי אבטחה של Firebase מהקובץ המקומי.
    • משחררים את קבוצת הכללים לקטגוריית האחסון.
    שימו לב שבלוקי המשאבים האלה מבצעים פעולה ששווה לקליק על הלחצן Publish במסוף 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
        ]
      }
    }
    
  4. מריצים את הפקודה terraform apply כדי להקצות את קטגוריית ברירת המחדל של Cloud Storage ולפרוס את כללי האבטחה שלה.
  5. מוודאים שה-bucket הוקצה ושהכללים שלו בנושא אבטחה נפרסו:
    1. במסוף Firebase, מאתרים את הקטע Build בחלונית הימנית.
    2. עוברים לקטע אחסון ולוחצים על הכרטיסייה כללים.
    אימות כללי אבטחה באמצעות מסוף Firebase

9. הפעלת האפליקציה באופן מקומי

עכשיו אפשר להפעיל את אפליקציית האינטרנט בפעם הראשונה. תשתמשו באמולטור של Firebase Hosting כדי להפעיל את האפליקציה באופן מקומי.

  1. פותחים חלון טרמינל חדש ומריצים את פקודת Firebase CLI הבאה מהספרייה web כדי להפעיל את האמולטור:
    firebase emulators:start --project=<PROJECT_ID>
    
  2. בדפדפן, פותחים את אפליקציית האינטרנט בכתובת ה-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

כדי להתחיל את בניית האפליקציה, צריך להריץ כמה פקודות.

  1. פותחים חלון טרמינל חדש.
  2. מוודאים שאתם נמצאים בספריית השורש של web.
  3. מריצים את הפקודה npm install כדי להוריד את Firebase SDK.
  4. מריצים את npm update כדי לעדכן את כל התלויות.
  5. מריצים את הפקודה npm run start כדי להפעיל את webpack.

מעכשיו, webpack יבנה מחדש את קוד המקור באופן רציף למשך שאר ה-codelab.

הוספת התצורה של Firebase לאפליקציה

צריך גם להוסיף את ההגדרה של Firebase לאפליקציה כדי שערכות ה-SDK של Firebase ידעו באיזה פרויקט Firebase אתם רוצים להשתמש.

יש שתי אפשרויות שונות לקבלת הגדרת Firebase עבור ה-codelab הזה:

  • אפשרות 1: מקבלים את התצורה של Firebase ממסוף Firebase.
  • אפשרות 2: קבלת הגדרות Firebase באמצעות Terraform.

אפשרות 1: מקבלים את התצורה ממסוף Firebase ומוסיפים אותה לבסיס הקוד

  1. במסוף Firebase, עוברים אל Project settings (הגדרות הפרויקט).
  2. גוללים למטה אל הכרטיס האפליקציות שלך ובוחרים את אפליקציית האינטרנט.
  3. בוחרים באפשרות Config (הגדרה) בחלונית של קטע הקוד של Firebase SDK, ואז מעתיקים את קטע ההגדרה.
  4. מדביקים את ההגדרה בקובץ 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.

  1. בקובץ main.tf, מחפשים את בלוק המשאבים google_firebase_web_app (הבלוק שרשם אפליקציית אינטרנט בפרויקט).
  2. מיד אחרי הבלוק הזה, מוסיפים את הבלוקים הבאים:

    main.tf
    ...
    
    data "google_firebase_web_app_config" "default" {
      provider     = google-beta
      project      = google_firebase_project.default.project
      web_app_id   = google_firebase_web_app.default.app_id
    }
    
    output "friendlychat_web_app_config" {
      value = {
        projectId         = google_firebase_project.default.project
        appId             = google_firebase_web_app.default.app_id
        apiKey            = data.google_firebase_web_app_config.default.api_key
        authDomain        = data.google_firebase_web_app_config.default.auth_domain
        storageBucket     = lookup(data.google_firebase_web_app_config.default, "storage_bucket", "")
        messagingSenderId = lookup(data.google_firebase_web_app_config.default, "messaging_sender_id", "")
        measurementId     = lookup(data.google_firebase_web_app_config.default, "measurement_id", "")
      }
    }
    
    ...
    
  3. הבלוקים data ו-output לא מיועדים לשינוי התשתית בשום צורה, ולכן צריך להריץ רק את הפקודות הבאות.
    1. כדי לטעון את ההגדרות של Firebase של אפליקציית האינטרנט למצב Terraform של הספרייה, מריצים את הפקודה הבאה:
      terraform refresh
      
    2. כדי להדפיס את ערכי ההגדרה של 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"
          }
        }
      }
      
  4. מעתיקים את הערכים מתוך המפה value.
  5. מדביקים את הערכים האלה (ההגדרות שלכם) בקובץ 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 של האפליקציה:

index.js

...

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

ניסיון השימוש באפליקציה

אחרי שסיימתם להגדיר הכול ל-Firebase, אתם יכולים לנסות את אפליקציית האינטרנט הפונקציונלית.

  1. מרעננים את הדפדפן שבו האפליקציה פועלת.
  2. עכשיו אמורה להיות לכם אפשרות להיכנס באמצעות Google ולהתחיל לפרסם הודעות בצ'אט. אם יש לכם קבצים של תמונות, אתם יכולים גם להעלות אותם.

11. שכפול ההגדרה בסביבות שונות

‫Terraform מצטיין בניהול של תשתית מרובה עם הגדרות דומות (לדוגמה, הגדרת פרויקט Firebase ב-Staging שדומה לפרויקט בייצור).

ב-codelab הזה תיצרו פרויקט שני ב-Firebase שיהיה סביבת Staging.

כדי לשכפל הגדרה קיימת וליצור את פרויקט ההכנה, יש שתי אפשרויות:

  • אפשרות 1: יוצרים עותק של הגדרת Terraform.
    האפשרות הזו מציעה את הגמישות הגבוהה ביותר לגבי מידת השוני בין הפרויקט המשוכפל לבין פרויקט המקור.
  • אפשרות 2: שימוש חוזר בהגדרות באמצעות for_each.
    האפשרות הזו מאפשרת שימוש חוזר בקוד, אם לא אמורים להיות הבדלים משמעותיים בין הפרויקטים ואתם רוצים להפיץ את השינויים לכל הפרויקטים בבת אחת.

אפשרות 1: יצירת עותק של הגדרות Terraform

האפשרות הזו מציעה את הגמישות הגבוהה ביותר לגבי מידת השוני בין הפרויקט המשוכפל לבין פרויקט המקור. לדוגמה, אפשר להשתמש באפליקציות עם שמות תצוגה שונים ובפריסות מדורגות.

  1. בשורש של הספרייה web, יוצרים קובץ תצורה חדש של Terraform בשם main_staging.tf.
  2. מעתיקים את כל בלוקי המשאבים מקובץ main.tf (חוץ מהבלוקים terraform ו-provider), ואז מדביקים אותם בקובץ main_staging.tf.
  3. לאחר מכן צריך לשנות כל אחד מבלוקי המשאבים המשוכפלים ב-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

    אם רוצים להשתמש בהגדרה הזו, צריך לוודא שמבצעים את הפעולות הבאות:
    1. מעתיקים את ההגדרות מ-main_staging-copypaste.tf ומדביקים אותן בקובץ main_staging.tf.
    2. בקובץ 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 עם הערך שלכם.
    main_staging.tf
    # Create a new Google Cloud project.
    resource "google_project" "staging" {
      provider = google-beta.no_user_project_override
    
      name            = "<PROJECT_NAME_OF_STAGING_PROJECT>"
      project_id      = "<PROJECT_ID_OF_STAGING_PROJECT"
      # Required if you want to set up Authentication via Terraform
      billing_account = "<YOUR_BILLING_ACCOUNT_ID>"
    
      # Required for the project to display in any list of Firebase projects.
      labels = {
        "firebase" = "enabled"
      }
    }
    
    # Enable the required underlying Service Usage API.
    resource "google_project_service" "staging_serviceusage" {
      provider = google-beta.no_user_project_override
    
      project = google_project.staging.project_id
      service = "serviceusage.googleapis.com"
    
      # Don't disable the service if the resource block is removed by accident.
      disable_on_destroy = false
    }
    
    # Enable the required underlying Firebase Management API.
    resource "google_project_service" "staging_firebase" {
      provider = google-beta.no_user_project_override
    
      project = google_project.staging.project_id
      service = "firebase.googleapis.com"
    
      # Don't disable the service if the resource block is removed by accident.
      disable_on_destroy = false
    }
    
    # Enable Firebase services for the new project created above.
    resource "google_firebase_project" "staging" {
      provider = google-beta
    
      project = google_project.staging.project_id
    
      # Wait until the required APIs are enabled.
      depends_on = [
        google_project_service.staging_serviceusage,
        google_project_service.staging_firebase,
      ]
    }
    
    # Create a Firebase Web App in the new project created above.
    resource "google_firebase_web_app" "staging" {
      provider = google-beta
    
      project      = google_firebase_project.staging.project
      display_name = "<DISPLAY_NAME_OF_YOUR_WEB_APP>"
      deletion_policy = "DELETE"
    }
    
  4. מריצים את הפקודה terraform apply כדי להקצות את פרויקט Firebase החדש 'staging' ואת כל המשאבים שלו, ולהפעיל את השירותים שלו.
  5. כדי לוודא שהקצאת ההרשאות וההפעלה בוצעו כצפוי, בודקים אותן במסוף Firebase כמו קודם.

אפשרות 2: שימוש חוזר בהגדרות באמצעות for_each

האפשרות הזו מאפשרת שימוש חוזר בקוד, אם לא אמורים להיות הבדלים משמעותיים בין הפרויקטים ואתם רוצים להפיץ את השינויים לכל הפרויקטים בבת אחת. הוא משתמש במטא-ארגומנט for_each בשפת Terraform.

  1. פותחים את קובץ ה-main.tf.
  2. לכל בלוק משאבים שרוצים לשכפל, מוסיפים מטא-ארגומנט for_each, כך:

    main.tf
    # Create new Google Cloud projects.
    resource "google_project" "default" {
      provider        = google-beta.no_user_project_override
      name            = each.value
      # Create a unique project ID for each project, with each ID starting with <PROJECT_ID>.
      project_id      = "<PROJECT_ID>-${each.key}"
      # Required if you want to set up Authentication via Terraform
      billing_account = "<YOUR_BILLING_ACCOUNT_ID>"
    
      # Required for the projects to display in any list of Firebase projects.
      labels = {
        "firebase" = "enabled"
      }
    
      for_each = {
        prod    = "<PROJECT_NAME_OF_PROD_PROJECT>"
        staging = "<PROJECT_NAME_OF_STAGING_PROJECT>"
      }
    }
    
    # Enable the required underlying Service Usage API.
    resource "google_project_service" "serviceusage" {
      provider = google-beta.no_user_project_override
      for_each = google_project.default
    
      project = each.value.project_id
      service = "serviceusage.googleapis.com"
    
      # Don't disable the service if the resource block is removed by accident.
      disable_on_destroy = false
    }
    
    # Enable the required underlying Firebase Management API.
    resource "google_project_service" "firebase" {
      provider = google-beta.no_user_project_override
      for_each = google_project.default
    
      project = each.value.project_id
      service = "firebase.googleapis.com"
    
      # Don't disable the service if the resource block is removed by accident.
      disable_on_destroy = false
    }
    
    # Enable Firebase services for each of the new projects created above.
    resource "google_firebase_project" "default" {
      provider = google-beta
      for_each = google_project.default
    
      project = each.value.project_id
    
      depends_on = [
        google_project_service.serviceusage,
        google_project_service.firebase,
      ]
    }
    
    # Create a Firebase Web App in each of the new projects created above.
    resource "google_firebase_web_app" "default" {
      provider = google-beta
      for_each = google_firebase_project.default
    
      project      = each.value.project
      # The Firebase Web App created in each project will have the same display name.
      display_name = "<DISPLAY_NAME_OF_YOUR_WEB_APP>"
      deletion_policy = "DELETE"
    }
    
    
    # NOTE: For this codelab, we recommend setting up Firebase Authentication
    # using the Firebase console. However, if you set up Firebase Authentication
    # using Terraform, copy-paste from your main.tf the applicable blocks.
    # Make sure to add the `for_each` meta-argument into each block.
    
    
    # Copy-paste from your main.tf file the applicable resource blocks
    # for setting up Cloud Firestore (including rules) and
    # for setting up Cloud Storage for Firebase (including rules).
    # Make sure to add the `for_each` meta-argument into each block.
    
    אפשר למצוא את ההגדרה המלאה של קובץ main.tf שמשתמש בארגומנט המטא for_each במאגר GitHub של ה-codelab הזה:

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

    אם רוצים להשתמש בהגדרה הזו, צריך לבצע את הפעולות הבאות:
    1. מעתיקים את ההגדרות מ-main-foreach.tf ומדביקים אותן בקובץ main.tf.
    2. בקובץ 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 עם הערך שלכם.
  3. במקום להחיל את ההגדרה הזו באופן מיידי, חשוב להבין ולתקן כמה דברים לגבי האופן שבו Terraform מפרש את ההגדרה הזו בהשוואה לתשתית הקיימת.
    1. אם תחיל את ההגדרה הזו שמשתמשת ב-for_each, כתובות המשאבים ייראו כך:
      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"]
      
      עם זאת, הפרויקט הקיים שיצרתם בחלק הראשון של ה-codelab הזה מוכר ל-Terraform בתור:
      google_project.default
      google_firebase_project.default
      google_firebase_android_app.default
      
    2. מריצים את הפקודה terraform plan כדי לראות אילו פעולות Terraform יבצע בהינתן המצב הנוכחי.

      הפלט צריך להראות ש-Terraform ימחק את הפרויקט שיצרתם בחלק הראשון של ה-Codelab הזה וייצור שני פרויקטים חדשים. הסיבה לכך היא ש-Terraform לא יודע שהפרויקט בכתובת google_project.default הועבר לכתובת החדשה google_project.default["prod"].
    3. כדי לפתור את הבעיה, מריצים את הפקודה terraform state mv:
      terraform state mv "google_project.default" "google_project.default[\"prod\"]"
      
    4. באופן דומה, כדי לתקן את כל בלוקי המשאבים האחרים, מריצים את הפקודה terraform state mv עבור google_firebase_project, google_firebase_web_app וכל בלוקי המשאבים האחרים בקובץ main.tf.
    5. עכשיו, אם מריצים שוב את הפקודה terraform plan, לא אמורה להופיע הודעה של Terraform על מחיקת הפרויקט שיצרתם בחלק הראשון של ה-Codelab הזה.
  4. מריצים את הפקודה terraform apply כדי להקצות את פרויקט Firebase החדש 'staging' ואת כל המשאבים שלו, ולהפעיל את השירותים שלו.
  5. כדי לוודא שהקצאת ההרשאות וההפעלה בוצעו כצפוי, בודקים אותן במסוף Firebase כמו קודם.

12. שלב בונוס: פריסת אפליקציות בסביבת פיתוח ובסביבת ייצור

  1. בבסיס הקוד של האפליקציה, משנים את firebase-config.js כך שישתמש בהגדרות של Firebase מפרויקט ההכנה במקום זאת.

    כדי להיזכר איך מקבלים את ההגדרות של Firebase ומוסיפים אותן לאפליקציה, אפשר לעיין בשלב הקודם של ה-codelab הזה, הוספת ההגדרות של Firebase לאפליקציה.
  2. בשורש של ספריית web, מריצים את הפקודה הבאה כדי לפרוס את האפליקציה לפרויקט Firebase של שלב הביניים.
    firebase deploy --only hosting --project=<STAGING_PROJECT_ID>
    
  3. פותחים את אפליקציית הסביבה הזמנית בדפדפן באמצעות כתובת ה-URL שמופיעה בפלט של firebase deploy. נסו להיכנס, לשלוח הודעות ולהעלות תמונות.

    כשפורסים אפליקציה בפרויקט Firebase, היא משתמשת במשאבים אמיתיים של Firebase, ולא במשאבים מדומיים. במהלך האינטראקציה עם אפליקציית הסביבה, נתונים ותמונות אמורים להופיע בפרויקט הסביבה במסוף Firebase.
  4. אחרי שבודקים את האפליקציה בסביבת הפיתוח, משנים את firebase-config.js בחזרה לשימוש בהגדרות Firebase של פרויקט הייצור (הפרויקט הראשון שיצרתם ב-codelab הזה).
  5. בספריית web הבסיסית, מריצים את הפקודה הבאה כדי לפרוס את האפליקציה לפרויקט Firebase של הסביבה הפעילה.
    firebase deploy --only hosting --project=<PRODUCTION_PROJECT_ID>
    
  6. פותחים את אפליקציית ההפקה בדפדפן באמצעות כתובת ה-URL שמודפסת בפלט של firebase deploy. נסו להיכנס, לשלוח הודעות ולהעלות תמונות.

    אחרי שתעשו את זה, תוכלו לראות את הנתונים והתמונות בפרויקט הפרודקשן במסוף Firebase.
  7. אחרי שתסיימו את האינטראקציה עם שתי האפליקציות ב-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 לתרחישי שימוש נפוצים, ופתרון בעיות ושאלות נפוצות שיעזרו לכם.