איך ליצור Lambda Function ו API Gateway על AWS באמצעות ה CLI

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

אחד הטרנדים החמים היום בפיתוח הוא Serverless או פיתוח ללא קוד Back End, או יותר נכון פיתוח בלי מערכת Back End מלאה שמטפלת בכל ההיבטים של צד השרת. פיתוח Serverless יהיה יותר דומה לפיתוח Micro Services, אבל בצורה שכל סרביס רץ בתוך סביבת ריצה מנוהלת ומבוקרת משלו.

שירות AWS Lambda הוא דוגמה לפיתוח מסוג זה. הוא מאפשר לנו לכתוב קוד (פונקציה) שירוץ בכל פעם שקורה משהו ויחזיר תוצאה למי שקרא לו. באמצעות חיבור הפונקציה לשירות שנקרא API Gateway אנחנו הופכים את אותה פונקציה לזמינה מכל מקום ברשת למרות שהיא עצמה בסך הכל פונקציה קטנה אחת ולא מערכת Back End מלאה.

במדריך זה אראה איך להקים פונקציה (לא משהו מסובך היא רק תחזיר Hello World בדוגמה שלנו) ולחבר אותה ל API Gateway וכל זה באמצעות שימוש בכלי שורת הפקודה של AWS בלבד.

1. למה לעבוד עם ה AWS CLI

את התהליך שנראה בפוסט אפשר לסיים ב-3 לחיצות מתוך הממשק הגרפי של אמזון ולכן מי שכבר הקים פונקציה בעבר עשוי לתהות: בשביל מה להתאמץ ולעבוד דרך ה CLI? ואיך בכלל מתקינים את ה CLI?

אז התשובה לשאלה השניה היא הקלה מבין השתיים. בשביל להתקין את AWS CLI פשוט צריך להוריד את הקובץ המתאים. יש כאן את הקישור לקובץ + הוראות התקנה: https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html.

אני אשתמש בגירסה 2 של הכלי aws שהיא החדשה ביותר כרגע.

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

  1. הוא מאפשר הקמה של אוטומציות ותהליכי פיתוח מקצועיים הרבה יותר מהירים.

  2. הוא דורש מאתנו הבנה יותר מעמיקה של מה קשור למה ואיך דברים עובדים.

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

2. הקמת פונקציה

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

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "arn:aws:logs:eu-west-3:123456789123:*"
        },
        {
            "Effect": "Allow",
            "Action": "logs:CreateLogGroup",
            "Resource": "*"
        }
    ]
}

במפתח Resource אנחנו מוצאים את הערך:

arn:aws:logs:eu-west-3:123456789123:*

הטקסט eu-west-3 הוא ה Region שמציין איפה השרת יושב, והמספר 123456789123 הוא ה Account ID. את שני הערכים תצטרכו להחליף בערכים שלכם.

עכשיו צריך להעלות את הקובץ לאמזון וליצור ממנו Policy, שזה אוביקט הרשאות:

$ aws iam create-policy --policy-name DemoPolicy --policy-document file://policy.json

כדי לחבר אוביקט הרשאות לפונקציה אנחנו צריכים לייצר Role. רול ב AWS הוא אוסף של אוביקטי הרשאות שיכולים להתאים לאוביקט ביצוע מסוים במערכת. בשביל ליצור את ה role אשתמש בפקודה:

$ aws iam create-role --role-name lambda-ex --assume-role-policy-document '{"Version": "2012-10-17","Statement": [{ "Effect": "Allow", "Principal": {"Service": "lambda.amazonaws.com"}, "Action": "sts:AssumeRole"}]}'

נשים לב לערך במפתח Service שהוא lambda.amazonaws.com שאומר ש Role זה יכול להתאים לפונקציות Lambda.

עכשיו צריך לחבר את ה Policy שיצרנו ל Role בעזרת הפקודה:

$ aws iam attach-role-policy --role-name lambda-ex --policy-arn arn:aws:iam::123456789123:policy/DemoPolicy

