אז… אתם רוצים Continuous Deployment? (חלק ג’)

בפוסט הקודם בסדרה דיברנו על Continuous Delivery (בקיצור CD), על ה Deployment Pipeline, ופרקטיקות נוספות.בפוסט הזה אני רוצה להתמקד ולהשלים את הסקירה של Continuous Deployment (לצורך הפוסט: CDD), ולדבר על הטמעה של הפרקטיקות הללו – בארגון שעדיין לא נמצא שם.

תנו לי CDD – ועכשיו!

Continuous Deployment הוא הרעיון שהפער בין קוד המערכת לסביבת הפרדוקשיין יהיה מינימלי – דקות עד שעות ספורות לכל היותר.

שאלה בוודאי שאתם שואלים את עצמם, לאחר הבנת התהליכים של CD – היא מהו הפער ליישום CDD?

הנה תיאור ה Deployment pipeline שהשתמשנו בו בפוסט הקודם:

בסביבת האינטגרציה יש הזדמנות למפתחים ו/או אנשי ה QA לבצע בדיקות ידניות על קוד – לפני שהוא הולך לפרודקשיין. לאחר שיש לנו אוטומציה מספיק טובה, האם לא טבעי שנפסיק עם התהליך הידני – ופשוט “נפתח את הברז” כך שכל שינוי יזרום ישר לפרודקשיין (לאחר שעבר את כל הבדיקות האוטומטיות)?

יש לכך כמה קשיים עיקריים:

המעבר מביטחון של 95% באוטומציה לביטחון של 100% באוטומציה – אינו קטן!

שמעתי הרצאה של קבוצה בגוגל שלאורך 18 חודשים (שנה וחצי) ניסתה לעבור מ CD ל CDD – ועדיין לא הצליחה. עדיין כ 1% מה commits היו בעייתיים למרות שעברו את הבדיקות, ותהליך השחרור אצלם נותר ידני. כלומר: מפתח מבצע החלטה בכדי להעביר commit לפרודקשיין.
כותרת ההרצאה הייתה אודות “Continuous Deployment” – למרות שלא עמדו בתנאי הרשמי הזה (בסדר מבחינתי!). קצת הופתעתי שהדבר הטריד אותם ונראה שהיה חשוב להצהיר שתוך כמה חודשים הם חושבים שכבר יוכלו לעשות שחרור אוטומטי לחלוטין.

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

עם הזמן מספר ה commit ילך ויגדל

אולי כי הארגון גדל, ואולי כי המפתחים באמת השתפרו בתהליך ה CI?
כמות ה commits בשעה תלך ותגדל: 1 בשעה, 2 בשעה, אח”כ 5 בשעה, וכו’.

כבר באזור שלושה-ארבעה ה commits בשעה – תהיה בעיה: תהליך ה deploy אורך כ 30 דקות.
מה עושים? נותנים לתור ה commits להצטבר? להיכנס לשעות העומס של המערכת או שעות הלילה? אולי לגלוש למחר?
אולי פשוט נאחד כמה commits ונעשה להם deploy ביחד?
אולי נשקיע מאמץ במיקבול טוב יותר של תהליכי ה deploy?

הבעיה הזו כנראה לא הולכת להיעלם, במיוחד אם אתם ארגון בצמיחה. גם אם תמקבלו את התהליך, את שלב ה deploy עצמו (blue/green או rolling) ואז צפייה בשינויים בסביבה בעקבות ה deploy – תהליך שאורך 10 דקות לפחות, כנראה ולא תוכלו ממש למקבל.

הפתרון המקובל הוא אימוץ של Microservices Architectures. הרבה repositories שונים של קוד, שעוברים deploy לשרתים שונים – מאפשרים מקביליות. כאשר יותר שורות קוד –> יותר שירותים (תנאי של Microservices Architecture) – המקבילות היא, תיאורטית, אינסופית.

Database migration

אם אתם עובדים עם RDBMS אזי המיגרציות:

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

הפתרונות המקובלים הוא לעבור לפתרונות בהם כמעט ולא צריך מיגרציה: Document Databases על פני Relational Databases, או Databases שבהם המיגרציה היא נוחה יותר (למשל PostgreSQL על פני MySQL).

כאשר יש מיקרו-שירותים, המיגרציה כבר לא כ”כ מפריעה: שירות אחד יכול להיות “תקוע”* על מיגרציה למשך 4 שעות – שאר המערכת ממשיכה להתעדכן כרגיל, וללא הפרעה.

* “תקוע” הכוונה שהשירות עובד – פשוט אי אפשר לבצע עוד deploys בזמן הזה.

אז למה באמת ארגונים בוחרים ב CDD?!

(אני קצת חוזר על הנאמר בפוסט הראשון)
הרעיון של Continuous Deployment קיבל תנופה גדולה מתנועת ה Lean Startup, שם צמצום מחזורי הלמידה והפידבק הם ערך מרכזי. הדרישה ל CDD, ע״פ המתודולוגיה, אמורה להגיע כיעד עסקי מה CEO – זה לא עניין ״פנימי״ של ה R&D…

במקום להיות ״נביאים״, או ״יודעי-כל״, תהליך ה CDD מאפשר לנו לנסות בשטח.
הפיצ’ר של אמזון של “אנשים שקנו את X קנו גם את Y”, נדחה ע”י אנשי המוצר כ”מטופש” – ובארגון אחר היה נקבר לעד.

התרבות הארגונית של אמזון, שגובתה בעזרת יכולות CDD, אפשרה למפתח שמאוד מאמין במשהו לבצע A/B test (על אוכלוסיה קטנה) – ולנסות להוכיח את צדקתו. כל אחד כמעט – יכול להציע ולהתניע ניסוי.
הניסוי הנ״ל הראה גידול של כ 3% במכירות (נתון מרשים מאוד!) – מה שהסיר מייד כל התנגדות, והפך אותו בן רגע לפיצ׳ר רצוי ע”י הפרודקט.

אם כולם מאמינים במערכת ובנתונים שהיא מייצרת, אזי נתונים מהשטח הם ״מחסלי ויכוחים ארגוניים״.

CDD, אם כן, בשילוב A/B Tests ותרבות ארגונית מתאימה – מספקת Empowerment לעובדים, ויכולה להביא רעיונות חכמים שלהם – לידי יישום.

מקור: Ash Maurya

ישנן עדויות ליתרונות נוספים הנובעים מאימוץ CDD:

  • ע”פ עדות של אינסטגרם ששמעתי – המעבר ל CDD שיפר את מהירות הפיתוח בכך שצמצם הסתבכויות של מפתחים: פחות ספקולציות (“אולי הקוד לא היה מספיק מהיר וכדאי לייעל פה קצת?”) ויותר חיבור למעשיות בשטח.
  • בגלל שעושים deploy לכל commit באופן נפרד – קל יותר לזהות commits בעייתיים, לתקן אותם, וכך להגביר את הלמידה של המהנדסים. היתרון ההדרגתי בלמידה – מצטבר ליתרון של מהנדסים טובים יותר.
  • שביעת הרצון של המפתחים גבוהה יותר, הן בשל שהם עושים משהו שרבים מנסים – אף רק חלק קטן מהתעשייה הגיע אליו בפועל, ואם בגלל שזו באמת סביבת עבודה מתגמלת יותר (רגשית) עבור המפתחים.

שימו לב: ככל הידוע לי לפחות, אין נתונים ממשיים שתומכים בטענות הללו. האם מדובר בדיסוננס קוגניטיבי בו מי שהשקיע מאמץ רב כ”כ בהגעה ל CDD בפועל – מנסה להצדיק את ההשקעה הזו בדיעבד? – אני לא יודע לומר.

אך איך מיישמים CD/CDD בארגון שעדיין לא שם?

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

נתחיל בגישות העיקריות, הנוגעות לארגונים שרק מתחילים בתהליך האימוץ:

גישה: AquaSlump

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

בעצם יש פה פרויקט שצריך להריץ:

  • שלב א’ – משקיעים בתשתיות build – חשוב מאוד לוודא שמהכנסה של קוד עד להגעה לפרודקשיין הכל הוא 100% אוטומטי.
  • שלב ב’ – בונים סביבת staging יציבה לאוטומציה. יש פה עניין של הקמת סביבות בצורה אוטומטית ומהירה – זהה לפרודקשיין, הבאת נתונים אמיתיים מפרודשיין, וכתיבת בדיקות End-to-End שיכסו אותנו בצורה טובה ויספקו אמינות שהקוד שאנחנו משחררים הלאה ב pipeline הוא באמת תקין.
  • שלב ג’ – מביאים את כל חלקי המערכת לרף הבדיקות שנקבע: למשל 85% Code Coverage.
  • שלב ד’ – מתחילים לאפשר לצוותים לשחרר קוד לפרודקשיין, אזור אחר אזור.
למי שלא הבין עדיין, ה AquaSlump היא מילה נרדפת ל WaterFall – יש עוד מאמינים גדולים בעקרונות ה Waterfall (בעיקר בארגונים גדולים), אך נראה שכולם הפסיקו להשתמש במונח ה”מביך” הזה.
אם תתקלו ב Waterfall ב CD (או בכלל) – סביר יותר שתתקלו בו עוטה שם אחר. אל תתנו לשם השונה לבלבל אתכם!
“משהו כמו CI/CD אי אפשר לעשות בלי תכנון מסודר ומרכזי” – הוא טיעון ששמעתי לא פעם…
בכל זאת, אם ייקח חצי שנה לפי התוכנית (ואולי שנה+ בפועל?) לראות Deploy מתרחש מקצה לקצה וללמוד מה עובד, מה לא עובד, ואיפה הכאבים הספציפיים של הארגון שלנו – אז זה פשוט לא אג’ילי ולא יעיל.
הסתייגות קלה: אם עשיתם פעולה בהצלחה כבר כמה פעמים, למשל: מעבר ל CI/CD – אז ייתכן ובאמת יעיל לקחת גישה יותר Waterfall-ית שמתמקדת ב Efficiency ולא בלמידה. אתם כבר יודעים כנראה לא מעט. אני מדבר ידע מוכח (ולא משהו כמו ContinuousIntegrationCertification)
CI/CD/CDD Maturity Model – מודל אידאלי ואוניברסילי ליישום השיטה. תורת הצורות/האידאות של אפלטון בהתגלמותה! מקור
גישה: Guerilla Transformationחבר שעבד בסטארט-אפ ישראלי קטן סיפר לי שהם עשו בזמנו 5 וגם 10 deploys ביום. בלי בדיקות יחידה, בלי אוטומציה, בלי “מערכת CI”. פשוט קימפלו – וזרקו לפרודקשיין. שהיו בעיות – תיקנו בזריזות.

