Ansible הוא אחד מכלי (Configuration Management (CM. היום נדבר בהרחבה על הכלי הזה, על היתרונות שלו ועל השימוש בו.
במאמר על ה-CAMS model דיברנו בין היתר על החשיבות של automation. לפעמים נרצה כל מיני קונפיגורציות עבור סביבות מסוימות וקונפיגורציות מסוימות עבור שרתים/רכיבים אחרים. automation היא אחת מאבני הבניין החשובות של CM. בעזרתה, אפשר לממש באופן מוחלט Infrastructure As Code (הקמת תשתית בלחיצת כפתור) למגוון רחב של דברים כגון: יצירת יוזרים, יצירת db, קנפוג שרת web, התקנת תוכנות ועוד.
כל הדברים האלו הם דברים שאפשר לעשות עם סקריפטים. אבל סקריפט לא יספק דיבוג נוח (וזה חיוני במקרה של בעיה, במיוחד כשמתעסקים בקונפיגורציות).
מושג חשוב מאוד בעולם ה-CM הוא Idempotent. משמעות המושג היא ביצוע פעולה מספר פעמים כך שהתוצאה של הפעולה תהיה זהה בכל הפעמים. דוגמא לפעולה כזאת היא לחיצה על הכפתור שמדליק את האור (האור יישאר דלוק בין אם הוא היה דלוק לפני ובין אם לא).
דוגמא לפעולה לא Idempotent היא הרצת סקריפט שמפרסם הודעה באתר. כל פעם שנריץ אותו תפורסם הודעה באתר, במידה והיא כבר פורסמה – היא תפורסם שוב. כשמדברים על CM, חשוב שהפעולות יהיו Idempotent כדי שנוכל לגזור מזה את ה-state המדויק לגבי כל קונפיגורציה.
Ansible Installation
ניתן להתקין ansible במגוון דרכים וזה מאוד פשוט. אפשר באמצעות pip:
pip install ansible
אפשרות נוספת היא להתקין Ansible באמצעות ה-package manager
שימו לב שאי אפשר להתקין Ansible על Windows. עם זאת, כן אפשר להשתמש ב-Ansible כדי לקנפג דברים ב-Windows
Ansible Characteristics
דבר עיקרי אחד שמייחד את Ansible הוא agentless. אין צורך להתקין agent על מכונה אחרת כדי להצליח להתחבר עליה. לכן, הדברים ש-Ansible צריכה כדי לתפקד כראוי הם:
- התקנת התוכנה של Ansible על השרת שיישמש כ-Master.
- חיבור תקין לשרת שנרצה לקנפג (ה-Client).
ישנם שני סוגי חיבורים עיקריים ש-Ansible תומכת בהם:
- חיבור ssh (פרוטוקול מוכר עבור תקשורת בטוחה למחשבים מרוחקים). זה עבור חיבורים לשרתים שמערכת ההפעלה שלהם אינה Windows.
- WinRM (פרוטוקול שמאפשר להתחבר ל-Windows שמתקשר מעל http/https).
Ansible Playbook
מדובר בקובץ בפורמט YAML שמכיל סט של פקודות שנרצה שירוצו על המכונות שלנו.
קובץ כזה יהיה מחולק ל Task-ים שיתבצעו. נוכל גם להתנות את ה-task במגוון תנאים.
Ansible Inventory File
כשמריצים playbook המכונות שעליהם נרוץ יהיו אלה שרשומות ב /etc/ansible/hosts. בעזרת flag של i- ניתן גם לטעון את המכונות מקובץ אחר שנכתוב (הפורמט של הקובץ הזה יכול להיות בפורמט ini או בפורמט yaml).
דוגמא לקובץ Inventory בפורמט ini:
הגדרנו קבוצת שרתים ששמה web. תחת הקבוצה הזאת יושב כרגע שרת אחד ופרטיו:
- ה-ip שלו.
- שם משתמש עם הרשאות root.
- סיסמא של השם משתמש הזה.
קצת על YAML
yaml הוא פורמט שגם בני אדם וגם מחשבים יכולים לקרוא. המידע בקובץ כזה מאוחסן בתצורת key: value. משתמשים רק ב-spaces, לא ב-tabs.
ככה ניתן ליצור חלוקה ברורה ונוחה של מידע, דוגמא:
People: - Name: avi Age: 39 Height: 1.80 - Name: Ronit Age: 34 Height: 1.67
כשרושמים קבצי YAML מומלץ להשתמש בעורך קוד נוח (כמו Atom או ++Notepad). כך אפשר להפחית את הסיכוי שיהיו בעיות בפרסור של הקובץ כמו רווחים לא צפויים.
דוגמא לפעולה Idempotent ב-Ansible:
ראשית, אנחנו רואים פה task שהוא חלק מ-playbook.
מה קורה ב-task?
- הגדרת השם של ה-task.
- שימוש במילה השמורה service על מנת לקנפג אותו.
- שם ה-service. השם הוא httpd שזה בעצם apache (שרת web).
- ה-state שנרצה שהוא יהיה בו (פעולה Idempotent). במקרה הזה נרצה שהוא יישאר רץ.
דוגמא ל-Ansible Playbook
הסבר:
השם של ה-play הוא play1.
Hosts מתייחס לקבוצת השרתים שעליה נרצה להריץ את ה playbook – במקרה שלנו זה רק על localhost.
אם היינו רוצים להריץ את ה-Play על כל ה-host-ים ב-inventory file היינו שמים hosts: all. בנוסף, כמו שראינו אפשר גם להגדיר קבוצה של host-ים ואז לקרוא לה מה-Playbook.
יש לנו שלוש task-ים ולכל אחד שם ייחודי:
- ב task הראשון נריץ את הפקודה date.
- המשמעות של ה-task השני היא הרצת yum install httpd.
- ב task השלישי נתחיל את ה-service של httpd.
כדאי לפצל playbook לכמה שיותר task-ים כדי שיהיה יותר קל לדבג באגים. אם באותו playbook נרצה לבצע הרבה דברים ויש משמעות להפרדת הלוגיקה שלהם, נוכל לחלק אותו לכמה Plays וכל אחד מהם יכיל בתוכו task-ים.
Conditions
מה אם אנחנו לא יודעים מראש על איזה מערכות הפעלה נרוץ ונרצה להתנות את ה-task בזה?
נוכל לעשות משהו כזה:
ה-task יתקין את החבילה https רק אם ה-Playbook ירוץ על שרת Linux שמותקן עליו centos או suse.
Loops
לפעמים נרצה לעשות פעולות בצורה מחזורית. הנה דוגמא לשילוב לולאה עם תנאי ב-Ansible:
- הגדרנו משתנה בשם packages שמתפקד כרשימה שמכילה שני שמות של חבילות והאם הם required.
- יצרנו task שמתקין אותם.
- ה-task רץ בלולאה שעוברת על כל ה-package-ים (בדוגמא שלנו יש שניים).
- בתנאי when הגדרנו שכל עוד required == true עבור ה-package, נבצע עבורו התקנה עם yum.
בסוף ריצת ה-Playbook שני החבילות אמורות להיות מותקנות.
לסיכום, דיברנו בהרחבה על CM, על החשיבות של הקונספט הזה ולמה אנחנו צריכים לשאוף לאוטומציה עבור הקמת סביבות וקונפיגורציות. התמקדנו ב-Ansible והבנו מה היתרונות שלו, פיצ’רים מרכזיים שהוא תומך בהם ואיך משתמשים בו.
מדריך מעולה, תודה רבה וכל הכבוד
אדיר!