ורק אל תשכחו להחליף את מספר החשבון בחשבון שלכם.

את הפונקציה עצמה אני כותב בקובץ JavaScript בשם index.js וזה יהיה תוכנו:

exports.handler = async (event, context) => {
  return {
    statusCode: 200,
    body: JSON.stringify("hello world"),
    headers: {
      "Content-Type": "application/json",
    }
  };
};

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

בשביל להעלות את הפונקציה לאמזון אני שם את הקובץ בתוך zip:

$ zip function.zip index.js

ולבסוף יוצר את הפונקציה עם ההרשאות המתאימות והתוכן המתאים מהזיפ:

$ aws lambda create-function --function-name my-function \
    --zip-file fileb://function.zip --handler index.handler --runtime nodejs12.x \
    --role arn:aws:iam::123456789123:role/lambda-ex

בנקודה הזאת שווה להיכנס לממשק הגרפי למסך ניהול ה Lambda Functions ולוודא שהפונקציה במקום.

3. הקמת ה API Gateway

באמזון API Gateway הוא הרכיב שמקבל קריאות מהרשת ומעביר אותן לטיפול, כשבמקרה שלנו הטיפול זה להפעיל את הפוקנציה ולהחזיר את הערך שהיא מחזירה. הפקודה הבאה יוצרת API Gateway:

$ aws apigatewayv2 create-api --name my-api --protocol-type HTTP

הפקודה הבאה יוצרת Integration, שזה חיבור בין API Gateway לבין פונקציה:

$ aws apigatewayv2 create-integration --api-id v7ee0lwd52 --integration-type AWS_PROXY --integration-uri arn:aws:lambda:eu-west-3:123456789123:function:my-function --payload-format-version "2.0"

שימו לב להחליף את מזהה החשבון ואת ה Region לערכים שמתאימים לכם, ואת ה API ID למזהה שקיבלתם מהפקודה הקודמת (שיצרה את ה API Gateway).

הפקודה תחזיר לכם Integration ID ובו נשתמש כדי לחבר את האינטגרציה לנתיב ב API Gateway:

$ aws apigatewayv2 create-route --api-id v7ee0lwd52  --target "integrations/7emao03" --route-key 'ANY /'

שימו לב להחליף את ה Integration ID מהמזהה שלי (7emao03) לזה שאתם קיבלתם, וכמובן להחליף את ה API ID לזה שלכם.

ולסיום הפקודה הבאה יוצרת רכיב שנקרא Stage, שזה בעצם הסביבה, כלומר production, development, staging וכו. אני משתמש בשם $default כדי לדבר על סביבת ברירת המחדל שזה מה שמקבלים כשלא מציינים סביבה בבקשת הרשת:

$ aws apigatewayv2 create-stage --api-id v7ee0lwd52  --stage-name '$default' --auto-deploy

שימו לב לשנות את ה API ID לערך שלכם.

הפקודה הבאה והאחרונה פותחת את ההרשאות ומאפשרת ל API שיצרנו להפעיל את הפונקציה שיצרנו קודם:

$ aws lambda add-permission --function-name my-function \
      --statement-id apigateway-get --action lambda:InvokeFunction \
      --principal apigateway.amazonaws.com \
      --source-arn "arn:aws:execute-api:eu-west-3:123456789123:v7ee0lwd52/*/*/"

וכאן זיכרו להחליף את ה Region, את מזהה חשבון אמזון ואת ה API ID.

אם הכל הלך כמו שצריך תוכלו לגלוש לנתיב שמתאים ל API שיצרתם, כלומר ל:

https://v7ee0lwd52.execute-api.eu-west-3.amazonaws.com

וכן אל תשכחו להחליף את ה API ID בזה שלכם, ולקבל אוביקט JSON שיגיד לכם Hello World.

4. מחשבות להמשך

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

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

בעבודה בסביבת Micro Services היכרות עם הכלים של AWS ושימוש בהם במקומות הנכונים יעזרו לכם לכתוב מערכות מהר יותר ולהתמודד טוב עם Scale משתנה.