ע”פ מודל ה Maturity למעלה, או רבים אחרים דומים – התנהלות שכזו לא נמצאת בכלל על הסקאלה!

בכל הפרמטרים החבר’ה האלה היו מתחת לשלב הבסיס הראשוני (קרי: 1-). בתכונה אחת, שלא מוגדרת ברוב המודלים הללו כיישות עצמאית: “כמות ה deploys ביום לפרודקשיין / ביחס למספר המפתחים” – הם היו בדרגה הגבוהה ביותר (קרי: 5).

מה זה אומר? שהם חוראניים (קרי: רשלניים)? לא מקצועיים? חסרי עתיד ללא ניהול צמוד? ממזרים חסרי כבוד?
זו כנראה גישה שלא הייתה מחזיקה לאורך זמן וצוות גדול יותר (היו להם פחות מ 10 מפתחים).
זו גישה מסוכנת שדורשת הרבה אחריות אישית, וכנראה לא מאפשרת סביבת production נקייה מאוד מבאגים.

אבל זה יותר CD/CDD ממה שארגונים מגיעים אליהם אחרי חודשים של עבודה קשה, בגישת ה AquaSlump.

ג’ז האמבל (המחבר של ספר ה CD המפורסם) מציע ששני המדדים העיקריים לאימוץ של CD יהיו:

  • כמה commits ל master ביום / ביחס למספר המפתחים.
  • כמה זמן אורך מרגע שיש רעיון – ועד שהוא מגיע לפרודקשיין (קרי: lead time).

בגישת הגרילה מתמקדים במדדים הללו – עד הסוף.
קודם הולכים ומתחילים לעשות Deploys תכופים לפרודקשיין – ואז מתחילים לשפר את התהליך.

המגע המהיר והתכוף עם פרודקשיין הוא בעיקר מלמד: דבר ראשון לומדים שזה לא כ”כ נורא. ושאפשר להוציא כמה וכמה עדכונים לפרודקשיין – בלי להרוס אותו. שתקלות – אפשר לתקן לעתים רבות בזריזות. למשל: הלמידה שהפחד משינויים בפרודקשיין הוא קצת מוגזם (זה בד”כ המצב) – היא כבר למידה חשובה!
בשלב הבא מתחילים להבין:

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

בשלב הבא, כשמעט מתבגרים – אלו כנראה הדברים שתרצו להתמקד בהם:

  • בדיקות אוטומטיות מהירות, עם כיסוי סביר.
  • תהליך של canary release.
  • בדיקות post-deployment ויכולת ל rollback מהירה.
  • יצירת אווירה שבה טוב ונוח למפתחים לעשות הרבה deploys ביום.

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

חוויתי כמה וכמה מאמצים אדירים בגישת ה AquaSlump – שלא הגיעו לתוצאות משמעותיות (אולי החבר’ה שם עדיין מנסים…?!) וחוויתי פעם אחת את הגישה הרזה – שסיפקה תוצאות יפות בזמן קצר. דעתי בנושא – התגבשה.

כמה בעיות של CDD שאולי לא חשבתם עליהן בתוכנית ה AquaSlump שלכם…


“פקקים” ב Deployment Pipeline

במהלך השעה האחרונה נכנסו לי סדרה של ארבעה commits לשירות מסוים: A, B, C, ו D.
commit A – עבר deployment בהצלחה.
commit B – נכשל.
האם אפשר לקחת את commits C +D לפקודקשיין בצורה אוטומטית? חבל לבזבז זמן!
איך יודעים האם הם תלויים ב commit B או לא?

הבעיה איננה בעיה לוגית כ”כ גדולה: בד”כ אפשר לבצע merge אוטומטי של commit C על גבי commit A וללא commit B – ואז להעביר את השינוי ב pipeline. מה שנקרא “commit selection” או “מי הבא בתור?”. אבל זה עדיין תהליך, הדורש עבודה וליטוש.

זיהוי בעיות ב UI

בעוד בדיקות אוטומציה הן טובות מאוד לקוד לוגי – קשה הרבה יותר לבדוק UI בצורה אוטומטית ומלאה.

יש סיפור של גוגל איך מתכנת הוסיף לאחד המוצרים אנימציה של unicorn מרקד כאינדיקציה לכך שאיזה Feature Flag, של פיצ’ר שעליו הם עבדו – הוא מודלק.
תהליך ה deploy עבר בהצלחה. המתכנת נכנס לפרודקשיין עם החשבון שלו – וראה את ה unicorn מרקד והכל נראה בסדר!

הוא שכח לבדוק, מה קורה עם משתמש שאינו ברשימת ה beta users של הפיצ’ר. מסתבר שכל משתמשי המוצר (מיליונים!) ראו את ה unicorn המרקד הזה – גם אם הפיצ’ר לא הופעל עבורם.

כיצד מאתרים בעיות מסוג זה? אולי כפתור שזז למקום מוזר? או טקסט שהפך לקטן? – כשהשינויים קטנים, “יקר” לבצע בדיקה ידנית של ה UI על כל deploy (שזה בעצם: commit קטן).

במוצר הספציפי הוסיפו ל pipeline שכבה של בדיקות אוטומציה שעונות “באיזה מסכים היה שינוי בUI, לכלל המשתמשים, בעקבות ה commit”. הבדיקות היו מבוססות בעיקר על צילום והשוואת screenshots של המוצר. אם היה שינוי שכזה (שמתגלה ב staging), המפתח צריך לאשר שהשינוי תקין, בכדי שהקוד יגיע לפרודקשיין.

שוב – אין פה rocket science, אך יש פה צורך ספציפי למוצר – שניתן להבין וללמוד אותו רק בעקבות “התנסות בשטח”.

תלויות בין מיקרו-שירותים

נניח שיש לי פיצ’ר בשירות X שדורש API מתאים בשירות Y?
זה נשמע אתגר קטן: נגדיר את התלויות. סגור!

בפועל: מצב ה pipeline של כל שירות הוא דינאמי – ולכן קשה לתכנון. בכל רגע נתון יכולים להיות לפני ה commit שלי מספר commits שמחכים להרצה ב pipeline. כיצד אם מוודאים שהשינוי ב API (שירות Y) יהיה זמן בפרודקשיין, לפני שהקוד בשירות X “נוחת” בפרודקשיין בעצמו? אם יש שלושה commits בתור בשירות Y, אך אין תור כלל בשירות X?

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

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

קצרים

רעיונות אחרונים בנושא שארצה להוסיף לגבי יישום של CD/CDD:

  • פגישת Slow Deployment Retrospective – לא משנה השם, אבל אם לא תדאגו לשפר כל הזמן את תהליך ה deploy שלכם – הוא הולך להיות אטי ומסורבל עם הזמן. במיוחד כאשר המוצר והחברה בשלבי גדילה.
  • ב Lean Startup (ממנו הגיע ה CDD) ה Definition of Done של פיצר הוא “הפיצ’ר ייצר את האימפקט המצופה בפרודקשיין”. לא סוגרים “טיקט” עד שלא מגיעים לשם, כלומר: עושים עוד ועוד איטרציות על הפיצ’ר עד שהאיפקט מושג. לסירוגין: אפשר להחליט שהפיצ’ר פשוט לא שווה את ההשקעה המסתמנת.
    • ב CDD מן הראוי, לא לסגור טיקט של פיצ’ר לפחות עד שלא רואים אותו בפרודקשיין. שינוי קטן ב Jira – ושינוי קצת יותר גדול ב mindset.
  • תזכורת: כמו ב CD – בעיות פרודקשיין ובעיות ב Deployment pipeline מטפלות בדחיפות הגבוהה ביותר בארגון! הזנחה של הכלל הזה – היא דרך מצוינת להכשיל יישום CD/CDD.
  • Hello Prod (על משקל “Hello World”) – כאשר מפתחים שירות חדש, דבר ראשון שלחו את ה template של שירות חדש (להלן “Hello Prod”) לפרודקשיין – ועליו תתחילו לפתח. בפרודקשיין. אל תחכו שבוע או שבועיים עם קוד בצד לפני שראיתם פרודקשיין. מייד!
    • זה תרגיל מצויין כדי להתחיל לתרגל CDD, גם אם אתם ממש בתחילת התהליך.
  • שאיפה של מוצר CDD הוא שעם הזמן (וגדילת מספר העובדים), קצב השחרורים לפרודשיין /יחסית למספר המפתחים – רק יגדל!
    • לרוב הוא יקטן, אבל תרצו שגם אם הוא קטן – שיקטן לאט ככל האפשר.

סיכום

CD ו CDD מרגישים ממש קרובים – אבל הם לא.
אם ב CD שיגרנו חללית לחלל, מיד גילינו שיש לנו עוד עבודה לגרום לה להשתחרר מהכבידה של כדור הארץ (להלן CDD). לא מאמץ קטן!

אני רוצה להתוודות שכאשר התחלתי את הפוסט… עוד דיקלמתי לעצמי: “אם יש לכם מוצר SaaS – חבל לעצור ב CD. לכו על CDD!”
במהלך כתיבת הפוסט, נוכחתי בעצמי שוב – עד כמה זה לא-פשוט!

ולכן אתקן: אני ממליץ לכל מוצר SaaS להגיע ל 90% CDD. שיהיו הרבה deploys ביום / ביחד למספר המתכנתים. יותר deploys ביום ממפתחים – לפחות.
אם יש מוצר SaaS ואתם משחררים לפרודקשיין רק פעם בשבוע או שבועיים – זה מרגיש פספוס.

אם תבחרו בגישת הגרילה – זה גם לא יהיה כ”כ קשה. מפתיע כמה זה קל!

שיהיה בהצלחה!

נ.ב. – יש!! סיימתי סדרת-פוסטים!

אז… אתם רוצים Continuous Deployment? (חלק ב’)

בפוסט הקודם דיברנו על המוטיבציה ל CI/CD/CDD, על הציפיות והסיבות לאמץ את המתודולוגיות הללו, ותיארנו בפירוט מהו CI (הרעיון מעט שונה ממה שמקובל לחשוב).בפוסט זה ארצה לפרט יותר על CD – ואולי גם כאן הרעיונות נבלעו תחת תפיסה פופולארית פשטנית.

