מדריך Ansible: הקמת שרת VPS ראשון עם Playbook
למדו להתקין Ansible עם pipx ב-Ubuntu 24.04, להגדיר inventory ו-Playbook לאבטחת VPS חדש, ולפתור Permission denied ושגיאות sudo.
מה תבנו
מכונת בקרה אחת עם Ansible מותקן, ושרת VPS אחד או יותר עם Ubuntu 24.04 שהותקנה עליהם תמונת ברירת המחדל בלבד. בסוף התהליך יהיה ברשותכם קובץ inventory שמגדיר את השרתים, פקודת ping אד־הוק שמוכיחה שהאימות פועל מקצה לקצה, ו־playbook שמבצע כקוד את כל רשימת הבדיקות לשרת VPS חדש: משתמש פריסה עם מפתח ה־SSH שלכם, sshd מוקשח, fail2ban, עדכונים ללא השגחה, וחומת אש שמאפשרת OpenSSH לפני שהיא חוסמת כל דבר אחר. אפשר להפעיל אותו על שרת אחד או על עשרים. בהפעלה השנייה לא יחול שום שינוי. זו כל המטרה.
לאחר חמש־עשרה שנים של הקמת שרתי VPS, התבנית ברורה: כולם מגדירים ידנית את חמשת השרתים הראשונים, ואז מאבדים סוף שבוע על השרת השישי, משום שאיש אינו זוכר מה נעשה בחמשת הראשונים. המדריך הזה מעמיק את הסקירה בנושא ניהול שרתי Linux מרובים. חזרו אליו ברגע שאתם תופסים את עצמכם מקלידים את אותו apt install בשלושה מסופים.
מה Ansible באמת, בפסקה אחת
Ansible פועל ללא agent. אין צורך להתקין daemon בשרתים שהוא מנהל: מכונת הבקרה מתחברת באמצעות SSH רגיל, מעתיקה מודול Python קטן ליעד, מפעילה אותו, קוראת את ה־JSON שהוא מדפיס ומוחקת אותו. הדבר היחיד שהיעד זקוק לו הוא python3, שכבר קיים בכל image סטנדרטי של Ubuntu. המונח החשוב הוא idempotent, ומשמעותו פשוטה: משימה מתארת מצב, ולא פעולה. state: present עבור package פירושו "לוודא שהוא מותקן", ולא "להפעיל את תוכנית ההתקנה". אם המצב כבר מתקיים, Ansible אינו משנה דבר ומדווח על המשימה כ־ok במקום כ־changed. תכונה זו היא מהות המוצר: היא הופכת הפעלה חוזרת של playbook לבטוחה, והפעלות חוזרות בטוחות הן שהופכות shell script לתשתית.
דרישות מוקדמות, והמלכודות שכדאי להכיר מראש
- מכונת בקרה: המחשב הנייד שלכם או VPS קטן. ההנחה היא שאתם משתמשים ב־Ubuntu 24.04; macOS פועל באופן זהה לאחר התקנת
pipxבאמצעות Homebrew. - VPS יעד אחד או יותר, המריצים Ubuntu 24.04 על KVM, ונגישים באמצעות המשתמש
root. לא יותקן בהם דבר. - אימות באמצעות מפתח SSH מול כל יעד. Ansible משתמש בדיוק באותם פרטי אימות שבהם משתמשת הפקודה
ssh; אםssh root@hostמבקשת סיסמה, Ansible נכשל. - ב־Ubuntu 24.04,
pip install ansibleנכשלת עםerror: externally-managed-environment. זו מדיניות מכוונת של ההפצה, ולא תקלה. השתמשו ב־pipx. - רווחים ויישור ב־YAML הם חלק מהתחביר. הזחה שגויה גורמת ל־
mapping values are not allowed in this context, ותו Tab בכל מקום גורם לכשל. - השאירו חיבור SSH פעיל בכל יעד בזמן שה־playbook מקשיח את sshd. בכל אירוע נעילה שממנו סייעתי ללקוח להתאושש, החיבור האחרון נסגר כדי "לבדוק מחיבור נקי".
שלב 1: התקנת Ansible על מכונת הבקרה באמצעות pipx, ולא באמצעות pip
האינסטינקט הקלאסי הוא pip3 install ansible. בתמונה נקייה של 24.04, פעולה זו נכשלת בשלב מוקדם, Command 'pip3' not found, but can be installed with: sudo apt install python3-pip, והתקנת pip רק מובילה אתכם למחסום האמיתי:
pip3 install ansibleerror: externally-managed-environment
× This environment is externally managed
╰─> To install Python packages system-wide, try apt install
python3-xyz, where xyz is the package you are trying to
install.Ubuntu 24.04 מסמנת את ה-Python של המערכת כ"מנוהל חיצונית" (PEP 668), ולכן pip אינו יכול להתנגש עם apt על אותם קבצים. אל תשתמשו ב---break-system-packages; שם הדגל מעיד על תפקידו. הפתרון הנקי הוא pipx, שמעניק ל-Ansible סביבת virtualenv מבודדת משלו ומציב את הבינאריים ב-PATH שלכם:
sudo apt update && sudo apt install -y pipx
pipx ensurepath
pipx install --include-deps ansibleפתחו shell חדש לאחר pipx ensurepath כדי שהשינוי ב-PATH ייכנס לתוקף. --include-deps אינו קישוט: חבילת ה-ansible אינה כוללת סקריפטים לקונסולה משל עצמה; ansible, ansible-playbook והשאר הם נקודות כניסה של התלות ansible-core שלה, לכן ללא הדגל, pipx מסרב לבצע את ההתקנה עם No apps associated with package ansible. ומנחה אתכם לנסות שוב עם --include-deps. התקינו את חבילת ה-ansible, ולא את ansible-core החשופה; החבילה המלאה כוללת את אוספי הקהילה (community collections), וספריית ה-playbook הזו משתמשת במודולים מתוך שניים מהם (ansible.posix ו-community.general).
ansible --versionנכון ל-2026-10-11, התקנה נקייה מושכת את חבילת ה-ansible בגרסה 14.5.0, שנועלת את ansible-core לגרסה 2.21.5, כך שהתוצאה התקינה נפתחת ב-ansible [core 2.21.5] ומציינת את ה-Python שבו היא רצה; כל גרסת core עדכנית תתאים לכל מה שמופיע כאן. Core 2.21 דורש Python 3.12 ומעלה על מכונת הבקרה, וזה בדיוק מה ש-Ubuntu 24.04 מספקת. אם התקנה ישנה עדיין מדווחת על core 2.19, דעו שסדרת 2.19 מגיעה לסוף חייה בנובמבר 2026. ansible: command not found משמעותו ש-~/.local/bin עדיין לא נמצא ב-PATH שלכם, נדרש shell חדש, או ש-source ~/.bashrc.
זוהי ההתקנה כולה. מכונות היעד אינן מקבלות דבר.
שלב 2: גישה באמצעות מפתח SSH לכל יעד
ssh-keygen -t ed25519 -C "ansible control"
ssh-copy-id root@10.0.0.10
ssh-copy-id root@10.0.0.20לאחר מכן הוכיחו זאת, פעם אחת עבור כל מארח:
ssh root@10.0.0.10 true && echo okשורה זו מבצעת שתי פעולות: היא מאשרת שאימות באמצעות מפתח פועל ללא סיסמה, ומתעדת את מפתח המארח ב־known_hosts. בצעו זאת כעת, משום ש־Ansible מציג מפתח מארח שלא תועד כהנחיה אינטראקטיבית באמצע ההרצה. מצב כזה נראה בדיוק כמו תקיעה.
שלב 3: ה־inventory, קודם INI, ו־YAML כשהוא מתרחב
ה־inventory הוא קובץ טקסט שמפרט את המכונות ש־Ansible רשאי לפעול עליהן. צרו את inventory.ini בספריית פרויקט חדשה:
[vps]
web1 ansible_host=10.0.0.10
web2 ansible_host=10.0.0.20
[vps:vars]
ansible_user=rootweb1 הוא כינוי שתבחרו. הוא יופיע בפלט, ובאמצעותו תבחרו את היעד של --limit web1. ansible_host היא הכתובת בפועל. [vps] היא קבוצה, ו־[vps:vars] מגדיר משתנים לכל השרתים שבה; ansible_user הוא המשתמש ש־Ansible מתחבר באמצעותו. הוסיפו לצדו ansible.cfg, כדי שלא תצטרכו להקליד שוב את -i:
[defaults]
inventory = inventory.iniAnsible קורא את ansible.cfg מהספרייה הנוכחית. כדי להשתמש באותו inventory בפורמט YAML, שמרו אותו בשם inventory.yml והפנו את ansible.cfg לשם זה. אפשרות זו עדיפה כאשר לכל מארח יש כמה משתנים:
vps:
hosts:
web1:
ansible_host: 10.0.0.10
web2:
ansible_host: 10.0.0.20
vars:
ansible_user: rootשני הפורמטים שקולים. INI נוח יותר לבדיקה מהירה כאשר יש שני שרתים; YAML מתאים יותר לעשרים שרתים. בחרו פורמט אחד והמשיכו הלאה.
שלב 4: פקודות ad-hoc, ה־pong הירוק שמוכיח שהכול פועל
ansible all -m pingאין כאן שימוש ב־ICMP. המודול ping הוא חזרה מלאה לקראת ההרצה: התחברות ב־SSH, העתקת המודול, הרצת Python ביעד וניקוי. התוצאה התקינה היא ירוקה, עם בלוק אחד לכל מארח:
web1 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}תוצאה ירוקה של SUCCESS פירושה שהאימות, מפרש Python והעברת הנתונים פועלים, ולכן גם ה־playbook יפעל. תוצאה אדומה של UNREACHABLE! פירושה שההעברה נכשלה לפני שהמודול הופעל; המחרוזת המדויקת והפתרון מופיעים בסעיף מצבי הכשל שבהמשך. כדאי להכיר גם שתי פקודות ad-hoc נוספות:
ansible all -a "uptime"
ansible all -m apt -a "update_cache=true upgrade=dist" --becomead-hoc מיועד לפעולות חד־פעמיות ולבדיקות. כל פעולה שתפעילו פעמיים צריכה להיכלל ב־playbook.
שלב 5: הפלייבוק הראשון, רשימת הבדיקה של VPS חדש כקוד
זה כל מה שהייתם מבצעים ידנית בעשר הדקות הראשונות בשרת חדש. שמרו זאת בשם site.yml:
---
- name: Baseline a fresh Ubuntu VPS
hosts: vps
become: true
vars:
deploy_user: deploy
deploy_pubkey: "{{ lookup('file', '~/.ssh/id_ed25519.pub') }}"
baseline_packages:
- fail2ban
- unattended-upgrades
- ufw
baseline_services:
- fail2ban
- unattended-upgrades
tasks:
- name: Create the deploy user
ansible.builtin.user:
name: "{{ deploy_user }}"
groups: sudo
append: true
shell: /bin/bash
- name: Install the deploy user's SSH key
ansible.posix.authorized_key:
user: "{{ deploy_user }}"
key: "{{ deploy_pubkey }}"
- name: Passwordless sudo for the deploy user
ansible.builtin.copy:
dest: /etc/sudoers.d/deploy
content: "{{ deploy_user }} ALL=(ALL) NOPASSWD:ALL\n"
mode: "0440"
validate: /usr/sbin/visudo -cf %s
- name: Install baseline packages
ansible.builtin.apt:
name: "{{ baseline_packages }}"
state: present
update_cache: true
- name: Enable and start baseline services
ansible.builtin.service:
name: "{{ item }}"
state: started
enabled: true
loop: "{{ baseline_services }}"
- name: Harden sshd with a drop-in
ansible.builtin.copy:
dest: /etc/ssh/sshd_config.d/00-hardening.conf
content: |
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin prohibit-password
X11Forwarding no
mode: "0644"
validate: /usr/sbin/sshd -t -f %s
notify: Restart ssh
- name: Allow OpenSSH through ufw
community.general.ufw:
rule: allow
name: OpenSSH
- name: Enable ufw with default deny
community.general.ufw:
state: enabled
policy: deny
handlers:
- name: Restart ssh
ansible.builtin.service:
name: ssh
state: restartedאלה השורות שכדאי להבין במקום להעתיק:
משתנים נמצאים תחת vars:, ומפנים אליהם באמצעות "{{ deploy_user }}". יש לתחום במירכאות את הביטוי כולו כאשר ערך מתחיל בסוגר מסולסל, אחרת מנתח YAML עלול לפרש אותו באופן שגוי. lookup('file', ...) קורא בזמן הריצה את המפתח הציבורי מהמחשב ה־control, ולכן הפלייבוק אינו כולל חומר מפתח.
הלולאה. loop: "{{ baseline_services }}" מריץ את משימת השירות פעם אחת לכל פריט, והפלט מציג כל פריט בשורה נפרדת. שימו לב שמשימת apt מקבלת את רשימת החבילות כולה בפעולה אחת. עסקת apt אחת מהירה יותר, וזהו הדפוס המועדף להתקנת חבילות; לולאות מיועדות למודולים שבאמת פועלים בכל פעם על פריט אחד.
ה־handler הוא המושג שחשוב להפנים. notify: Restart ssh אינו אומר "להפעיל מחדש את ssh עכשיו". הוא מצרף את ה־handler לתור, והוא מופעל פעם אחת בסוף ה־play, ורק אם המשימה שהודיעה עליו דיווחה בפועל על changed. אם תריצו את הפלייבוק שוב מחר, קובץ ה־drop-in כבר יהיה תקין, משימת ההעתקה תדווח על ok, ו־sshd לא יופעל מחדש. השורה validate: מספקת את שכבת הבטיחות בטריגר: sshd בודק את הקובץ לפני שהוא מחליף את הקובץ הישן, ולכן שגיאת כתיב תכשיל את המשימה במקום להשבית את ה־daemon.
PermitRootLogin prohibit-password, ולא no, בכוונה. הפלייבוק הזה מתחבר כ־root באמצעות מפתח. prohibit-password משבית התחברויות root באמצעות סיסמה, תוך שמירה על החיבור שלכם פעיל. לאחר שתוודאו שמשתמש הפריסה פועל כראוי (ssh deploy@10.0.0.10 sudo true, הכתובת הפשוטה, משום ש־web1 הוא כינוי ש־Ansible בלבד מכיר), החליפו את ansible_user=deploy במלאי והקשיחו אותו ל־no בהרצה מאוחרת יותר. בצעו את ההקשחה בסדר שאינו עלול לנעול אתכם מחוץ לשרת.
הקידומת 00- חשובה. עבור רוב מילות המפתח, sshd מכבד את המופע הראשון שהוא מנתח, ו־sshd_config של Ubuntu כולל את sshd_config.d/*.conf בסדר לקסיקוגרפי, לפני גוף הקובץ שלו. תמונות הענן של Ubuntu 24.04 כבר כוללות 60-cloudimg-settings.conf בתיקייה זו, וספקים שמאפשרים התחברויות באמצעות סיסמה דרך cloud-init מוסיפים 50-cloud-init.conf עם PasswordAuthentication yes. מתן השם 00-hardening.conf לקובץ שלנו גורם לו להופיע ראשון בסדר המיון ולגבור על שניהם.
סדר המשימות הוא מנגנון הבטיחות של ה־firewall. Allow OpenSSH מופעל לפני Enable ufw עם מדיניות deny. Ansible מבצע את המשימות בדיוק לפי הסדר שבו הן מופיעות, ולכן הפרצה קיימת לפני שהחומה מופעלת. fail2ban אינו זקוק כאן לתצורה כדי להיות שימושי; ברירות המחדל שלו ב־Ubuntu מנטרות את sshd ללא הגדרה נוספת. הפעולות שה־jails מבצעים בפועל וההגדרות שכדאי לכוונן מתוארות ב־מדריך fail2ban ב־Ubuntu 24.04.
שלב 6: הרצה מקדימה באמצעות --check, ולאחר מכן הרצה בפועל
ansible-playbook site.yml --checkמצב בדיקה מתחבר, מחשב מה הוא היה מבצע, ואינו משנה דבר. קראו את מונה ה־changed= ב־PLAY RECAP שבתחתית. זהו מספר המשימות שהיו משנות כל שרת. חשוב להכיר במגבלה אחת: למצב בדיקה יש מגבלה מבנית כאשר משימה מאוחרת תלויה בשינויים שביצעה משימה קודמת. תמונת השרת הסטנדרטית של Ubuntu כוללת מראש את ufw, ולכן הרצה מקדימה של ה־playbook הזה מסתיימת ללא שגיאות. עם זאת, בתמונה מינימלית שאינה כוללת אותו, משימות ufw נכשלות במצב בדיקה, משום שמצב זה אינו מתקין בפועל את החבילה, ולמודול אין דבר להפעיל. זו מגבלה של הרצות מקדימות, ולא באג ב־playbook. כאשר התוכנית נראית נכונה:
ansible-playbook site.ymlכל משימה מדפיסה שורה עבור כל שרת: changed בצהוב, ok בירוק, ותקציר ההרצה אמור להיראות כך:
PLAY RECAP *********************************************************************
web1 : ok=10 changed=9 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
web2 : ok=10 changed=9 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0עשרת ok כוללים איסוף עובדות, שמונה משימות ואת ה־handler. ה־changed שלכם יכול להיות שונה מזה שלי באחד או שניים. תמונת השרת הסטנדרטית של Ubuntu כוללת מראש את ufw ואת unattended-upgrades, ו־fail2ban מופעל מיד לאחר ש־apt מתקין אותו. לכן משימה יכולה לדווח באופן תקין על ok כבר בהרצה הראשונה, משום שהמצב שהיא מגדירה כבר התקיים. המונים שחייבים להיות אפס הם unreachable ו־failed. הערה לגבי become: true: זהו עניין פורמלי כל עוד אתם מתחברים כ־root. אולם ברגע שתשנו את ansible_user ל־deploy, sudo נכנס לשימוש בפועל, וקובץ ה־sudoers עם NOPASSWD שה־playbook הזה מתקין הוא שמונע את הופעת -K בשורת הפקודה. בלעדיו תקבלו Missing sudo password, כפי שמוסבר בהמשך.
שלב 7: להפעיל פעמיים ולראות כיצד נראית אידמפוטנטיות
הפעילו שוב מיד את אותה פקודה:
web1 : ok=9 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0changed=0 ו־ok קטנו באחד, משום שה־handler שלא קיבל התראה לא הופעל. שום דבר לא הותקן מחדש, sshd לא הופעל מחדש, ו־ufw לא שונה. כך ה־playbook משמש גם כ־audit וגם ככלי להקצאת תצורה: הוסיפו בחודש הבא את web3 ל־inventory והפעילו שוב. השרת החדש יוגדר, והשרתים הקיימים יאומתו. ערך שאינו אפס של changed בשרת שלא שיניתם מצביע על drift, ומראה שמישהו ערך ידנית הגדרה שהיה צריך לערוך ב־playbook.
מכאן התבנית מתרחבת. ה־playbook הבא שכדאי לכתוב מתקין VPN של WireGuard באותו VPS ומחמיר את כלל ufw, כך ש־SSH יענה רק דרך המנהרה. לאחר מכן כדאי לכתוב playbook שמתקין Docker ו־Compose בכל שרת יישומים. כאשר site.yml עובר את גבול שלושה המסכים, פצלו אותו ל־roles, אך לא לפני כן.
מצבי כשל והודעות השגיאה הנלוות
UNREACHABLE עם Permission denied.
web1 | UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh: root@10.0.0.10: Permission denied (publickey).",
"unreachable": true
}תעבורת ה-SSH נכשלה לפני הרצת מודול כלשהו: ansible_user שגוי, המפתח לא הועתק למארח היעד, או שמוצע מפתח שגוי. שחזרו את הבעיה באמצעות ssh root@10.0.0.10 רגיל, ולאחר מכן השתמשו ב-ssh -v כדי לראות אילו מפתחות הוצעו. אם התחברות SSH עם סיסמה עובדת אך Ansible לא, סימן שדילגתם על ssh-copy-id.
חסרה סיסמת sudo.
web1 | FAILED! => {
"msg": "Missing sudo password"
}הגדרתם את become: true, התחברתם כמשתמש שאינו root, ומשתמש זה דורש סיסמה עבור sudo. הוסיפו את -K (--ask-become-pass) לשורת הפקודה, או הגדירו למשתמש הרשאת NOPASSWD ב-sudoers; זו בדיוק הסיבה שה-playbook מתקין הרשאה כזו עבור deploy עוד לפני המעבר למשתמש זה.
error: externally-managed-environment. הרצתם pip מול ה-Python של המערכת ב-Ubuntu 24.04. הנושא טופל בשלב 1: השתמשו ב-pipx, לא ב-pip, ובטח שלא ב---break-system-packages.
mapping values are not allowed in this context.
ERROR! Syntax Error while loading YAML.
mapping values are not allowed in this contextכמעט תמיד מדובר בבעיית הזחה (indentation): מפתח שנמצא בעומק שגוי, או רווח חסר אחרי נקודתיים. מספר השורה המדווח מצביע על אזור השגיאה, לא בהכרח על השורה המדויקת; בדקו גם את השורה שמעל. השגיאה הקרובה found character '\t' that cannot start any token מעידה על שימוש ב-tab; פורמט YAML אוסר על כך. הפכו את ansible-playbook site.yml --syntax-check להרגל לפני כל הרצה, והגדירו את העורך שלכם להזחה של שני רווחים עבור קובצי YAML.
/usr/bin/python3: not found. נדיר בתמונות מערכת סטנדרטיות של Ubuntu 24.04, אך נפוץ בתמונות מינימליות או ב-netboot: הרצת המודול נכשלת כי בשרת היעד אין Python. בצעו אתחול (bootstrap) באמצעות המודול raw, אחד המודולים הבודדים שאינם דורשים Python בצד המרוחק (script הוא האחר), והוא מיועד להעברת פקודה ישירות: ansible all -m raw -a "apt-get update && apt-get install -y python3" --become, ולאחר מכן הריצו שוב את ה-playbook.
FAQ
האם עליי להתקין את Ansible בשרתים שהוא מנהל?
לא. Ansible פועל ללא סוכן: מכונת הבקרה מעבירה מודולי Python קטנים באמצעות SSH, מפעילה אותם ומסירה אותם. בשרת היעד נדרשים רק python3 וגישה באמצעות SSH, ושניהם כבר זמינים בתמונות Ubuntu רגילות. ההתקנה היחידה בכל המדריך הזה מתבצעת במכונת הבקרה.
מדוע Ansible מציג "Permission denied (publickey)"?
הבלוק UNREACHABLE! עם Permission denied (publickey) מציין שאימות ה־SSH נכשל לפני ש־Ansible הריץ פעולה כלשהי. בדקו ש־ansible_user במלאי תואם לחשבון שהגדרתם בפועל, שהרצתם ssh-copy-id מול השרת הזה, ושפקודת ssh user@host רגילה מתחברת ללא סיסמה. כל תיקון לפקודת ה־ssh הרגילה יתקן גם את Ansible, משום ששניהם משתמשים באותו ערוץ תעבורה.
מה פירוש המונח idempotent ב־Ansible?
משימה מצהירה על מצב רצוי, כגון "החבילה מותקנת" או "השורה נמצאת בקובץ", במקום להצהיר על פעולה שיש לבצע. אם המצב כבר קיים, Ansible אינו עושה דבר ומדווח ok במקום changed. לכן הרצה של playbook בפעם השנייה מציגה changed=0, ולכן הרצה חוזרת היא בדיקת מצב בטוחה ולא התקנה מחדש הכרוכה בסיכון.
האם עליי להשתמש ב־pip או ב־pipx כדי להתקין את Ansible ב־Ubuntu 24.04?
ב־pipx. Ubuntu 24.04 מסמן את Python של המערכת כמנוהל חיצונית, ולכן pip install ansible נכשל עם error: externally-managed-environment, בהתאם לתכנון. pipx install --include-deps ansible מתקין את Ansible בתוך virtualenv מבודד ומוסיף את ansible, ansible-playbook ואת שאר הכלים ל־PATH באופן מסודר.
מה ההבדל בין החבילות ansible ו־ansible-core?
ansible-core הוא המנוע, וכולל רק את מודולי ansible.builtin. החבילה ansible כוללת את הליבה ואת אוספי הקהילה שנבחרו, ובהם ansible.posix (מודול authorized_key) ו־community.general (מודול ufw), ששניהם משמשים במדריך הזה. התחילו בחבילה המלאה. עברו ל־core ולאוספים שנבחרו ידנית רק כאשר יש לכך סיבה.