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

Infrastructure as a Code

בשנם האחרונות ישנה גדילה בפופולאריות של שירותי ענן וביכולות המטורפות אותן מביאות ספקיות הענן הקטנות והגדולות. אחת מהיכולות שנוצרה היא היכולת להקים, לשנות ואף להרוס משאבי ענן בצורה אוטומטית ע״י שימוש ב-Infrastructure as a Code.

עד לפני מספר שנים על מנת להקים משאבי ענן היינו צריכים להשתמש בממשק המשתמש של הספקית או רחמנא ליצלן 🫣 דרך כלי CLI של של הספקית.

פעם כאשר זאת הייתה הדרך היחידה זה לעבוד עם שירותי ענן זה היה זניח, אך עם התקדמות הטכנולוגיה וההבנה כי אוטומציה היא הכרחית, וגם כי נמאס לנו שמזיזים לנו את הגבינה (ממשקים משתנים, מה נעשה 🤷‍♂️) – לשם כך הומצא Infrastructure as a Code, או IaC בקיצור.

IaC מאפשר לנו לכתוב סט של הוראות להקמה ושינוי של משאבי ענן, אשר אותו נוכל להריץ או לעלות לכלי של הספקית על מנת שהוראות אלו יבוצעו.

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

אז מה זה Terraform?

אז דיברנו על זה ש-Infrastructure as a Code הוא כלי חזק, אך אם אני עובד עם מספר ספקיות ענן אני צריך סוג של להכיר את הפורמט שבו הם מממשות IaC.

Terraform היא תוכנת קוד פתוח אשר מפותחת ומתוחזקת ע״י HashiCorp, אשר בעזרתה ניתן לנהל משאבי ענן בכל אחת מספקיות הענן הגדולות וברוב הקטנות. היא עושה זאת ע״י שימוש ב-Provider-ים, שהם לרוב מפותחים ומתוחזקים ע״י HashiCorp על מנת שנוכל לממש את סט ההוראות מול ה-API של ספקית הענן הרלוונטית.

כתיבה הוראות הקמת משאבים מבוצעת ע״י שימוש בשפת HCL (קרי, HashiCorp Configuration Language). והיא כוללת 4 פקודות מרכזיות אותן מריצים בטרמינל של המחשב או השרת על מנת שסט הפקודות אותן כתבנו יבוצע 💪.

איך זה עובד?

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

שימוש ב-Terraform מתבצע ב-3 פעולות:

  1. כתיבה – בשלב זה אנו כותבים סט הוראות והגדרות להקמה או שינוי של משאבי ענן בחשבון שלנו ע״י שימוש בשפת HCL.
  2. תכנון – בשלב זה אנו מבצעים ״הרצה יבשה״ של סט הפקודות שלנו על מנת לראות מה יוקם ומה ישתנה.
  3. ביצוע – בשלב זה אנו מריצים את השינויים בפועל.

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

שימו לב, שימוש לא נכון בשירותי ענן יכול לגרום לעלויות גבוהות, לכן מומלץ שתהיה לכם היכרות עם שירותי ענן.

צעדים ראשונים עם Terraform

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

התקנת Terraform CLI

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

הדרך הכי מומלצת להתקין היא ע״י שימוש ה-Homebrew, בשלב הראשון עלינו להגדיר ל-Homebrew את הכתובת של ה-Repository של HashiCorp:

brew tap hashicorp/tap

לאחר מכן נתקין ע״י הרצת הפקודה הבאה:

brew install hashicorp/tap/terraform

לבסוף על מנת לוודא שהותקן בהצלחה נריץ את הפקודה terraform -v ונוודא שלא מוצגת לנו שגיאה.

התקנת AWS CLI

על מנת שנוכל לעבוד עם Amazon Web Services אנו צריכים להתקין כלי ה-CLI של AWS ע״י הרצת הפקודות הבאות:

curl "https://awscli.amazonaws.com/AWSCLIV2.pkg" -o "AWSCLIV2.pkg"

לאחר מכן נתקין את הכלי ע״י הרצת הפקודה:

sudo installer -pkg AWSCLIV2.pkg -target /

ולבסוף נוודא התקנה ע״י הרצת הפקודה aws --version.

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

aws configure

הגדרת משאבים עם Terraform

הגיע הזמן לכתוב קצת קוד, נתחיל ביצירת תיקייה שנקראת iac בפרוייקט שלנו (בת׳כלס אפשר לתת לה איזה שם שאנחנו רוצים 😉) ובתוכה ניצור קובץ חדש שנקרא main.tf.

כעת נפתח את עורך הקוד המועדף עלינו ונכניס בתור התחלה את הקוד הבא:

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.41.0"
    }
  }
}

הקוד הנ״ל מגדיר שאנחנו רוצים לעבוד עם Amazon Web Services, מה שיגרום לו להוריד את הקוד של ה-Provider הרלוונטי.