Continuous Delivery (בקיצור: CD)

זהו הרעיון שקוד המערכת יהיה כל הזמן במצב ניתן לדילוור (“shippable state“).

המונח CD התחיל להיות נפוץ בעקבות הספר הפופלארי של ג’ז האמבל ודייויד פארלי (למעלה באמצע).
המחברים לא המציאו את הרעיונות, אלא נתנו תוקף ומסגרת לתהליכים שהיו בשימוש ע”י חברות כמו Yahoo, אמזון, פייסבוק, גוגל, ועוד.

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

רבים בתעשייה הכריזו על עצמם כמיישמי CI – גם כאשר היישום לא היה יותר מ Build Server (או “CI Server”) שמבצע Build בצורה תדירה. האינטגרציה עדיין נותרה אירוע של סוף ספרינט או רחוק מכך.
האם זו בורות, או פשוט גיוס של עוד מונח מקצועי לשיפור את המוטיבציה של העובדים (“תראו אותנו, אנחנו עושים CI, איזה מעולים!!”)? – קשה לי לומר.

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

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

הצעד החשוב השני שתנועת ה CD עשתה היא להרחיב את מעגל האיטרציות ה SCRUM-י.
יישום נפוץ של סקראם (או מתודולוגיות אג’ייל דומות) בארגונים היה שצוותי הפיתוח עבדו באיטרציות קצרות – אך השלבים בתהליך שלפני הפיתוח (תכנון / אפיון מוצר) והשלבים שבאים אחריהם (בדיקות ו Release) – נותרו תהליכים ארוכים ולא גמישים.

ג’ז האמבל קרא למצב הזה Water-SCRUM-Fall, והוא מתואר בתרשים הבא:

מקור: ג’ז האמבל – http://www.slideshare.net/jezhumble/21-century-software

מי לא מכיר את המצב הזה? אני מניח שרובנו…

CD בה להרחיב את תחומי ה SCRUM (ליתר דיוק: האיטרציות הקצרות והתכופות) בארגון, ולכלול בתוכן את ה QA וה Release  מצד אחד, אך גם תכנון המוצר – מצד שני.

DevOps Culture – הוא אחד הרעיונות שצצו משם וקיבלו תשומת-לב מיוחדת. הרעיון שבמקום שיהיה “קיר” בין פיתוח ו Operations: פיתוח מייצרים משהו ו”זורקים” ל Operations להתקין בפרודקשיין – הקבוצות ישתלבו זו בזו.
במקום שיהיה ביניהם ניגוד אינטרסים מובנה (פיתוח לחוץ לפתח עוד פיצ’רים, Operations “אחראים” על יציבות המערכת ורוצים כמה שפחות שינויים) – הם עובדים בשיתוף פעולה, יד-ביד, למען מטרה משותפת.
האחריות למה שקורה בפרודקשיין – היא משותפת.

רבים בתעשייה לא הבינו את המסר בצורה נכונה: הם שינו את שם התפקיד מ “אנשי Operations” ל “אנשי DevOps” – והמשיכו בשכנוע-עצמי (או אולי: שכנוע-האחר) שהם התקדמו בצד משמעותי ליישום CD, או בכלל ברמה התהליכית…
זכרו: DevOps זה לא תפקיד – זוהי תרבות.

הספר Continuous Delivery יצא ב 2010, עוד לפני עידן ה SaaS. כלומר: לפני ש SaaS היה הצורה המקובלת לדלוור תוכנה. הספר מדבר בעיקר על Packaged Software – כזו שהלקוח מוריד את קובצי ההתקנה ומתקין בעצמו.

Case Study שג’ז האמבל אוהב להזכיר הוא הטמעת CD במחלקת המדפסות של חברת HP – כיצד לבצע CD ל firmware (הקוד שרץ בתוך המדפסת). זו דוגמה טובה לקוד שניתן לבנות אותו כל יום – אך עדכונים ישוחררו ללקוחות רק אחת לכמה חודשים (או אפילו פחות מכך).

יישום CD בצד הרעיוני

מדד-מפתח באימוץ של CD בארגון הוא ה Lead Time, אותו יש לשפר כל הזמן:

הזמן מרגע שאיש Product ביקש פיצ’ר, או מהזמן שנפתח באג – ועד שהוא מוכן וארוז לשימוש. ארוז (“Shippable”) הכוונה שיש לנו את קובצי ההתקנה של המערכת, והם שמישים, בדוקים, ובאיכות טובה.

ההתמקדות ב Lead Time מספקת אופטימיזציה בארגון לתהליכים רבים: תקשורת, תעדוף, Build מהיר, handover ל QA, ותהליכי בדיקות אוטומטיים, ועוד. אם היינו מתמקדים רק ב Process Time, או רק בחלק הפיתוחי של ה Process Time – אולי הפיתוח היה עובד מהר יותר, אבל הפיצ’ר עדיין היה “תקוע”:
“הפיצ’ר מוכן, אבל הוא עדיין מחכה רק ל QA/התקנה” או “אנחנו מוכנים להתחיל, אבל מחכים ל Product/עיצוב” – הוא תירוץ שמתכנתים מרגישים נוח איתו, אך הוא לא מספק את צורכי הביזנס.

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

עוד הבחנה ש CD מתמקד בה היא שהזמן שמושקע בפיתוח מתחלק לחלק נראה, ולבתי-נראה:

כשאנחנו עסוקים כמעט כולנו בפיתוח פיצ’רים, ולא מקדישים זמן לפיתוח הארכיטקטורה ותהליך ה CD שלנו – הזמן הישיר והעקיף שהולך ל Negative Value הולך וצומח – עד שאנחנו כמעט ונעצרים מהיכולת לפתח ערך חיובי.

Technical Debt, כפי שאנו יודעים, זהו סיבוך בקוד, שינויים חשובים ב Design שנדחו, קיצורי דרך לא אלגנטיים – כל אלה גורמים להכנסת כל קוד חדש / שינויי קוד להיות קשים וארוכים יותר. מן “מס בלתי נראה”.

“בלתי נראה”? המפתח שעובד על שינויי הקוד מרגיש אותו היטב, אך קשה לשקף אותו לשאר הארגון.

הנה השיפורים שהושגו, בחניכה של ג’ז האמבל במחלקת ה Firmware (מדפסות) של HP:

האם CD מציע לנו עולם שבו 80% מהזמן מוקדש לכתיבת קוד חדש ופיצ’רים? – לא ולא. יש הרבה עבודת אוטומציה ואחזקה. אבל, במקרה הנ”ל הצליחו להגדיל פי 8* – את הזמן שגוף הפיתוח משקיע בפיתוחים חדשים (“Innovation”).
ההערה למטה בלבן מסבירה ש 23% מהזמן של הל המפתחים הושקע בכתיבת אוטומציה. כמעט חצי מהזמן שהושקע בכתיבת קוד שנותן ערך לללקוח.

* טוב, זהו Case Study, ויש כל אינטרס להציג את התמונה בצורה אופטימית ככל האפשר. בואו נניח ששיפרו את הזמן שמושקע בקוד חדש – רק פי 4-5 בפועל.

יישום CD בצד הטכני

המפתח ליישום CD מההיבט הטכני הוא בניית ה Deployment Pipeline – הצינור בו מעבירים קוד ממערכת ה Source Control – לפרודקשיין.

כל שינוי ב Source Control מפעיל Trigger שגורם לבנייה של תוצר הקומפליציה. במקרה של פיתוח בענן (נניח AWS) – מדובר כנראה בבניה של ה AMI (קרי Amazon Machine Image) או Container, ממנו ניתן “להרים” מכונה בפרודקשיין בפקודה פשוטה. בשל הפופולאריות של Containers, אתייחס אליהם – אם כי ב Gett אני רגיל ביום-יום לעבוד עם AMIs.

נניח שאנו עובדים ב Github ויש לנו branch בשם master עליו מפתחים, ו branch בשם release שמתאר את מה שרץ בפרודקשיין.
חשוב להדגיש: הכוונה היא לא שנבצע merge ל release פעם בשבוע-שבועיים (או לסירוגין: בסוף ה Sprint) ואז יבנה ה Container. זה יהיה Automated Delivery – ולא Continuous Delivery!
הכוונה היא שבכל שינוי ב master (ואם יש כמה כאלה בטווח של דקה, אז אחת לכמה דקות) – ייבנה Container, הוא יופעל בסביבת ה Staging – ועליו המפתחים וה QA יבדקו את הקוד. סביבת ה Staging אמור לשקף את מצב הפיתוח הרגעי, כך שברגע שאנו מתכננים להשיק (“Ship”) – יש לנו קוד במצב טוב.

“אבל זה לא יעבוד! סביבת ה Staging תהיה עם פונקציונליות שבורה כל הזמן – והמפתחים וה QA לא יוכלו לעבוד!”

זו הנקודה בה CD מסתמך על יישום של CI:
עלינו להוכיח שהקוד אכן מוכן לדילוור באיכות הרצויה, ועל כן אנו מעבירים אותו בסדרה של “מבחנים” – אלו הן התחנות השונות ב Deployment Pipeline. ככל שמבחן הוא מהיר יותר להרצה – הוא יהיה במיקום מוקדם יותר ב Deployment Pipeline. כלל שמבחן הוא יעיל יותר (סביר יותר שיתפוס בעיות) – הוא יהיה גם כן מוקדם יותר ב Deployment Pipeline.
כלומר: אנו מתחילים עם מבחנים זולים (= מהירים) ובעלי סיכוי גבוה לתפוס תקלות, למשל “Smoke Test” (= “מדליקים את המכשיר ורואים שלא יוצא עשן”), וככל שמתקדמים מגיעים למבחנים יקרים (= אטיים) יותר, ושבודקים יותר מקרי-קצה.

עדיין חשוב מאוד הכלל שאומר: שמירת ה Pipeline עובד היא בעדיפות עליונה. על הארגון לעזוב הכל ולטפל ב Pipeline שבור – ממש כמו שמטפלים ב Production.

זכרו: הטיפול ב Deployment Pipeline הוא משני בדחיפות רק ל Production.

