למה Terraform state locking נשבר בעבודה במקביל
Terraform מחזיק מפת משאבים מנוהלים בקובץ ה-state ובונה תוכנית שינויים מהגרסה הנוכחית שלו. כשמהנדס אחד מיישם, הכול מסתדר. בשני יישומים במקביל לא שניהם מסתדרים — והסימן לתקלה צף לא בלוגים, אלא בענן.
מנגנון terraform state locking מכסה בדיוק את המקרה הזה: לפני היישום התהליך תופס נעילה, השני ממתין או נעצר עם הודעה שהמנעול כבר תפוס. באחסון אובייקטים המנעול הוא טבלת DynamoDB עם מזהה נעילה, וב-Consul — סשן עם זמן חיים מוגבל. ההבטחה אחת: עם תיאור התשתית עובד בדיוק תהליך אחד.
קונפליקט של יישום בו-זמני מתחיל במקום שבו הנעילה לא מוגדרת או לא נשמרת: יש כתובת אחסון, אבל אין טבלת מנעול; ולמהנדס אין הרשאת כתיבה אליה; למכונה המקומית ולסוכן הבנייה יש פרטי זיהוי שונים; זמן החיים של הסשן פג ביישום ארוך. בנפרד — הסרת המנעול ידנית אחרי קריסת תהליך, בלי לבדוק שכתיבת ה-state הושלמה.
ואז שני התהליכים קוראים גרסה אחת של ה-state ובונים ממנה תוכנית; הראשון כותב את התוצאה, השני — מעליה את שלו, שנבנה מנתונים מיושנים. המשאבים של הראשון נופלים מתוך התיאור: בענן הם חיים ומחויבים, ואילו Terraform חושב שהם לא קיימים.
זהו קובץ state פגום — לא פגום בבייטים, אלא חסר במשמעות. הוא גם יוצר חוסר סנכרון: ההרצה הבאה מנסה ליצור שמות תפוסים או יוצרת מחדש צמתים פעילים, ואין במה לחזור אחורה אם באחסון לא הופעלה גרסאות. בואו נפרק איך זה נסגר.
מה נותנת נעילת state מנוהלת לצוות
נעילת state היא שכירות מבוזרת לכתיבה. לפני יישום ה-plan, Terraform מציב באחסון המשותף תג בעלים — שורה בטבלת DynamoDB או מפתח נעילה ב-Consul — ומסיר אותה רק לאחר סיום הפעולה. המהנדס השני רואה מי מחזיק ואיזו פעולה, במקום לדרוס בשקט תוצאה של אחר.
בלי שכירות, שני יישומים בו-זמניים מתכנסים לקובץ state אחד: חלק מהמשאבים נשארים מחוץ לתיאור, חלק מתוארים פעמיים. את חוסר הסנכרון מפרקים ידנית לפי לוגים של ה-provider — זה לוקח לילה במקום עשר דקות.
איך מצטמצם זמן ההכנה של שינוי בתשתית
המהנדס עובד עם תמונה מהימנה, ולא עם state שמישהו ערך במקביל, ולכן אין צורך להרכיב מחדש את ה-plan ולהשוות ידנית. ההמתנה בתור נראית בפלט הפקודה ונמדדת בשניות; בצוות של כמה אנשים השינוי עובר כבר ביישום הראשון, בלי נסיגות להכנה חוזרת.
איזה סוג כשל נעלם מהעבודה היומיומית
נעלם התרחיש היקר ביותר בזמן השיקום — קובץ state שאבד או נכתב חלקית מחדש, שאותו משחזרים לפי לוגים וייבוא משאבים ידני. תפוגה אוטומטית של השכירות סוגרת את החצי השני: אם מהנדס איבד גישה, התג מוסר לפי timeout ולא נשאר עצירה נצחית לכל הצוות.
אפשרויות נעילת state: השוואת מצבי עבודה
נעילת state היא נעילת כתיבה מבוזרת לקובץ ה-state: לפני תכנון או יישום התהליך תופס אותה, והרצות אחרות ממתינות או נופלות עם שגיאה ברורה. ב-Terraform המנגנון מופעל ברמת ה-backend, ולכן בחירת אפשרות היא בחירת אחסון נעילות, ולא תוספת מעליו.
| אפשרות | מתי מתאימה | מגבלות |
|---|---|---|
| DynamoDB עם backend מרוחק | סביבה בענן אחד, state באחסון אובייקטים | תלות בענן; טבלה לכל workspace; נעילה תקועה מוסרים ידנית |
| Consul: key-value וסשנים | בסביבה כבר יש cluster Consul מתוחזק | צריך לשמור קוורום וגיבויים; באובדן קוורום הנעילה לא ניתנת |
| קובץ state מקומי | מהנדס אחד על המכונה שלו | בצוות לא מגן: הרצות במקביל דורסות את ה-state |
נעילה דרך שירות מנוהל DynamoDB
טבלה עם מפתח לפי שם ה-state, כתיבה מותנית ושדה זמן חיים — הנעילה מוצבת אטומית, ואין צורך להרים ולתחזק את השירות בעצמך. הרשאות ניתנות באמצעות policy גישה, ותוכן הטבלה נקרא בעין, מה שמקל על פירוק הרצות תקועות. מגבלת המנגנון: אם התהליך נקטע, סימן הנעילה נשאר ומוסר בפקודה נפרדת ידנית.
נעילה דרך Consul
הסשן קשור לסוכן: הסוכן נפל — המפתח התפנה מעצמו, אין צורך בהתערבות ידנית. זה נוח אם Consul כבר מתוחזק בסביבה: לא נוצרת תלות ענן שנייה ולא סט הרשאות שני. המחיר — תחזוקת cluster: קוורום, גיבויים, עדכונים.
מגבלה משותפת לכל האפשרויות: הנעילה מגנה מפני כתיבה בו-זמנית, אבל לא מפני פגיעה ב-state עצמו — גרסאות באחסון וגיבויים קבועים נשארים חובה.
שלבי הטמעת נעילת state בצוות
נעילת state היא לא אפשרות «להפעיל ולשכוח»: היא משנה את סדר העבודה של הצוות, ולכן מטמיעים אותה בהדרגה. להלן מסלול ההגדרה למקרה שבו יותר ממהנדס אחד משתמש ב-state או שימוש בצינור בנייה.
ביקורת של ה-state הנוכחי ונקודות יישום בו-זמני
- אוספים מפת backends. מתעדים היכן נמצא קובץ ה-state, מי ומאילו סביבות ניגש אליו, והאם יש הרצות מחוץ לצינור.
- מחפשים נקודות יישום בו-זמני. לפי לוגים וסקר בצוות מסמנים היכן הרצות במקביל כבר יצרו קונפליקט או קלקלו את ה-state.
- מגדירים דרישות. מספר הצוותים, הפרדת גישות, זמן חיים של הנעילה, התנהגות בניתוק תקשורת — מזה תלויה בחירת האחסון.
הגדרה ובדיקה בסביבת אימון
- פורסים אחסון נעילות. טבלה ב-DynamoDB או cluster Consul עם policy גישה וזמן שכירות לנעילה.
- מעבירים את ה-backend. מעבירים את ה-state ובודקים שהקריאה והכתיבה עוברות דרך האחסון החדש, ושחזרה אחורה נשארת אפשרית.
- בודקים את הנעילה תחת עומס. שני יישומים במקביל: אחד מקבל נעילה, השני נעצר כראוי עם הודעה מובנת.
- מעבירים את הפתרון לצוות. נוהל קונפליקטים, הוראות להסרת נעילה תקועה, הדרכת מהנדסים ואחראי תורנות.
בסביבת העבודה זה סוגר סוג כשל שבו שני יישומים כותבים מחדש את ה-state והתשתית מתפצלת מהקונפיגורציה.
קונפיגורציות, תרשימים ונוהלים שנשארים אצלכם
אחרי ההטמעה נשארת אצלכם לא רק תשתית עובדת, אלא גם סט ארטיפקטים שאפשר לפתח לפיהם בלי ההשתתפות שלנו. הכול נמצא במערכת בקרת גרסאות, השינויים עוברים בדיקה לפני יישום, וההחלטות שהתקבלו מתועדות לצד הקוד — מהנדס חדש נכנס לפרויקט בלי סיפורים בעל פה.
תרשים אינטראקציה ותיאור הרשאות גישה
- תרשים אינטראקציה: אילו שירותים תלויים זה בזה, היכן עוברים גבולות הרשתות, מה יקרה למערכת בכשל של צומת בודד.
- policy גישה: תפקידים והרשאות לפי עקרון המינימום הנדרש, בנפרד לאנשים ובנפרד לאוטומציה.
- תיאור אחסון ה-state: היכן נמצא קובץ ה-state של Terraform, איזה מנגנון נעילה מגן מפני שינויים בו-זמניים ואיך הוא מתנהג בניתוק תקשורת.
- מפת תלויות חיצוניות: registries של images, אחסוני סודות, נקודות כניסה — עם ציון האחראים.
נוהל עבודה עם ה-state והוראות לצוות
- נוהל עבודה עם ה-state: מי ואיך מסיר נעילה, מה לעשות בקונפליקט ואיך לשחזר state מגיבוי.
- הוראות פריסה וחזרה אחורה: שלב-אחר-שלב, נבדקו בסביבת בדיקות.
- הסכמות למבנה קונפיגורציות: חלוקה למודולים, שמות משאבים, כללי אחסון סודות.
- Checklists לפעולות טיפוסיות: חיבור סביבה חדשה, הוצאת צומת משימוש, רוטציה של מפתחות וגישות.
מקרה בוחן: איך הסרנו יישומי state בקונפליקט
הפרויקט — תשתית מכמה סביבות, שישה מהנדסים וכארבעים שינויים בשבוע. ה-state ישב ב-backend אחד בלי נעילה: שני יישומים בו-זמניים — מהענף ומהמכונה המקומית — כתבו מחדש את אותו קובץ. התוצאה: פער בין ה-state למציאות, משאבים «מיותמים» ופירוק ידני במקום עבודה.
העברנו את ה-state ל-backend מרוחק עם נעילה: Terraform תופס נעילה בטבלת DynamoDB לפני תכנון ומסיר אותה אחרי יישום, ובאתר השני Consul משמש כמתאם. חשוב יותר מהנעילה עצמה היה כלל הפירוק: כשהנעילה תפוסה, המהנדס רואה את הבעלים שלה ומסיר אותה רק אחרי בדיקה שהתהליך באמת לא רץ.
מה השתנה בעבודה היומיומית של הצוות
לפני: בממוצע שני פערי state בשבוע, פירוק — מארבעים דקות עד כמה שעות; פעם אחת שחזור מגיבוי לקח חצי יום עבודה. אחרי: במשך תשעה חודשים — אף יישום בקונפליקט, וזמן היישום הצטמצם מעשרים ואחת דקות לתשע דקות בזכות הרצות חוזרות והמתנה שנעלמו.
נעלם סוג שלם של כשלים: כתיבה מחדש של state ומשאבים שקיימים בענן אבל חסרים בקובץ. השינויים נעשו קטנים ותכופים יותר — זה הפסיק להיות סיכון.
במה שונה state locking ב-DynamoDB וב-Consul?
שני המנגנונים פותרים משימה אחת: לא לאפשר לשתי הרצות לכתוב מחדש state בו-זמנית ולהשאיר את התשתית במצב מיושם חלקית. ההבדל — היכן חי המנעול, מי מסיר אותו בעת כשל, ומה יהיה צריך לתחזק כדי שהנעילה עצמה לא תהפוך למקור לאירועים.
DynamoDB — זו נעילה באמצעות כתיבה: לפני שינוי Terraform מבצע כתיבה מותנית בטבלה עם מזהה הרצה, וניסיון במקביל נדחה. את הטבלה וההרשאות אליה צריך ליצור ולתחזק, אבל אין צורך ב-cluster נפרד — הכול חי באותו מקום שבו ה-state.
ההתנהגות בכשל נוקשה: אם התהליך נקטע או הסוכן מת, הרשומה נשארת, ואפשר להסיר אותה רק בכוח. עד אז כל הבניות עומדות.
Consul — נעילה על סשנים: הסוכן פותח סשן עם זמן מוגבל ומאריך אותו כל הזמן, המנעול קשור לסשן ומתפנה מעצמו כשההארכה נפסקת. אין צורך בהתערבות ידנית בנפילת סוכן, אבל משלמים על זה בתחזוקה: צריך cluster עמיד בכשלים, טוקנים לגישה, בקרה על הסוכנים.
יש גם סיכון הפוך — בכשל רשת ההארכה לא עוברת, והמנעול מוסר בזמן ש-apply עדיין רץ, אם זמן הסשן הוגדר קצר מהיישום הארוך ביותר.
קריטריון מעשי לבחירה — תשתית שכבר פרוסה. במקום שבו ה-state והעומסים חיים בענן, DynamoDB מוסיפה טבלה אחת ולא יותר; להרים Consul רק בגלל נעילה — cluster מיותר בתחזוקה. אם Consul כבר משרת גילוי שירותים, הנעילה מתקבלת בלי תשתית חדשה.
בשני המקרים בוחרים זמן סשן לפי ה-apply הארוך ביותר, ואת סדר הסרת המנעולים התקועים כותבים מראש — כדי לא להתברר אותו ברגע שצינור העבודה עצור.
ספקות טכניים לגבי נעילת state
נעילת state מגנה ממצב שבו שני יישומים כותבים בו-זמנית לאותו קובץ. בהתחלה היא כמעט לא מעוררת שאלות — הן מופיעות בתפעול: להסיר נעילה תקועה, להחליף אחסון, להסכים על כללים למי שעובד מקומית.
היישום נפל, והנעילה נשארה. מה לעשות?
קודם מוודאים שהתהליך באמת מת: מסתכלים על מזהה הבעלים וזמן התפיסה. אם זה ניתוק תקשורת משירות חיצוני, ולא הרצה חיה, מסירים את הנעילה בכוח — אבל רק אחרי בדיקה שאיש אינו מריץ את ה-plan. אחר כך מוסיפים הגבלת זמן המתנה לתפיסה וניסיונות חוזרים, כדי שניתוק רשת לא ידרוש התערבות ידנית.
איך לעבור מאחסון נעילות אחד לאחר בלי השבתה?
את המעבר עושים בשני שלבים: קודם מעבירים את קובץ ה-state ובודקים שה-plan תואם את התשתית בפועל, אחר כך משנים את הגדרות הנעילה וסוגרים את הסביבה הישנה לכתיבה. את המנגנון החדש מריצים מראש בסביבה נפרדת — כולל תרחיש של הרצה בו-זמנית.
חלק מהצוות מיישם קונפיגורציה מקומית — האם זה מותר?
עותקים מקומיים של ה-state הם מבוי סתום: שינויים על המכונה של מהנדס אחד לא נראים לאחרים, ופערים צפים בהחלה הבאה של כולם. אפשרית אפשרות אחת — הרצות מקומיות עובדות עם state משותף ונעילה. ניסויים מוציאים לסביבות נפרדות עם state מבודד.
איך לפרק אירוע אם ה-state כבר נפגע?
מתעדים נקודה: גרסת קובץ ה-state מהאחסון והיסטוריית השינויים. אחר כך משווים משאבים עם ה-plan, מחזירים ל-state אובייקטים שנעלמו ומסירים רשומות מיותרות. לאחר מכן — הגנה מפני הסרת נעילה בכוח ואיסור יישומים מעותקים מקומיים.
נדבר על המשימה: נתאים סכמת נעילה לצוות שלכם
אי אפשר להגדיר נעילת state לפי תבנית: אותה סכמה בדיוק לשני מהנדסים ולעשרים נותנת תוצאה שונה. לכן לפני הערכה ותוכנית עבודה אנחנו מפרקים את הסביבה שלכם ותנאי התפעול, ולא מציעים פתרון מוכן מהקטלוג.
- כמה מהנדסים עובדים עם ה-state בו-זמנית והאם יש הרצות אוטומטיות — מזה תלוי עד כמה הנעילה צריכה להיות רגישה לקונפליקטים.
- באיזו תדירות התשתית משתנה: תיקונים נדירים וזרימת שינויים רציפה דורשים זמן החזקת נעילה שונה ותגובה שונה למקרים תקועים.
- איזה מנגנון משמש עכשיו — קובץ מקומי, נעילה באחסון ענן או Consul — ואילו כשלים כבר הובילו לפער ב-state.
- הרשאות וגישות: למי יש זכות להסיר נעילה תקועה, איך זה מתועד בלוגים ומי מקבל התראה על ההסרה.
- האם נדרשת הפרדה לפי סביבות — בדיקות, קדם-פרודקשן ופרודקשן ננעלים בנפרד או במנגנון אחד עם הפרדת גישות.
- סדר מסירת הפתרון: קונפיגורציות, סכמת עבודה, נוהל הסרת נעילה והוראה למהנדס תורן.
תארו את המשימה בגדול — נחזור עם הערכה ותוכנית עבודה ונתאים סכמת נעילה לצוות שלכם.