כעת נוסיף את הקוד הבא בנוסף:

provider "aws" {
  region = "eu-west-1"

  default_tags {
    tags = {
      Managed_By = "Terraform"
    }
  }
}

הקוד הבא רושם את ה-Provider של AWS עם מספר הגדרות:

  1. ע״י שימוש ב-region אנו מגדירים את ה-Region בו אנו רוצים להקים את המשאבים.
  2. הפרמטר default_tags יגדיר לכל Resource שנקים תגיות ברירת מחדל, במקרה שלנו תגית אשר תסמן לנו שהמשאב מנוהל ע״י Terraform.

ולבסוף ניצור S3 Bucket חדש ע״י הוספת הקוד הבא:

resource "aws_s3_bucket" "dorzki-bucket" {
  bucket        = "dorzki-bucket"
  force_destroy = true

  tags = {
    Name = "dorzki-bucket"
  }
}

הגדרנו ליצור לנו S3 Bucket חדש עם השם dorzki-bucket ב-AWS, והגדרנו לו שיוסיף לתגיות ברירה המחדל תגית נוספת עם שם ה-Bucket.

אתחול והקמת משאבים

כעת אחרי שיצרנו את הקובץ IaC הראשון שלנו, כל שנשאר לנו הוא להריץ את הקוד. אך לפני שנוכל להריץ את הקוד, אנו צריכים לאתחל את הפרוייקט מה שבין השאר יוריד את הקוד של ה-Provider יחד עם מודולים נוספים במידה והגדרנו.

נפתח את הטרמינל, ננווט בו לתיקייה בה נמצא הקובץ שיצרנו ונריץ את הפקודה הבאה:

terraform init

לאחר שהפקודה תסתיים לרוץ, נוכל לבצע הרצה יבשה ולראות מה השינויים שיבוצעו בעקבות הקוד שלנו, לצורך כך נריץ את הפקודה הבאה:

terraform plan

במידה והכל תקין אנחנו אמורים לראות פלט בדומה לפלט הבא:

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:

  # aws_s3_bucket.dorzki-bucket will be created
  + resource "aws_s3_bucket" "dorzki-bucket" {
      + acceleration_status         = (known after apply)
      + acl                         = (known after apply)
      + arn                         = (known after apply)
      + bucket                      = "dorzki-bucket"
      + bucket_domain_name          = (known after apply)
      + bucket_regional_domain_name = (known after apply)
      + force_destroy               = true
      + hosted_zone_id              = (known after apply)
      + id                          = (known after apply)
      + object_lock_enabled         = (known after apply)
      + policy                      = (known after apply)
      + region                      = (known after apply)
      + request_payer               = (known after apply)
      + tags                        = {
          + "Name" = "dorzki-bucket"
        }
      + tags_all                    = {
          + "Managed_By" = "Terraform"
          + "Name"       = "dorzki-bucket"
        }
      + website_domain              = (known after apply)
      + website_endpoint            = (known after apply)

      ...
    }

Plan: 1 to add, 0 to change, 0 to destroy.

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

על מנת להקים את המשאב בפועל כל מה שעלינו לעשות זה להריץ את הפקודה הבאה:

terraform apply

אם נכנס לאחר מכם ל-S3 תחת החשבון שלנו ב-AWS נראה שהוקם לנו ה-Bucket.

צילום מסך של הממשק משתמש של S3 המציג את ה-Bucket שנוצר.

במידה ונרצה למחוק את כלל המשאבים שיצרנו, נוכל להריץ את הפקודה הבאה:

terraform destroy

שמירת State

כאשר אנו מקימים משאבים עם Terraform, יווצר לנו קובץ אשר שומר מידע אודות אילו משאבים הוקמו ומה ההגדרות שלהם.

לרוב כאשר עובדים עם Terraform אנו לא נסתמך על שמירת ה-State בצורה לוקלית מכיוון שאם נעבור מחר ונריץ שוב את הפקודה הוא ינסה ליצור את המשאבים מחדש 🫢. על מנת להתמודד עם הנושא, אנו יכולים להגדיר Backend, שזה מעין אחסון מרוחק ל-State, במקרה שלנו אנו יכולים להגדיר שה-Backend שלנו יהיה S3 Bucket.

על מנת להגדיר S3 Bucket כ-Backend, ניתן להוסיף את הקוד הבא אחרי required_providers:

backend "s3" {
  bucket  = "dorzki-tf-bucket"
  region  = "eu-west-1"
  key     = "terraform.tfstate"
  encrypt = true
}

שימו לב שצריך ליצור את ה-Bucket הזה בצורה ידנית לפני שנוכל להשתמש בו.

סיכום

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

    כתיבת תגובה

    1. רועי

      אחלה מאמר, מאוד מפורט!

      הגב
      1. דור צוברי

        היי רועי 👋🏽,
        תודה רבה, כיך לשמוע!

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

    שתפו