התהליך שב Pipeline רץ כל הזמן, סביבות הבדיקות השונות אמורות לעבוד מסביב לשעון, לאורך כל הספרינט – ולא רק בסוף הספרינט (זו המשמעות של Continuous). ונכון: יהיו כמה גרסאות של שירותים במערכת (אני מניח שיש לכם Microservices) – וחלקן לא יגיע ל Production (אם בשל תקלה בבדיקות, או בשל כך שגרסה מתקדמת יותר “עקפה” אותה והגיעה ל Production לפניה).

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

נקודות חשובות:

  • את ה Isolated Testing Environment – מרימים לכל Service לדקות בודדות של בדיקה. לא אכפת לנו להפעיל כמה וכמה כאלו במקביל. וירטואליזציה או קונטיינריזציה – היא פלטפורמת ההרצה הטבעית לסביבה הזו.
  • ה Integration Environment היא סביבה יחידה – בה ניתן לראות את התנהגות כל השירותים במצב ה dev שלהם ביחד.
    • ה Integration Environment דומה ככל האפשר לפרודשיין:
      • התקנה מבוצעת באותו האופן: clusters, מכונות נפרדות, DB נפרדים, קונפיגורציה – כמו בפרודקשין.
      • ה Data מגיע מפרודקשיין, אך עובר ניקוי למידע פרטי (שלא צריך להיות נגיש לעובדים), או מיותר (למשל: טבלאות audit גדולות).
    • לכאורה זו סביבה שעלולה להיות מאוד לא יציבה (גרסאות שונות ומשונות רצות ביחד), אבל עם התבגרות ה pipeline היציבות שלה אמורה להשתפר משמעותית:
      • קוד מגיע אליה לאחר שעבר כבר סבב בדיקות.
      • תאימות לאחור היא תנאי מחייב.
      • עדיף מאוד לבצע deploy ב immutable deployment (על מכונה “נקייה” ולא “מלוכלכת”) – containers או AMIs מאוד עוזרים כאן. אחרת – חשוב מנגנון reset לסביבה, והוא כנראה יופעל מפעם לפעם.
      • כאשר יש התנגשות בין שירותים – אפשר להחזיר אחד השירותים לגרסה קודמת, אבל השאיפה היא להציע מהיר תיקון ולהתקדם קדימה. Rollback הוא פשרה.
  • ה Staging Environment מאפשרת לבצע בדיקות אינטגרציה בין שירות נתון – למצב שיש כרגע בפרודקשיין.
    • לא נדיר להגיע לסט בדיקות שהרצת כל הבדיקות שבו אורך שעות רבות (ראיתי גם יממה ויותר) – ועל כן לא מריצים את כל הבדיקות. חשוב לדעת לכל שירות איזה subset של הבדיקות הוא מספיק טוב. כלל אצבע שאני מכיר הוא לחתור ללא יותר מ 10 דקות של בדיקות. כלומר: ייתכן וסך כל הבדיקות אורכות שעתיים או שלוש (כי אנו מקפידים על שיפורי הזמנים: מסירים בדיקות לא יעילות, ועובדים לקצר בדיקות ארוכות) – אך אנו יודעים לסמן לכל שירות איזה סט של בדיקות שנכנס ב-10 דקות הוא ה 80/20.
      • לפני שינויים רגישים במערכת – אפשר לסמן ל pipeline להריץ את הסט המלא של הבדיקות. שייקח שלוש שעות. אני מדבר על אירוע שאמור לקרות פעם בחודש בערך. אם השינויים שאנו מבצעים בקוד הם קטנים – אז הם לא כ”כ מסוכנים.
    • סביבת Staging יחידה תיצור, מן הסתם, תור ארוך ב pipeline – כי מפתחים רוצים להכניס שינויים כל הזמן. בכדי להשיג מקביליות של עבודה – יהיו כמה סביבות Staging שכאלו: 2, 3, 5, 10 – תלוי בגודל הארגון. בדיקות מהירות מאפשרות לנו להחזיק בפחות סביבות Staging.
    • ה Staging Environment דומה ככל האפשר לפרודקשיין:
      • התקנה מבוצעת באותו האופן: clusters, מכונות נפרדות, DB נפרדים, קונפיגורציה – כמו בפרודקשין.
      • ה Data יהיה לרוב Data שהוכן מראש לבדיקות האוטומציה.
רק לאחר שכל התהליכים האוטומטים הסתיימו (Isolated + Stating Environments), והתאפשרו בדיקות ידניות (של מפתחים / QA) על סביבת ה Integration (או Staging – לבקשתם) – ניתן לבצע את ההחלטה “לשחרר ל Production”.
אם אתם זוכרים את הפוסט הקודם, כך זה נראה בצורה הפשטנית:

ה Manual Trigger מגיע לאחר בדיקות שהן ידניות (כמובן שמישהו יכול להחליט לדלג עליהן במקרים מסוימים ולאשר ללא בדיקה). הוא לא נמצא שם סתם.

הנה תיאור קצת יותר מפורט של ה Pipeline שהראתי למעלה:

ליד כל שלב רשמתי זמן שנחשב סביר לתהליך. סה”כ, גם Pipelines יעילים אורכים כחצי שעה-שעה מרגע ה push לגיט – ועד לפעולה ב Production.

שלב למשל שהוספתי ב Pipeline המפורט הוא שלב שלא מופיע בתרשים ה High Level: בדיקות Rollback.
בסיפור הזה הארגון נתקל בכמה פעמים שהיו בעיות לבצע Rollback של שירותים בפרודקשיין – מה שמגביל את הארגון לשחרר את השירותים לפרודקשיין בחופשיות שהוא רוצה. אופציית ה Rollback היא חיונית להתאוששות מהירה.

על כן נוסף שלב נוסף ב Pipeline בשם Rollback Test. הוא הולך בערך כך:

  • מתקינים את השירות בגרסה N (בצורה isolated) ומבצעים DB migration.
  • מבצעים Rollback: מתקינים את השירות מחדש בגרסה N-1 (ללא rollback ב DB).
  • מבצעים בדיקות Service/API של השירות בגרסה N-1 – לראות שהוא עובד בצורה תקינה.
כל התהליך הזה קורה במקביל לשאר התהליך והוא לא אמור להיכשל. אבל אם הוא נכשל – מונעים את היציאה של השירות הזה ל Production (עד שמתקנים את התאימות לאחור).
שלב כזה הוא בדרך כלל פרי ניסיון ולא תכנון מוקדם. קשה להעריך את העלות / תועלת של שלב שכזה – מבלי שהארגון הספציפי, עם המערכת שלו, השוק שלו, והתרבות שלו – עוברים כמה כשלים ב deployments בגלל נושא ה Rollback.
ה Pipeline אמור להשתנות לאורך הזמן ולהתאים את עצמו לצורכי הארגון: לפעמים להוסיף שלבים – ולעתים להסיר ממנו שלבים.

בהקמת ה Pipeline, וגם לאורך חייו, הארגון ישאל את עצמו שאלות שונות:

  • האם את הבדיקות הראשונות של המיקרו-שירות, לבצע במכונה בודדת (עם stubs) – או האם להרים landscape שלם? מישהו צריך לשלם על מכונות ה landscape – וזה ייקח יותר זמן.
  • כמה אנו מוכנים לחכות לבדיקות? יותר בדיקות = יותר בטחון, מצד שני – פחות יעילות וזמן תגובה לשינויים ב Production?
  • היכן לעשות בדיקות ידניות? בסביבת אינטגרציה – ואז לגלות בעיות אינטגרציה מוקדם יותר, או בסביבת Staging? ואז להגביר את הסיכוי למנוע את הבעיה הבאה בפרודקשיין? זו לא רק שאלה של עדיפות פילוסופית: פריון עבודה מול יציבות הפרודקשיין – זו שאלה כמה מנגנוני ה Rollback והבדיקות השונות יעילים, והיכן יש לפצות אותם?
  • האם להשקיע ב Load Tests כחלק מה Pipeline – או האם להסתמך על Canary Tests (בהמשך) עבור Load?
  • האם לבצע הרצה של כל הבדיקות האפשריות מדי פעם (על תצורה שהגיעה לפרודקשיין), גם אם סט הבדיקות לוקח שעות רבות? (פעמים רבות – עושים זאת).
  • ועוד ועוד…
שווה לציין באזז עכשווי בשם Pipeline as Code. מכיוון שה Pipeline הופך ונעשה מורכב, התחילה גישה בה ניתן “לתכנת” אותו בשפת תכנות ולא רק בקונפיגורציה.

את המונח Pipeline as Code ייתכן ותשמעו מהפרסומים של Jenkins 2.0 – שלכאורה עבר שינוי מהותי בכדי לתמוך ביכולות הללו. בפועל הוצגה מערכת Plugins שעדיין רחוקה מהאידאל של Pipeline as Code. מקביליות בהרצת בדיקות עדיין מבוססת בעיקרה על Plugins ואיננה יכולת ליבה של המערכת – וכך גם השגת הגמישות ב Pipeline עצמו. ניתן לומר (באופן מעט מרושע) ש Jenkins 2.0 היא מוצר Pipeline by Plugins.

Jenkins הוא עדיין כנראה הכלי הנפוץ ביותר לבניית Deployment Pipeline, אם כי כלים כמו Concourse CI או goCD ו gomatic – נחשבים למתאימים יותר לבניית ה Deployment Pipeline. ייתכן והגיע זמנו של Jenkins לפנות את כס המלכות.

עוד כמה רעיונות של CD שכדאי להכיר

Infrastructure as Code / Everything as Code – מכיוון שחשוב שהקונפיגורציה של המערכות תהיה זהה בין סביבות ה Staging וה Production, ומכיוון שחשוב שהקמת סביבה לפי אותה קונפיגורציה נתונה יהיה תהליך אוטומטי, מהיר, ואמין – הרעיון הוא שכל הגדרות המערכת, או מה שגורם להן יהיה מנוהל כמו קוד, ב Version Control System – אם אותה בקרה (למשל: pull requests) ותהליכים שמוכיחים את עצמם עבור קוד.
אלו חדשות ישנות כבר – אני מניח.Blue/Green Deployment – הרעיון בו שחרור גרסה חדשה של שירות מבוצע באופן הבא:

תמיד מחזיקים ב Production שתי סטים של מכונות (או clusters): סט כחול וסט ירוק. כל סט מספיק גדול בכדי לשרת את כל התעבורה ב production בעצמו.
סט אחד תמיד יהיה עם גרסה N, והסט השני – עם גרסה N-1.
נניח שאנו עכשיו בגרסה הירוקה, ורוצים לבצע התקנה של גרסה חדשה: נתקין אותה על סט המכונות הכחול.
נוודא שההתקנה הצליחה (בעזרת smoke tests).
עכשיו פשוט נורה ל Load Balancer להעביר את כל התעבורה ל Set הכחול. זה תהליך של שניות – בד”כ. בקשה שכבר התחילה תסתיים במכונה הירוקה, אבל הבקשה הבאה – תגיע לסט המכונות הכחולות.
הכל טוב? הסט הכחול הפך להיות הסט הפעיל.
יש בעיה? ניתן לבצע Rollback בשניות ולהחזיר את התעבורה לסט הירוק.
חיסרון ניכר הוא הצורך בחומרה כפולה.
וריאציה מקובלת היא להחזיק רק סט אחד של חומרה ברוב הזמן, ורק בעת התקנת גרסה חדשה – להרים סט נוסף (פעולה פשוטה בענן). לאחר ההעברה, מחזיקים את הסט הקודם של המכונות לשעה נוספת – כי רוב התקלות בפרודקשיין מתרחשות זמן קצר לאחר מעבר גרסה. הכל בסדר לאחר שעה? – מורידים את סט המכונות היתיר.
Canary Release – הרעיון הזה הוא וריאציה של Blue/Green Deployment.
הרעיון הוא לבצע את ההתקנה באותו האופן (נניח שהגרסה החדשה שהתקנתי היא על סט המכונות הכחולות), אבל להעביר רק כמות מזערית של תעבורה לסט הכחול: במקום 100% מהתעבורה – להעביר רק 1% מהתעבורה.
עכשיו מחכים זמן קצר לראות אם מערכות המוניטורינג של הסט הכחול מזהה בעיה. נאמר: לרבע שעה.
אם יש בעיה – מחזירים את 1% התעבורה לסט הירוק. אם לא – מתקדמים ל 100% לסט הכחול.
המטפורה לשם Canary Release הוא הנוהג של כורים להחזיק כלובים עם קנריות כאמצעי התרעה מוקדם.
אם היו נפלטים גזים רעילים בעת הכרייה, הציפורים העדינות היו מתות ראשונות – ולכורים הייתה הזדמנות להסתלק לפני שיספגו פגיעה קשה.
Dark Deployment – הרעיון כאן הוא שאין חובה ש Deployment יהיה גם בעצם Release.

פיצ’רים רבים במערכת – ניתן לשחרר אותם עם Feature Flag כבוי. הפיצ’ר הוא Deployed, אך לא Released.

למה לעשות את זה? בזמן הזה QA או המפתחים יכולים לבדוק את הפיצ’ר בפרודקשן, בסביבה הכי אמיתית עם תעבורה אמיתית. אפשר לעשות beta testing למשתמשים נבחרים – ולהכניס בפיצ’ר שיפורים, ורק כשהוא מוכן, בדוק, ויציב – לשחרר אותו.

כיום הפרקטיקה של Dark Deployment היא דיי מקובלת, גם אם מי שעושה זאת לא מכיר ולא משתמש המונח הרשמי :).

סיכום

שוחחנו על CD לא מעט – זה נושא גדול, שנוטה להעסיק את הארגון רבות.
עדיין לא שוחחנו על איך מתחילים בהטמעה של CD בארגון שלא רגיל לכך, ולא על Continuous Deployment: האם זה באמת רק דילוג על שלב ה manual tests?

שיהיה בהצלחה!

אז… אתם רוצים Continuous Deployment?

נתקלתי בארגונים שרצו לעשות Continuous Delivery (או Deployment, או אפילו Integration) משום שרצו להידמות לארגונים מצליחים אחרים. הייתה מן מחשבה מעורפלת שאם נעשה את “זה” – דברים יסתדרו טוב יותר, כל זאת ללא התעמקות אמיתית בהבנת התמורות הצפויות ממהלך שכזה.
המחשבה כנראה הולכת כך: “CD זה טוב => אנחנו רוצים להיות טובים יותר => בואו נעשה CD”.
(ייתכן, כמובן, והייתה התעמקות – אך פשוט לא נחשפתי אליה.)Continuous Delivery היא כבר שאיפה סטנדרטית: כמעט כולם רוצים להיות שם. כ”כ הרבה נמצאים “בתהליך…”. כרגיל…

בפוסט הזה אני רוצה לחזור ולדבר על הציפיות הסבירות מ CD, על המשמעות, המעבר, וכו׳…

הפשט

בדומיין שאנו מדברים עליו יש 3 פרקטיקות דומיננטיות, שנהוג לפרש אותן בערך כך:

  • Continuous Integration (בקיצור CI) – יש לנו שרת Build עם בדיקות אוטומטיות. כל כמה זמן (לילה?) – כל הבדיקות רצות ואנו מגלים אם יש בעיות בקוד – ואז מתקנים.
  • Continuous Delivery (בקיצור CD) – יש לנו שרת Build אוטומטי, שגם אורז את הקוד ל Delivery. למשל: בונה את ה ISO (אם אנו מפיצים את המערכת על DVD – פחחח) או Docker Image – שניתן להטמיע בפרודקשיין (SaaS או On-Premises).
  • Continuous Deployment (בקיצור גם CD, לצורך הפוסט אשתמש בקיצור CDD) – כמו Continuous Delivery, אבל ההחלטה לשלוח ל Production היא אוטומטית. כל קוד שנכנס למערכת – מגיע ל Production. לכאורה, תוספת קטנה לתהליך.
התיאור הזה הוא נכון בגדול – אך גם שטחי למדי.
נכון, אך פשטני משהו…
מקור: notafactoryanymore.com

מוטיבציה – אז למה לנו CD עכשיו…?

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

  • צמצום אי-ודאות – היכולת לשחרר קוד מהר יותר, מספקת לנו פידבק מהיר ותדיר יותר מהשטח. ״לפגוע בקרקע בתדירות גבוהה יותר״. (רלוונטי בעיקר ל Continuous Deployment)
  • פישוט תהליכי ה Integration / Deploy – ארגונים רבים נאבקים לסיים גרסאות בזמן, ובאיכות טובה. CD היא דרך לשפר את התהליכים, בכמה צורות.
  • יציבות, או Uptime של המערכת בפרודקשיין.
איזה מדד הכי חשוב? – תלוי בארגון.
אני רוצה להרחיב מעט יותר על המוטיבציות:
צמצום אי-ודאות / סיכוןכשמנהלים פרויקט או מוצר בארגון, תמיד יש לנו חוסר ודאות מסוים: לפעמים הוא בינוני, ולפעמים – גדול.

  • חוסר ודאות מה הלקוחות צריכים –לפעמים הם בעצמם לא יודעים, ופשוט יש לראות כיצד הם משתמשים במוצר.
  • חוסר ודאות לגבי התוצאות של פעולות שנעשות – האם המעבר ל NoSQL DB יספק את ה Scalability הצפוי. האם ה Design החדש של מודול Y יעמוד יפה בשטף הדרישות העתידיות?
  • חוסר ודאות לגבי הבנת תוכנית הפעולה והתיאום בין אנשינו – כאשר האנשים שעובדים איתנו לא מבינים את אותה התוכנית – הם עלולים למשוך לכיוונים מנוגדים.
שווה לציין שהרעיון של Continuous Deployment קיבל תנופה גדולה מתנועת ה Lean Startup, שם צמצום מחזורי הלמידה והפידבק הם ערך מרכזי. הדרישה ל CDD, ע״פ המתודולוגיה, אמורה להגיע כיעד עסקי מה CEO – זה לא עניין ״פנימי״ של ה R&D…

במקום להיות ״נביאים״, או ״יודעי-כל״, תהליך ה CDD מאפשר לנו לנסות בשטח.
הפיצ’ר של אמזון של “אנשים שקנו את X קנו גם את Y”, נדחה ע”י אנשי המוצר כ”מטופש” – ובארגון אחר היה נקבר לעד.
התרבות הארגונית של אמזון, שגובתה בעזרת יכולות CDD, אפשרה למפתח שמאוד מאמין במשהו לבצע A/B test (על אוכלוסיה קטנה) – ולנסות להוכיח את צדקתו. כל אחד כמעט – יכול להציע ולהתניע ניסוי.
הניסוי הנ״ל הראה גידול של כ 3% במכירות (נתון מרשים מאוד!) – מה שהסיר מייד כל התנגדות, והפך אותו בן רגע לפיצ׳ר רצוי ע”י הפרודקט.
אם כולם מאמינים במערכת ובנתונים שהיא מייצרת,  אזי נתונים מהשטח הם ״מחסלי ויכוחים ארגוניים״.
CDD, אם כן, בשילוב A/B Tests ותרבות ארגונית מתאימה – מספקת Empowerment לעובדים, ויכולה להביא רעיונות חכמים שלהם – לידי יישום.
מיחסים ל CDD גם שיפור בשביעות הרצון של המפתחים, שכבני-אדם, גם הם צמאים לפידבק מהיר. מה יותר כיף: לפתח פיצ׳ר במשך שנה – ואם לראות אותו עובד (אם בכלל), או לראות שינוי בפרודקשיין כל שבוע-שבועיים? להרגיש את העשייה בצורה מתמשכת?
פישוט תהליכי ה Integration / Deploy
כשהחברה גדלה, תהליכי ה Integration וה Deploy הם לא פעם – כאב ראש רציני!
כמה עבודה אתם משקיעים בהגדרה ושיפור של התהליכים?
בתחקור של גרסאות שהתעכבו או יצאו באיכות לא-מספקת?
במינוי ״אחראים״ ושינוי מנגנונים – על מנת ש ״זאת תהיה הפעם האחרונה שזה קורה״?
– אם אתם ראשי צוותים או מנהלים בכירים יותר, אתם בוודאי חשופים למאמצים הללו יותר.
כאשר התוצאות מבוששות להגיע, המנהלים לוקחים פיקוד: מגדירים תהליכים, וממנים אחראיים – שלא תמיד בנויים מתוך הבנת הדקויות של המציאות היומיומית, ושלא תמיד יעילות במידה מירבית.

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

אין כאן קסם:

בתהליכי Integration/Deploy תקופתיים (נאמר: פעם בחודש) – משקיעים המון.
וגם בתהליכי CD – משקיעים המון.

