פרויקט DevOps: התוכנית
בפרויקט הזה בונים delivery pipeline ל‑web API קטן:
- CRUD API ב‑Python, ב‑GitHub repository משלו;
- pipeline של GitHub Actions:
- push ל‑branch שלכם מריץ את ה‑tests המהירים;
- pull request מריץ יותר: integration tests, וכלי אבטחה ובחינת קוד;
- pull request מחכה למאשר לפני שאפשר לעשות לו merge;
- merge ל‑
mainבונה container image ומעלה אותו;
- deployment ב‑AWS: EKS cluster, או קבוצת EC2 instances.
ה‑pipeline המוגמר בפעולה, אירוע אחר אירוע: The Pipeline, Step by Step (באנגלית).
המסלולים
בחרו אחד מכל זוג בתחילת הדרך, ועקבו רק אחרי הצעדים שלו.
ה‑framework של ה‑API
- Flask: המסלול הבסיסי.
- כל request מריץ function רגילה, מההתחלה ועד הסוף, ב‑worker משלו.
- מספיק Python רגיל.
- FastAPI: המסלול המתקדם.
- הוא בודק כל request מול types מוצהרים, ומייצר מהם דף OpenAPI.
- הוא בנוי על
asyncio: route יכול להיותasync def, שרץ על ה‑event loop היחיד של השרת.awaitמעביר את ה‑loop ל‑request אחר בזמן שה‑request הזה מחכה.- קריאה חוסמת בתוך
async def(time.sleep, או driver סינכרוני ל‑database) עוצרת את כל ה‑requests.
- בחרו בו אם אתם מכירים
async/awaitואת ה‑event loop, או רוצים ללמוד אותם בדרך.
היעד של ה‑deployment
- EKS: המסלול הראשי.
- Kubernetes cluster: ה‑deployment הוא Deployment ו‑Service, כמו שרוב הצוותים מעלים containers.
- הוא עולה כסף מהרגע שהוא קיים, בין אם האפליקציה רצה ובין אם לא.
- אם יוצרים אותו בתחילת כל מפגש עבודה ומוחקים בסופו, הוא עולה בערך $13–$37 בסך הכול ל‑20–30 שעות בחודש, לאורך 2–4 חודשים: החישוב נמצא במשימה 5.
- אם משאירים אותו רץ, הוא עולה בערך $200 בחודש.
- EC2: קבוצת instances שמריצים את ה‑container, למי שמוצא את EKS קשה מדי.
- פחות חלקים ללמוד, ומשלמים רק על ה‑instances ועל ה‑load balancer.
- ה‑deploy הוא script שלכם, במקום ה‑rollouts וה‑health checks ש‑EKS נותן.
בשני היעדים האפליקציה רצה ב‑container.
עבודה לבד או בזוג
את הפרויקט עושים לבד, או שני סטודנטים שחולקים repository אחד. בחרו בתחילת הדרך.
- בשני המקרים, הדרך שבה שינויים מגיעים ל‑
mainמשתנה במשימה 3:- משימות 1–2: עושים push ישר ל‑
main. שום דבר עוד לא מגן עליו, וכך הכי קל לראות את ה‑pipeline הריק. - ממשימה 3 והלאה:
mainמוגן. כל שינוי נעשה ב‑branch משלו, דרך pull request, ועובר merge רק אחרי שה‑checks שלו עוברים והוא מאושר.
- משימות 1–2: עושים push ישר ל‑
- ההבדל הוא מי מאשר.
- בכל מקרה, כל branch נקרא לפי שיטת שמות אחת: ראו Topic branches.
לבד
- כל issue משויך אליכם, וכל branch הוא שלכם.
- המאשר הוא
pr-reviewer, ה‑GitHub App: הוא ממלא את מקומו של האדם השני.- הוא מאשר אחרי סבב אחד של בקשת שינויים, ולעולם לא קורא את הקוד.
- ה‑review הוא פורמליות; ה‑checks הם מה שעוצר שינוי שבור.
- AWS: החשבון שלכם.
בזוג
- repository אחד: סטודנט אחד יוצר אותו, ומוסיף את השני כ‑collaborator עם הרשאת write.
- כל משימה ביחד, ושני המסלולים משותפים: בוחרים Flask או FastAPI, ו‑EKS או EC2, פעם אחת לזוג.
- כל issue משויך לאחד מכם: מי שהוא משויך אליו הוא בעל ה‑branch שלו, כך ששניכם יודעים של מי כל branch.
- הסטודנט השני מאשר: GitHub לא מאפשר לכותב של pull request לאשר אותו.
- קראו את השינוי לפני שאתם מאשרים: זה ה‑review ש‑
pr-reviewerרק מחקה. - התחלפו: אחד כותב את השינוי של משימה, השני עושה לו review, ובמשימה הבאה מתחלפים.
pr-reviewerמותקן גם כאן במשימה 3, כך שה‑pipeline זהה לעבודה לבד; כל אחד מהאישורים מספיק ל‑merge.
- קראו את השינוי לפני שאתם מאשרים: זה ה‑review ש‑
- אחרי משימה 3, לעולם לא עושים push ישר ל‑
main, גם לא כדי לתקן טעות של השני: פותחים pull request. - חשבון AWS אחד, של בעל ה‑repository. ה‑pipeline עושה deploy עם ה‑role שלו, כך שהסטודנט השני צריך גישה ל‑console רק כדי להסתכל: TODO: IAM user עם הרשאת קריאה בלבד, או IAM Identity Center.
- מתחלקים בעלות של AWS: השעות של ה‑cluster הן השעות של הזוג, כך ש‑cluster אחד לא עולה יותר מאשר לבד.
Topic branches
כל שינוי מתחיל כ‑issue ב‑GitHub, וה‑branch שלו נקרא <type>/<issue>-<what>.
| חלק | מה הוא מכיל | דוגמה |
|---|---|---|
| type | feature להתנהגות חדשה של ה‑API, fix ל‑bug, ci ל‑pipeline: ה‑workflows, ה‑Dockerfile, התשתית | feature |
| issue | המספר של ה‑issue | 12 |
| what | כמה מילים, באותיות קטנות, מחוברות במקפים | search-books |
1$ git switch -c feature/12-search-books
2$ git push -u origin feature/12-search-books
- המספר מקשר את הכול: ה‑branch נושא את מספר ה‑issue, בתיאור של ה‑pull request כתוב
Closes #12, וה‑merge סוגר את ה‑issue. - ה‑type מקבץ את ה‑branches: רשימת ה‑branches של GitHub, והפילטר
branches:של workflow, יכולים לבחורfix/**. - המילים אומרות מה זה בלי לפתוח את ה‑issue.
- issue אחד, branch אחד, pull request אחד; ה‑branch נמחק אחרי ה‑merge.
ה‑pipeline המוגמר
The Pipeline, Step by Step מציג את כולו, אירוע אחר אירוע:
push ל‑topic branch, pull request דרך ה‑checks וה‑review שלו, ה‑merge וה‑delivery, ו‑push ל‑main שנדחה.
| אירוע | Jobs |
|---|---|
| push ל‑branch שלכם | lint, unit tests |
pull request ל‑main | lint, unit tests, integration tests, אבטחה ובחינת קוד, בניית image; ואחריהם ה‑review של המאשר |
merge ל‑main | בניית image ו‑push, deploy, smoke test |
סדר המשימות
המשימות בונות קודם את כל ה‑pipeline, ואז ממלאות אותו.
- משימות 1–3: ה‑pipeline, ריק.
- כל job קיים ממשימה 2, כ‑placeholder שמדפיס מה הוא יעשה.
- רואים כל אירוע מריץ את ה‑jobs שלו, ואת המאשר עוצר את ה‑merge, לפני שאיזשהו job עושה עבודה אמיתית.
- משימות 4–6: הפתרון השלם הראשון.
- ה‑placeholders של ה‑image ושל ה‑deployment נעשים אמיתיים.
- merge ל‑
mainמעלה את האפליקציה ל‑AWS.
- משימות 7–10: הפרטים.
- כל משימה מחליפה עוד placeholders, או מחמירה job שכבר עובד.
לפני שמתחילים
- חשבון GitHub.
- חשבון AWS, ממשימה 5. התשתית עולה כסף כל זמן שהיא רצה; משימה 11 מסירה אותה.
- חשבון Docker Hub, ממשימה 4.
- Python 3.12 ומעלה, Docker ו‑git על המחשב שלכם.
החומרים האחרים באתר שמשמשים בדרך (באנגלית):
- GitHub Actions Workflows: an Introduction
- Pipeline Identities: ה‑credentials שה‑pipeline משתמש בהם
- Git Collaboration: pull requests, review ו‑branch protection