התמורה היא שב CD הסיכויים להגיע לתהליך מוצלח – הם טובים יותר. במיוחד כאשר המערכת שלנו מחולקת למודולים נפרדים (למשל: microservices) ואז ניתן לייצר pipeline נפרד ומותאם לכל חלק במערכת (sub-system).

מקור: http://www.mindtheproduct.com

יציבות

לאחר מעבר מוצלח ל CD/CDD, המערכות נוטות להיות יציבות יותר.
זה לכאורה פרדוקס: שינוי בפרודקשיין הוא סיכון – והנה אנחנו הולכים לעשות הרבה יותר כאלה. במקום שינוי בחודש, אולי כמה שינויים כל יום!
מצד שני, כשהשינויים הם מאוד קטנים – הסיכון מאוד קטן, יכולת האיתור של תקלות משתפר פלאים, וכמו שאומרים: Practice Makes Perfect. הרבה אימון בתהליך מאפשר להשתפר בצורה מהירה יותר.
מודל היציבות של CD הוא MTTR (קרי: Mean Time To Resolve) על פני מודל של MTBF (כלומר: Mean Time between Failures). יהיו לנו יותר תקלות במספר – אך הן יתוקנו מהר, וסה״כ ה downtime שלנו יהיה נמוך יותר.שאלה מפורסמת ב Lean היא: “כמה עבודה עליכם לעשות בכדי לבצע Deploy של שורת קוד בודדת במערכת?” (כלומר: נזניח את תוכן השינוי, ואז – מהי התקורה על כל deploy של גרסה?). התרגיל הזה ידוע גם כ Single Line of Code DevOps Kata.

בארגונים ללא CD, מדובר בד”כ על כמה ישיבות, עבודה ידנית של ביצוע רגרסיות ומעבר על התוכן, ואף כמה פעולות ידניות של איש Operations שמלווה את ה deploy. כמה שעות עבודה, וכמה דקות של פחד (במקרה הטוב).

אם אתם רוצים לעשות deploy כל יום, זה נראה כחוסר-יעילות, ולכן ה”Best Practice” שהיה מקובל במשך שנים הוא להפחית את מספר ה releases, או לפחות למתן אותו – נאמר, פעם או פעמיים בחודש, ולא יותר.

לא שעות העבודה שמושקעות ב deployment הן המחסום העיקרי – אלא הפחד מתקלות: תקלת Deploy עלולה לגרום להפסדים כספיים (“פגיעה בביזנס”), לעלות עשרות שעות עבודה של מפתחים ,ולגרום לפגיעה במוניטין החברה.

הגישה של CD נקראת: Bring the Pain forward (כמו באג’ייל).
אם זה כואב, עשו את זה בתכיפות רבה יותר – עד שתשתפרו וזה כבר לא יכאב.

בפועל, באימוץ CD אתם הולכים “לשבור דברים” כ”כ הרבה פעמים – כך שתוך כדי אתם צפויים לפתח יכולות Recovery טובות במיוחד ולשפר מאוד את ה MTTR. כמובן שחשוב מאוד לשבור דברים קטנים, ולהיות עם יכולת recovery כמעט מיידית, למשל: לסגור את ה feature flag או לחזור ל deployment הקודם תוך שניות (ע”י blue/green deployment – פרטים בהמשך).

המערכת לא תהיה יציבה יותר כי היא “תשבר פחות”.
אם תציבו לארגון ה R&D מדד פנימי של “מינימום תקלות” – קרוב לוודאי שתהרגו את תהליך ה CD.

המדד צריך להיות: תוך כמה זמן אנו מתקלים תקלה, end-to-end: זיהוי התקלה עד אימות התיקון.

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

Continuous Integration (בקיצור: CI)

זהו הרעיון שקוד המערכת יהיה כל הזמן במצב תקין (“working state”).

בניגוד למיתוס מקובל, המשמעות איננה שעליכם להתקין ולהגדיר מערכת של Jenkins או Cruise Control.
זכרו: הכלי – הוא החלק השולי. התהליך – הוא העיקר.

העיקרון הוא שאינטגרציה של קוד (“merge”) הוא הכלי האולטימטיבי לזהות שבירות במערכת – ולכן עליכם לבצע אינטגרציה כל הזמן.

כפי שאמרו זאת מייסדי ה Extreme Programming (שהיו הראשונים לאמץ את הפרקטיקה בצורה רחבה):
“אם אינטגרציה של קוד היא טובה – עשו אינטגרציה של קוד כל הזמן.”

המדד המקובל ליישום CI הוא:
כל מפתח, מבצע בכל יום עבודה – לפחות פעם אחת merge של הקוד שלו ל branch המרכזי. (ועדיף: חמש פעמים)

(רמז: Jenkins לא גורם לזה לקרות.)

שימו לב: זה לא שכל מפתח מושך את ה branch המרכזי (נקרא לו לצורך הפוסט: master) ועושה merge לתוך ה feature branch. זה פחות מועיל / מלמד על שברים. העניין הוא לבצע merge לתוך ה master בכל יום.

Feature Branches? לא כ”כ מומלצים, אלא אם אתם מקפידים לבצע merge ל master.
זה מחייב את המפתחים לחשוב ביחידות קטנות, לפרק את הפיצ’ר לשלבים קטנים (שזה טוב – בפני עצמו), ולדאוג כל הזמן שהקוד הנכתב – לא שובר את המערכת.

מה קורה עם קוד שמשנה חלק גדול במערכת? איך אפשר לעשות merge כאשר הקוד לא “מוכן”? – פשוט הכניסו feature flag, ואל תדליקו אותו עד שהקוד מוכן. תחשבו איזה יופי יהיה להדליק את הפיצ’ר רק עבור המשתמש שלכם בפרודקשיין – ולבדוק איך הפיצ’ר עובד בלייב עם traffic/data אמיתי!

העיקרון החשוב השני של CI הוא:
כאשר ה Build נשבר – לתקן אותו זו עדיפות עליונה של הארגון. לפני כל דבר אחר.

יעד מקובל הוא תיקון תוך 10 דקות – לרוב ע”י rollback.
אפילו יותר טוב: בדקו את ה merge בצד, ורק לאחר שהצליח – בצעו את ה merge בפועל. השיטה הזו עובדת יותר טוב כאשר יש code bases קטנים (למשל: microservices) ואין race condition על merges.

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

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

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

בדיקות יחידה (Unit-Tests) או אינטגרציה (Integration-Tests) הגיעו לתהליך ה CI מאוחר יותר – והפכו לחזות עיקר התהליך. אין ספק: הן חשובות מאוד, ומועילות מאוד. מה היה קודם לכן? קומפליציה + בדיקת המערכת end-to-end (שאורכת זמן רב, ותופסת רק חלק מסוים מהבעיות).

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

בד”כ השבירות בקוד (גם אם הן נתפסות ע”י Unit tests) מגיעות אחרי merges של קוד – ואתם לא רוצים “לחטוף אותן” בסוף הספרינט – חשוב לבצע אינטגרציה כל הזמן.

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

כל מיני פשרות של “רק את הפיצ’ר הזה נפתח בצד” – הן דרכים מצוינות לא להגיע ל CI עובד, שמצדיק את עצמו.

האם שווה לעשות CI ע”י merges תכופים, אך ללא בדיקות יחידה מקיפות?
– גם על זה לא הייתי ממליץ. זה כנראה עדיף במעט על בדיקות ללא merges תכופים – אך זה לא ייתן את האפקט המלא.

CI הוא האב הרוחני של CD, ולרוב מגיע איתו ביחד.
האם חובה ליישם CI לפני שמתחילים לעבוד על CD? – נדבר על זה בהמשך…

סיכום

בפוסט זה ניסיתי להסביר מה הציפיות הסבירות מ CI/CD/CDD – תהליך חשוב שלאט הולך ומוטמע באמת בעוד ועוד חברות. אימוץ תהליכים אלו הם לרוב מאמץ ארגוני אינטנסיבי של חודשים – אבל גם השיפור עשוי להיות משמעותי למדי.

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

שיהיה בהצלחה!

רשמים ראשוניים מ GOTO; Berlin 2014

זה עתה חזרתי מ-3 ימי כנס \”;GOTO\” שהתרחש בברלין.

כחלק מתהליך התייעלות בסאפ, שולחים פחות אנשים לכנסים תוך התחייבות להעביר אח\”כ את הידע (בלוג פנימי, הרצאות) בתוך החברה.

מה יותר טבעי עבורי מלהעביר סיכום גם כאן בבלוג? (בוריאציה מעט שונה, לקהל מעט שונה).

Martin Fowler מגיע למתחם Kosmos – לתת את ה Keynote הראשי. חבר הסביר לי שהמבנה נבנה בתקופה הסובייטית – ושיש עוד רבים ממש כמותו.

כנסי ;GOTO הם סדרה של כנסים שרצים ברחבי ארה\”ב ואירופה (שיקאגו, ברלין, אמסטרדם, אורהוס, וקונפהגן) ומתמקדים ב Software Craftsmanship, ארכיטקטורה, אג\’ייל, DevOps, וטכנולוגיות \”חמות\”.
הרבה מרצים מפורסמים מגיעים לשם כ\”דרך קבע\”: Martin Fowler, Kent Beck, רוד ג\’ונסון, בכירים באמזון, עובדי ThoughtWorks השונים, ועוד. כמעט לא תמצאו שם אנשים מגוגל או מסטראט-אפים אלמונים, אלא יותר מרצים שהם מחברי ספרים (איני יודע אם זו דרישה מפורשת), מובילים של קהילות (למשל מובילת קהילת הפייטון באנגליה), או לקוחות של ThoughtWorks (למשל: חברות ביטוח ובנקים) ושל אמאזון (למשל: נטפליקס).

נדמה לי שהשנה הייתי הישראלי היחידי בכנס.

מה נשתנה?

חוץ מכך שהייתי ב QCON London 2008 (סדרת כנסים \”אחות\” של ;GOTO) – אני עוקב כמעט כל שנה אחרי תוכן כנס GOTO בכדי להתעדכן בטרנדים העכשוויים.

מגמה אחת שאני מזהה בתכנים, היא נוכחות גוברת של נושאי UX בכנס. לפחות ע\”פ מתכנני הכנס – נראה אנשי תוכנה הולכים ומתעניינים יותר ב UX כחלק אינטגרלי מהפיתוח – וכחלק שמעניין את אנשי הפיתוח. מי יודע? אולי עוד שנתיים נשמע על UX Culture (כמו DevOps culture) ועל כך שיש לשלב את איש ה UX כחלק אינטגרלי מצוות הפיתוח?

ז\’רגון

כמה ביטויים ששמעתי בכנס שוב ושוב, ושאני לא נוהג לשמוע כ\”כ ביום-יום:

  • a Unicorn – כינוי לחברות שהן thought Leaders בנושאי טכנולוגיה, כמו פייסבוק, נטפליקס, או Etsy, בניגוד ל Horse – חברות \”רגילות\”.
    \”ההבדל היחידי בין unicorns לסוסים – הוא PR\” – מיהר אחד המרצים לנסות ולאזן את ההייפ. כן, גם אצל ה unicorns הקוד נרקב (\”code rots\”).
  • Shaving Yaks – פעולה ארוכה ומתישה, שבסופה אף אחד לא זוכר כיצד ומדוע היא התחילה:
    \”?!Why the hell, were we shaving this Yak\”
  • Bounded Context – רעיון מעולם ה DDD, שמציע פתרון ל business logic מורכב מדי לתחזוקה.
    הרעיון הוא להגדיר \”הקשרים מוגבלים\” (bounded context) במודל,
    לדוגמה: יש לנו מערכת לניהול לקוחות. במקום ליצור מודל אחד שמטפל גם במכירות וגם בתמיכה (support), אנו יוצרים שני מודלים, בלתי תלויים, של העולם (לקוח, מוצר, עסקה) שכל אחד מתמחה בהקשר המוגבל שלו: מכירות או תמיכה.
    הרעיון הועלה כמה פעמים בכנס – כדרך לפרק מערכת מונוליטית גדולה למיקרו-שירותים.
  • Two-pizzas Team – ביטוי שצמח באמזון, ואומץ ע\”י SCRUM לבטא צוותים של \”בערך\” 8 אנשים (או 16 בחורות ממש רזות 🙂 ) – מה שניתן להאכיל בעזרת 2 פיצות אמריקאיות גדולות.
  • T-Shaped Person – תיאור המבטא איש מקצוע רצוי, בעל רוחב (קו אופקי), וגם עומק מקצועי (קו אנכי). הרוחב מתבטא בהכרות עם נושאים שונים והיכולת לתקשר היטב עם אנשים מתחומים שונים.
    באחת המצגות המציג הציג שארכיטקט אמור להיות π-Shaped Person, כאשר לו רגל של הבנה טכנית עמוקה, ורגל שנייה של הבנה עסקית עמוקה.
רעיונות שחזרו על עצמם שוב ושוב בהרצאות

  • Micro-Services היו כנראה ה-Highlight של הכנס, ומדברים עליהם כבר כארכיטקטורת \”ברירת-המחדל\” למערכות ווב בענן. 
  • Breaking Down Silos (למשל עם DevOps או עם ה Business) – בכדי להשיג אג\’ייל אפקטיבי. 
  • אג\’ייל (וסקראם בפרט) דורשים תיקונים. סקראם הוא מעט נוקשה, ולא כ\”כ פתוח לשינויים.
  • התלהבות גדולה מ Docker – ככלי ל Continuous Deployment מהיר יותר.
  • התלהבות מה Netflix Chaos Monkey (סיפרו עליו ב 3 הרצאות שהייתי, כולל ה keynote) – תהליך שתפקידו להרוג שירותים אמיתיים ב production בכדי לאתגר את מנגנוני ההתאוששות של המערכת.
  • שימוש ב Strangler Pattern על מנת לבצע מעבר הדרגתי בארכיטקטורה. בעיקר מ Layered Architecture ל Micro-Services Architecture.

ה Keynote הפותח (מרטין פאוולר)

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

  1. Software Development in the 21st Century – שבעצם עסק ב Micro-Services והחיבור הטוב שלהם לענן ול Continuous Deployment.
  2. מצגת ללא כותרת – מכיוון שהוא התקשה למצוא לה כותרת. אולי הקהל יוכל לעזור לו.
ההרצאה הראשונה הייתה מבוססת בעיקרה על הפוסט של מרטין ממרץ השנה על micro-services, וכללה מעט הסברים חדשים. בקיצור, מרטין מתאר שם 9 תכונות מקובלות של מיקרו-שירותים:

  1. Componentization via Services
  2. Organized around Business Capabilities
  3. Products not Projects
  4. Smart endpoints and dumb pipes
  5. Decentralized Governance
  6. Decentralized Data Management
  7. Infrastructure Automation
  8. Design for failure
  9. Evolutionary Design
נושא המיקרו-שירותים שווה פוסט בפני עצמו. האמת שיש לי כבר פוסט כזה בעבודה, נקווה שאגיע ל delivery…

ההרצאה השנייה היתה אוסף של רעיונות שונים, ולכאורה לא קשורים:

הרצון לבצע כמה תיקונים ועדכונים ל SCRUM – לאור הניסיון שנצבר
התלונה העיקרית הייתה בכך שה PO הוא ה\”מוח\” היחידי בכל הנוגע להגדרת המוצר – והמפתחים הם רק מבצעים.
מרטין סיפר על מקרה שקרה באמזון – בו מתכנת באמזון הציע פי\’צר חדש: \”לקוחות שקנו מוצר X קנו גם מוצר Y, עם קישור למוצר Y\”. הרעיון עלה ל VP Marketing שביטל אותו במקום: \”לא צריך להפריע ללקוחות בזמן תהליך הקנייה, שהם כבר שם – לא מפריעים להם!\”. המתכנת בכל זאת הלך ו\”דחף\” ל production את הפי\’צר – שהראה מיידית (בעזרת A/B testing) עליה של 3% ברווחים. ה VP התעצבן על המהלך – אך לא יכל ללכת נגד צמיחה של 3% ברווחים בהשקעה כ\”כ קטנה[א].

מלבד כך ש AB Testing היא לא פרקטיקה של סקראם (אלא Lean Startup) – הרעיון העיקרי הוא שלמתכנתים יש יתרון בהבנת ה feasibility של פיצ\’רים – והם יכולים לתרום הרבה. \”השתקה\” שלהם, מפאת קולו היחיד של ה PO – נראית כמו טעות היסטורית גדולה.
מרטין המליץ שבמוצר יהיה Conversational Stories – שנוצרים במשותף ע\”י POs ולא-POs. בכל זאת, עדיין ההמלצה היא לתת משקל רב יותר ל POs (למשל: לקבוע priorities, בהנחה שזה לא כלי לייבש כל מה שלא הגיע מה PO).
עוד אלמנט היה האחריות של המפתחים לדאוג למשתמשי ולקוחות המערכת (ולא רק לרזומה שלהם עצמם – באימוץ טכנולוגיות חדשות). למשל: בהגנה על פרטיות ואבטחה על המשתמשים – אפילו אם ה PO לא דוחף לשם ביזמתו.
Dark Patterns
Dark Patterns הם דפוסים של מערכת, שנוהגת בהטעיה / חוסר צדק כלפי המשתמש. לדוגמה: חנות אונליין שמוסיפה בעת הרכישה של מוצר מסוים, ביטוח או אחריות בתשלום – שהלקוח בכלל לא ביקש. הניסיון הוא שהלקוח לא ישים לב וירכוש בנוסף מוצר שלא התכוון לרכוש – מה שאנו מכירים בלבנט היטב כ \”שיטת מצליח\” (קרה לי פעם – זה באמת מעצבן!).
בשלב זה מרטין נכנס למצב תוכחה וממש גער במפתחים \”אם המנהל שלכם אמר לכם להכניס כזה פיצ\’ר למוצר – זה לא פוטר אתכם!\”.
\”…אל תגידו \’רק מילאתי פקודה\’. אתם שותפים באחריות!\”.
לא היה ברור לי אם מרטין הבין את משמעות המשפט הזה לקהל הגרמני, ועוד בכמעט-צעקה. אני בלעתי את הרוק כשהוא קרא את הקריאה הזו.
בסופו של דבר הוא דווקא יצא מזה יפה: הוא לא קרא לאנשים להתפטר (מה שלא סביר לדרוש) – הוא אמר להם כך: \”עשיתם משהו רע, וזה באחריותכם. עכשיו יהיה עליכם למצוא משהו טוב לעשות – על מנת לאזן את זה\”. הנה דרישה שאנשים יכולים לחיות איתה.
קריאה לפעולה
עוד 2 עניינים שעלו, כקריאה לפעולה מהמפתחים הם:
  1. להשפיע ולתרום למאבק בפרטיות ברשת האינטרנט. הייתה לו הרצאה נוספת שלמה בנושא, בניסיון להסביר ש: \”לא עשיתי כלום רע\” היא לא סיבה שלא יעקבו אחריכם. ברגע שעקבו כבר אחריכם – יש מידע שניתן לנצל כנגדכם. לדוגמה: היה לי משבר בחיים שאני לא מתבייש בו, אבל פרסום מגמתי שלו בשלב מאוחר יותר בחיים – יכול לפגוע בי.
  2. להימנע מ Alienating Atmosphere (אווירה גיקית עמוקה) בתעשיית התוכנה, שמרחיקה \”אנשים חברתיים\” ונשים מהתחום.
    למה לדאוג? כי באופן הזה התעשייה מאבדת הרבה כישרון. הנה מאמר שהוא הזכיר – כיצד אחוז הנשים בהייטק שבארה\”ב פחת משמעותית לאורך השנים, אולי בעקבות \”מתקפת הגיקים\” על התעשייה.
בסוף המצגת עלה למרטין \”לפתע\” רעיון לשם למצגת, ואז השם הופיע בשקף האחרון: \”Professionals, not just code monkeys\”.

    הערה: ניתן למצוא גרסה דיי דומה של ההרצאה הזו מכנס OOP2014 (מאז הוא קצת שיפר את ההצגה, בעיקר).

    סדנה: Continuous Delivery

    עוד לפני הכנס עצמו, היה יום שלם של סדנאות לימוד בקבוצות קטנות. מאוד התעניינתי ב System Thinking של מייקל נייגארד, אבל בחרתי בסוף בפרקטי – והלכתי לסדנאת Continuous Delivery של Jez Humble.

    ג\’ז (קיצור של Jessie שזה קיצור של Jayson, אני מניח) הוא הבחור שכתב את הספר המפורסם \”Continuous Delivery\” וגם העביר בהמשך הכנס הרצאה בהשראת הספר החדש שלו: \”The Lean Enterprise\” (שנראה לי שבעקבותיה ארכוש אותו).

    ג\’ז היה מגניב למדי. שמח, משעשע, משוחרר (קרא \”Shitty\” לכל דבר שחשב שהוא לא מוצלח), וסיפק תובנות טובות.
    אני לא הולך לכתוב פה פוסט שלם על Continuous Delivery, אלא רק להזכיר את התובנות העיקריות שעלו:

    דבר ראשון הוא ההבחנה שההבדל בין Continuous Delivery ל Continuous Deployment הוא לא בשלבים שונים של אותו התהליך, אלא ביכולת לספק כל אחד בהקשר הנתון. ג\’ז קיטלג מערכות תוכנה לשלוש קטגוריות:

    • מערכות ווב – שם אין טעם לעשות Continuous Delivery, אם ניתן לעשות Continuous Deployment.
    • מערכות Packaged (למשל SQL Server), ומערכות Embedded – שם לא ניתן לעשות Continuous Deployment, אך עדיין יש ערך רב ב feedback התמידי, ולכן עושים Continuous Delivery.

    קצת מבלבל ששני המונחים מתקצרים לצירוף CD, בדיעבד – אולי זה כבר לא משנה.

    הוא עבר על use-case כיצד HP העבירו את תהליך פיתוח ה Firmware שלהם למדפסות שלהם – ל CD. רוב העיסוק היה באופן בו נבנה והתפתח ה deployment pipeline שלהם.

    המעבר \”עלה\” בשנתיים של כמעט-השבתה של התהליכים השוטפים, אבל ההישגים – היו משמעותיים. כמות פיתוח הקוד החדש (Innovation) – עלתה פי 8!
    בצד ימין, סה\”כ התשומות לא מתחברת ל 100%. 23% נמצאים בתחזוקת האוטומציה (בדיקות בעיקר) – מה שעשוי להראות ב waste – עד הרגע בו משווים כמה זמן נותן סה\”כ ל innovation – שזהו בעצם יצירת הערך היחידה בכל התהליך.

    ה Use-Case הזה מתואר במפורט בספר בשם Large-Scale Agile Development.

    מקור: Jez Humble

    עוד תובנות ספורדיות:

    • חשוב מאוד להחזיק את ה App Configuration במערכת ניהול הקוד – על מנת שיהיו גרסאות מדויקות.
    • מייבן הוא כלי מחורבן לביצוע CD. ה build life-cycle שלו הוגדר בעולם פרה-CD-י. Gradle הוא לא יותר טוב.  הוא ציין לטובה רק את Rake (של רובי).
      ה mitigation העיקרי למייבן הוא להפסיק להשתמש ב snapshots – כדי שיהיה אפשר לשחזר במדויק build שכשל – ולאבחן מה הייתה התקלה.
    • התייחס לפוסט Google Platforms Rant לגבי מדיניות micro-services עבור CD והאופן לנהל גרסאות של APIs.
    • בדיון על גרסאות קוד, בחור גרמני עצר את הדיון וקרא: \”אבל versioning על REST API נחשב כ bad practice…\”.
      ג\’ז לא חיכה: \”אתה צריך להחליט: אתה רוצה CD או לא? אם כן – אל תתן לאיזה כלל של REST להפריע לך.\”
      \”אתה יודע מה? אני אדבר מחר עם ג\’ים וובר (מחבר של ספר מפורסם בנושא) – אני בטוח שהוא יהיה בסדר עם זה… כן לג\’ים לא תהיה בעיה…\”.
      הוא אמר את זה בצורה מצחיקה למדי, ונראה לי שהצליח גם לא לפגוע בבחור שהעלה את זה.
      אהבתי את הגישה: באמת לפעמים עקרונות לא לגמרי מסתדרים זה עם זה – וחשוב להבחין מה חשוב לנו יותר.
    • עברנו על מספר פתרונות לתצורות CD, ובעיקר:
    • אי אפשר להוכיח Releasability, רק להפריך אותה (בעזרת בדיקות ואוטומציה).
    • כאשר build נשבר (ברמת ה CI) – יש לחזור מהר מאוד (דקות) למצב תקין ע\”י revert של השינויים האחרונים. את הניטור עושים offline. באופן דומה מאוד – עושים זאת ב production.
    • הוא לא מתלהב מגיט עבור CD / CI – וממליץ כ mitigation לעבוד על trunk (או master) בלבד.
      בגוגל, 10,000 מהנדסים עובדים רק על trunk גלובלי שכולל כמעט את כל הקוד של גוגל (מלבד אנדרואיד ו chromeOS, מסיבות היסטוריות).
    • מדד שהוא ממליץ לעשות לו אופטימיזציה הוא Time To Restore Service.
    • עקרון: deploy the same way to every environment.
      • היה לו סיפור על נטפליקס שבדקו קוד על MRI (ה VM הרגיל של רובי) – כי קל לדבג, אבל ב production עבדו עם JRuby (שהוא מהיר בהרבה, ואמור להיות זהה). כצפוי: באג בלתי-צפוי ב JRuby גרם להם להשבתת פעילות מאוד לא נעימה.
    • עקרון משנה: only build packages once. מצד אחד שיקול ביצועים (לא לעשות אותה העבודה פעמיים), מצד שני – ייתכן שבנייה מאוחרת יותר (בעיקר בסביבת CD) תיצור image מעט שונה.
    • עיקר האתגר ב CD הוא לא הכלים ו/או הטכניקות, אלא בעיקר ליצור DevOps Culture. בחלק זה היה לו סיפור מדליק על נומי (NUMMI) – שיתוף הפעולה בין טויוטה וGM, שיצר הצלחה מדהימה – ש GM לא הצליחו לשחזר. אלו סיפורי שחר ההיסטוריה של Lean שהם תמיד מעניינים…
      • הוא המליץ על הספר Toyota Kata 
      • בלי, ועם קשר, המליץ על הספר The Phoenix Project כתחליף מודרני ומכוון IT לספר \”המטרה\” (ספר שנכתב ע\”י בחור ישראלי, והיה דיי מהפכן בכל העניין של ניהול תהליכים ע\”פ אילוצים)
      • המלצה נוספת – The Corporate Culture Survival Guide. אין מה לומר, הבחור אוהב ספרים.
    • לראשונה שמעתי מישהו קורא ל Router (רכיב רשת) – \”רוטר\”. דיי הגיוני, אני יודע שבארה\”ב קוראים ל Route (למשל Route 66) לסירוגין כ ראוט 66, או רוט 66.
      חלק גדול מהסדנה (כמעט חצי) – עסק בביצוע בדיקות. החלק הזה היה קצת יותר משעמם עבורי – כי זה נושא שכבר טחנתי רבות לאורך הקריירה.
      במקום פירמידה – הוא הציג את סוגי הבדיקות השונים במטריצה.
      • גם הוא התלונן על חוסר הבהירות במינוח של בדיקות פונקציונליות / קבלה / אינטגרציה (נושא שעלה אצלנו לדיון לאחרונה בעבודה).
        • בזמן הכנס, פחות או יותר, מרטין פאוולר פרסם עדכון לפוסט ישן על בדיקות יחידה, שמכיל דיון על Solitary Tests ו Sociable Tests. כמה נוח – אנו מנהלים בדיוק דיון מקביל בעבודה, ואין כמו גורו בינלאומי, בכדי לתמוך ולתת הרגשה שאנו בכיוון הנכון.
      • קריאה מומלצת Google Testing Culture
      • ציין את PageObject כדפוס מוצלח לבדיקות Acceptance.
      • עודד למחוק מהקוד בדיקות שכבר לא תורמות / לא רלוונטיות (בגלל שינויים בדרישות).
      • הבחין בין Acceptance Tests (\”מקטע בודד של פעילות\”) ל Journey Tests (המכסים flow גדול של acceptance), ושוחח קצת על הבחירה ביניהן (כמובן שגם וגם – אבל כמה ומתי כל אחד).
      • \”בדיקות לא-יציבות הן יותר גרועות מבדיקות חסרות-תועלת\” (כי אז אנשים מפסיקים לסמוך על בדיקות).
      נושא גדול אחרון היה ההתמודדות עם בסיסי נתונים בסביבת CD:
      • DB Versioning – רעיון שלכל שורה בבסיס הנתונים יש גרסה (בדומה ל multi-tenancy), וכך ניתן להריץ בדיקות של בסיס הנתונים במקביל / לעשות deploy הדרגתי.
      • טכניקה נוספת לבדיקות: לעשות טרנזקציה ו rollback בכל בדיקה.
      • שימוש של In-Memory DB (למשל: H2) לבדיקות בלבד – בכדי להשיג מהירות גבוהה. מחיר בעייתי נדרש: שוני מסביבת ה production.
      • יכולת Fork DB של Heroku – שיכול לעזור מאוד לבדיקות. אולי ניתן לעשות זאת עם backup/restore גם בצורה מקומית.
      • טכניקות שונות ל nZDM (קיצור של near Zero Downtime for Maintenance) בכדי להחליף \”גרסה\” של בסיס נתונים ב production (או לבצע migration ל schema) – תוך כדי צמצום ההשפעה על הלקוח הסופי. הכוונה היא להשאיר את המערכת חיה, אך למשך זמן קצר (דקות) – לא לאפשר למשתמשים לבצע כתיבות לבסיס הנתונים (או לאגור אותם בצד בנוסח CQRS – ולעדכן אח\”כ).
      • noSQL – כדרך לעקוף רבות מהבעיות. מה לעשות: noSQL, micro-services ו CD מתאימים זה לזה – ובמקום הזה בסיסי-נתונים רלציוניים משתלבים פחות טוב.
      מקור: Jez Humble

      סיכום

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

      שיהיה בהצלחה,
      ליאור

      ——

      [א] בסשן אחר שאל המציג את הקהל: \”כמה מכם יכולים לדחוף מ production פיצ\’ר לאחר שה VP Marketing אמר שזה רעיון רע?\” (כמו בסיפור של אמזון).
      באופן מפתיע למדי, כעשרים אחוז מהקהל הרים יד. אולי בגלל שהיו הרבה סטארט-אפיסטים (?!) אולי גם האווירה הליברלית של ברלין.