Ansible playbook आणि role मधील फरक: कधी काय वापरावे?
Ansible playbook आणि role मधील मुख्य फरक जाणून घ्या. साध्या कामांसाठी फ्लॅट प्लेबुक कधी पुरेसे असते आणि कोडची व्याप्ती वाढल्यावर role ची रचना कशी करावी, याची सविस्तर माहिती.
Ansible playbook आणि role मधील फरक
Ansible playbook ही अशी फाईल आहे जी तुम्ही ansible-playbook वापरून रन करता. ती होस्ट्सच्या समूहाला त्यांच्यावर करायच्या कामांशी जोडते. Ansible role म्हणजे एका ठराविक रचनेची डिरेक्टरी असते, ज्यामध्ये tasks, templates, handlers आणि default variables असतात. Playbook त्याला नावाने कॉल करते. या दोन्हीमधील task syntax एकसारखीच असते, त्यामुळे तुम्ही काय करू शकता हा प्रश्न नाही. हा प्रश्न पुनर्वापराचा (reuse) आहे.
सुरुवात एका साध्या playbook पासून करा. एका site.yml मध्ये tasks: ची यादी असणे हे तुमच्या पहिल्या ऑटोमेशनसाठी योग्य स्वरूप आहे आणि ते बऱ्याच काळापर्यंत पुरेसे ठरते. जेव्हा कामांचा तोच संच दुसऱ्या होस्ट्सच्या समूहासाठी चालवावा लागतो, किंवा फाईलची लांबी साधारण 100 ओळींच्या पुढे जाते आणि स्क्रोल करून task शोधणे कठीण होते, तेव्हा त्याचे रूपांतर role मध्ये करा.
जर तुम्ही अजून एकही playbook लिहिली नसेल, तर एका सिंगल VPS साठी पहिल्या playbook पासून सुरुवात करा आणि जेव्हा ती मोठी होऊ लागेल तेव्हा पुन्हा येथे या.
फ्लॅट प्लेबुक कधी योग्य असते
जेव्हा काम एकदाच करायचे असते, एकाच होस्टवर करायचे असते किंवा ते प्लेबुक इतर कोणीही वाचणार नसेल, तेव्हा फ्लॅट प्लेबुक वापरणे योग्य ठरते. एखादा सिंगल ॲप्लिकेशन सर्व्हर प्रोव्हिजन करणे किंवा मेंटेनन्स विंडोच्या आधी एखादा सर्व्हर पॅच करणे, या कामांसाठी डिरेक्टरी ट्रीची गरज नसते. एक रोल तयार केल्यास सात डिरेक्टरीज आणि एक अतिरिक्त लेयर (indirection) वाढतो. जर त्या रोलला कॉल करणारे एकमेव प्लेबुक त्याच्या शेजारीच असेल, तर त्या अतिरिक्त लेयरचा काहीही फायदा होत नाही; उलट, प्रत्यक्ष काय रन होत आहे हे पाहण्यासाठी तुम्हाला प्रत्येक वेळी एक जंप (jump) घ्यावी लागते.
फ्लॅट प्लेबुक वापरणे कधी थांबवावे, हे एका विशिष्ट क्षणी स्पष्ट होते आणि तो क्षण ओळखणे सोपे आहे. जेव्हा तुम्ही टास्कचा एक ब्लॉक दुसऱ्या प्लेबुकमध्ये कॉपी करता, तेव्हा तो क्षण येतो. ती कॉपी हा एक इशारा असतो. त्यानंतर प्रत्येक दुरुस्ती दोनदा करावी लागते आणि एके दिवशी ती फक्त एकदाच केली जाईल, ज्यामुळे त्रुटी निर्माण होतात.
रोल डिरेक्टरीमध्ये नेमके काय असते
roles/common/
defaults/main.yml
vars/main.yml
tasks/main.yml
handlers/main.yml
templates/99-hardening.conf.j2
files/
meta/main.ymltasks/main.ymlहा प्रवेश बिंदू (entry point) आहे. जेव्हा रोल कॉल केला जातो तेव्हा Ansible ही फाईल चालवते आणि इतर प्रत्येक डिरेक्टरी ऐच्छिक असते.defaults/main.ymlमध्ये अशा व्हेरिएबल्स असतात ज्या कॉलरने ओव्हरराईड करणे अपेक्षित असते. Ansible मध्ये हे सर्वात कमी प्राधान्य असलेले स्त्रोत आहे, त्यामुळे इतर जवळजवळ सर्व गोष्टी याला मागे टाकतात.vars/main.ymlमध्ये अशा व्हेरिएबल्स असतात ज्या कॉलरने ओव्हरराईड करणे अपेक्षित नसते. प्राधान्यक्रमामध्ये हे इन्व्हेंटरीच्या वर असते, जे एक महत्त्वाचे स्थान आहे. याचा वापर दुर्मिळपणे करा.handlers/main.ymlमध्येnotifyद्वारे ट्रिगर होणारे टास्क असतात. कितीही टास्कनी नोटिफिकेशन दिले तरी, हँडलर प्लेच्या शेवटी एकदाच चालतो.files/मध्येcopyमॉड्यूलद्वारे जसेच्या तसे कॉपी केलेले फाईल्स असतात आणिtemplates/मध्येtemplateमॉड्यूलद्वारे रेंडर केलेले Jinja2 टेम्पलेट्स असतात. रोलच्या आत तुम्ही दोन्हीचा संदर्भ केवळ फाईलच्या नावाने देता, कारण Ansible प्रथम रोलच्या स्वतःच्या डिरेक्टरीजमध्ये शोध घेते.meta/main.ymlरोलच्या अवलंबित्व (dependencies) आणि Ansible Galaxy द्वारे वाचले जाणारे मेटाडेटा घोषित करते.
ही मांडणी केवळ शैलीचा भाग नाही. Ansible या नेमक्या मार्गांवर शोध घेते, त्यामुळे तुम्ही roles/common/template/ (एकवचनी) मध्ये ठेवलेले टेम्पलेट कधीही सापडणार नाही.
ansible-galaxy init वापरून कॉमन रोल तयार करा
mkdir -p ~/infra/roles
cd ~/infra
ansible-galaxy init --init-path roles commonहे कमांड roles/common अंतर्गत संपूर्ण साचा (skeleton) तयार करते, ज्यामध्ये तुम्ही न वापरणार असलेल्या डिरेक्टरीज आणि केवळ --- असलेले main.yml स्टब्स असतात. जे तुम्ही रिकामे सोडता, ते काढून टाका. रिकामे vars/main.yml Ansible साठी हानिकारक नसले तरी, त्या रोलमधील कोणत्या फाइल्स खरोखर महत्त्वाच्या आहेत हे समजणे कठीण होते.
आता काम करणाऱ्या फाइल्स भरा. आधी defaults भरा, कारण ते रोलचा सार्वजनिक इंटरफेस (public interface) असतात.
# roles/common/defaults/main.yml
---
common_packages:
- ufw
- fail2ban
- unattended-upgrades
common_admin_group: admins
common_permit_root_login: "no"
common_password_authentication: "no""no" आणि "yes" ला कोट (quote) करा. Ansible YAML ला PyYAML द्वारे पार्स करते, जे रिकाम्या no ला boolean false म्हणून वाचते. त्यामुळे तयार झालेली कॉन्फिगरेशन ओळ PermitRootLogin False अशी बनते आणि sshd तिला नाकारते. कोट्समुळे ती व्हॅल्यू स्ट्रिंग म्हणून राहते.
# roles/common/tasks/main.yml
---
- name: Install the base packages
ansible.builtin.apt:
name: "{{ common_packages }}"
state: present
update_cache: true
cache_valid_time: 3600
- name: Create the admin group
ansible.builtin.group:
name: "{{ common_admin_group }}"
state: present
- name: Install the sshd hardening drop-in
ansible.builtin.template:
src: 99-hardening.conf.j2
dest: /etc/ssh/sshd_config.d/99-hardening.conf
owner: root
group: root
mode: "0644"
validate: /usr/sbin/sshd -t -f %s
notify: Restart sshd# roles/common/handlers/main.yml
---
- name: Restart sshd
ansible.builtin.service:
name: ssh
state: restarted# roles/common/templates/99-hardening.conf.j2
# Managed by Ansible. Local edits are overwritten on the next run.
PermitRootLogin {{ common_permit_root_login }}
PasswordAuthentication {{ common_password_authentication }}Debian आणि Ubuntu वर systemd युनिटला ssh म्हणतात, तर RHEL फॅमिली सिस्टिम्सवर ते sshd असते. चुकीचे नाव असलेला हँडलर तेव्हाच अपयशी ठरतो जेव्हा टेम्पलेटमध्ये काही बदल होतो, म्हणूनच ही समस्या अनेकदा काही आठवड्यांनंतर समोर येते.
त्या टास्कमधील validate ओळ सर्वात उपयुक्त आहे. Ansible टेम्पलेटला एका तात्पुरत्या फाइलमध्ये रेंडर करते, त्या फाइलचा पाथ %s साठी वापरते आणि कमांड रन करते. जर कमांडचा एक्झिट कोड 0 असेल, तरच डेस्टिनेशन फाइल रिप्लेस केली जाते. टेम्पलेटमध्ये एखादी चुकीची डायरेक्टिव्ह टाकून पुन्हा रन करा: टास्क failed to validate सह अपयशी ठरेल, मूळ /etc/ssh/sshd_config.d/99-hardening.conf सुरक्षित राहील आणि तुम्ही सर्व्हरमध्ये लॉग इन करू शकाल. लक्षात ठेवा की हे चेक केवळ सिंटॅक्सपेक्षा जास्त गोष्टी तपासते. जर sshd -t होस्ट कीज वाचू शकले नाही, तर ते sshd: no hostkeys available -- exiting. सह एक्झिट होते आणि Ansible सुद्धा तोच failed to validate रिपोर्ट करते, त्यामुळे टेम्पलेटला दोष देण्यापूर्वी मॉड्यूलचे msg वाचा.
How a playbook calls a role
# site.yml
---
- name: Base configuration for every server
hosts: all
become: true
roles:
- common# inventory.ini
[local]
localhost ansible_connection=localansible-playbook -i inventory.ini site.ymlThe play should end with failed=0 in the recap. Pass parameters at the call site with the expanded form, which is how one role serves two groups of hosts:
roles:
- role: common
common_admin_group: ops
common_permit_root_login: prohibit-passwordThere is one ordering rule that surprises almost everybody. A play can hold pre_tasks, roles, tasks and post_tasks, and Ansible runs them in that order whatever order you wrote them in the file. Put tasks: above roles: and the roles still run first. So if something must happen before a role, it belongs in pre_tasks:, not at the top of tasks:.
- name: Ordering demonstration
hosts: local
gather_facts: false
pre_tasks:
- name: Runs first
ansible.builtin.debug:
msg: pre
roles:
- common
tasks:
- name: Runs after the role
ansible.builtin.debug:
msg: task
post_tasks:
- name: Runs last
ansible.builtin.debug:
msg: postTo call a role from inside a task list instead of the roles: key, use import_role or include_role.
tasks:
- name: Static, read when the playbook is parsed
ansible.builtin.import_role:
name: common
- name: Dynamic, resolved when the task runs
ansible.builtin.include_role:
name: postgres
when: "'db' in group_names"import_role is static. Ansible reads the role at parse time and its tasks become part of the play, so ansible-playbook --list-tasks site.yml lists them and a tag on the import applies to every task inside. include_role is dynamic. Nothing is read until the task runs, which is what lets you drive the role name from a variable or a loop. The cost is that those tasks are invisible to --list-tasks and to --start-at-task.
One trap lives here. A when: on an include_role task is evaluated before the included role's defaults/main.yml is in scope. Write when: common_packages | length > 0 on the include and the run stops with 'common_packages' is undefined, even though that variable is defined in the very role you are including. The fix is to move the toggle out of the role: put it in group_vars/all.yml, where it is in scope everywhere, and leave the role's defaults for values the role itself consumes.
कोणता व्हेरिएबल प्रभावी ठरतो: defaults, group_vars, vars, extra vars
Ansible मध्ये व्हेरिएबल प्राधान्याचे (variable precedence) वीसपेक्षा जास्त स्तर आहेत. त्यापैकी चार स्तर बहुतेक सर्व व्यावहारिक प्रश्न सोडवतात. त्यांची ताकदीनुसार (सर्वात कमकुवत ते सर्वात शक्तिशाली) मांडणी खालीलप्रमाणे आहे.
roles/<name>/defaults/main.ymlहे सर्वात खालच्या स्तरावर असते. इतर कोणत्याही ठिकाणी सेट केलेले मूल्य याला ओव्हरराइड करते. म्हणूनच रोलसाठी आवश्यक असणारे ट्युनेबल नॉब्स (tunable knobs) ठेवण्यासाठी ही योग्य जागा आहे.group_vars/आणिhost_vars/हे मधल्या स्तरावर येतात. तुमच्या साइटची स्वतःची उत्तरे येथे असावीत, कारण ती रोल डिफॉल्ट्सना सहजपणे ओव्हरराइड करतात.roles/<name>/vars/main.ymlहेhost_varsच्या वरच्या स्तरावर असते. येथे दिलेले मूल्य इन्व्हेंटरीमधून ओव्हरराइड करता येत नाही. हे अशा गोष्टींसाठी राखून ठेवा ज्या रोलला अंतर्गत सुसंगत राहण्यासाठी आवश्यक आहेत, उदाहरणार्थ, सर्व्हिसच्या नावाला जुळणारे पॅकेजचे नाव.- कॉल साइटवर पास केलेले रोल पॅरामीटर
vars/main.ymlला ओव्हरराइड करते आणि कमांड लाइनवरील-eहे रोल पॅरामीटर्ससह इतर सर्वांपेक्षा वरचढ ठरते.
हे कसे कार्य करते हे तुम्ही एका मिनिटात पाहू शकता. एका छोट्या रोलला एक डिफॉल्ट आणि एक रोल व्हेरिएबल द्या, त्यानंतर तीच नावे host_vars मध्ये सेट करा.
# roles/prec/defaults/main.yml
---
prec_tunable: from-defaults
prec_internal: from-defaults# roles/prec/vars/main.yml
---
prec_internal: from-rolevars# host_vars/localhost.yml
---
prec_tunable: from-hostvars
prec_internal: from-hostvars# roles/prec/tasks/main.yml
---
- name: Show which value survived
ansible.builtin.debug:
msg: "tunable={{ prec_tunable }} internal={{ prec_internal }}"ansible-playbook -i inventory.ini prec.yml
ansible-playbook -i inventory.ini prec.yml -e prec_internal=from-cliपहिली रन tunable=from-hostvars internal=from-rolevars प्रिंट करते. इन्व्हेंटरीने रोल डिफॉल्टला मागे टाकले, पण ती रोल व्हेरिएबलपेक्षा कमी पडली. दुसरी रन internal=from-cli प्रिंट करते, कारण एक्स्ट्रा व्हेरिएबल्स सर्वात वरच्या स्तरावर असतात आणि खालचा कोणताही स्तर त्यांना बदलू शकत नाही. म्हणूनच -e हे एकदाच चालवायच्या रनसाठी ठीक आहे, पण तुम्ही जपून ठेवलेल्या स्क्रिप्टमध्ये ते चुकीचे ठरते: ते तुमच्या रिपॉझिटरीमधील सर्व विचारांती घेतलेल्या निर्णयांना शांतपणे मागे टाकते.
कार्यरत नियम: जर तुम्हाला एखादे मूल्य बदलण्यायोग्य (settable) ठेवायचे असेल, तर ते defaults/ मध्ये ठेवा. ते vars/ मध्ये ठेवल्यास, रोल वापरणाऱ्या भविष्यातील प्रत्येक वापरकर्त्याला असा संदेश मिळतो की इन्व्हेंटरी ते बदलू शकत नाही. काही वेळा तुमचा हेतू तोच असू शकतो, पण सहसा ही एक चूक असते.
रोल आयडेम्पोटंट (idempotent) असल्याची खात्री करा: तो दोनदा चालवा
ज्या Ansible रनवर विश्वास ठेवता येतो, तो दुसऱ्यांदा चालवल्यावर कोणताही बदल न करता तोच निकाल देतो. प्लेबुक दोनदा चालवा आणि त्याचा सारांश (recap) वाचा.
ansible-playbook -i inventory.ini site.yml
ansible-playbook -i inventory.ini site.ymlदुसऱ्या सारांशाचे स्वरूप खालीलप्रमाणे असावे:
PLAY RECAP *********************************************************************
localhost : ok=4 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0changed=0 चा अर्थ असा की प्रत्येक मॉड्यूलने सध्याची स्थिती तपासली आणि काम आधीच पूर्ण झाल्याचे आढळले. दुसऱ्या रनवर changed=2 दिसणे म्हणजे दोन टास्कमध्ये फरक ओळखता येत नाही, त्यामुळे ते सतत फाइल्स पुन्हा लिहित राहतील आणि सर्व्हिसेस पुन्हा सुरू करत राहतील. याचे सामान्य कारण command किंवा shell हे असते, कारण एखादी अनियंत्रित कमांड काय करते हे Ansible ला समजण्याचा मार्ग नसतो.
# traps.yml
---
- name: Command modules do not know what they changed
hosts: local
gather_facts: false
tasks:
- name: This appends a line on every run
ansible.builtin.shell: "echo run >> /tmp/grow.txt"
- name: This appends a line only once
ansible.builtin.shell: "echo run >> /tmp/guarded.txt"
args:
creates: /tmp/guarded.txtते प्लेबुक दोनदा चालवा, त्यानंतर wc -l /tmp/grow.txt /tmp/guarded.txt असलेल्या ओळी मोजा. /tmp/grow.txt मध्ये दोन ओळी असतात आणि /tmp/guarded.txt मध्ये एक ओळ असते. दुसऱ्या रनवर सुरक्षित (guarded) टास्क अजिबात कार्यान्वित झाला नाही आणि त्याचा निकाल skipped, since /tmp/guarded.txt exists हा संदेश देतो, कारण creates मॉड्यूलला शोधण्यासाठी एक दृश्य उत्पादन (visible product) देते. जेव्हा एखादी कमांड असे कोणतेही उत्पादन मागे ठेवत नाही, तेव्हा तिचे आउटपुट रजिस्टर करा आणि changed_when वापरून स्वतः निर्णय घ्या.
ansible-playbook --check --diff site.yml बदल न करता त्यांची पूर्वसूचना देते आणि --diff टेम्पलेटमध्ये बदलल्या जाणाऱ्या नेमक्या ओळी प्रिंट करते. आउटपुट वाचताना एक गोष्ट लक्षात ठेवा: shell आणि command टास्क चेक मोडमध्ये वगळले जातात, त्यामुळे वरवर स्वच्छ दिसणाऱ्या प्लॅनमध्येही काही काम लपलेले असू शकते.
त्या सारांशातील आणखी एक कॉलम तितक्याच काळजीने पाहणे आवश्यक आहे: ज्या होस्टशी Ansible कनेक्ट होऊ शकले नाही, तो failed ऐवजी unreachable अंतर्गत मोजला जातो आणि त्याचे कोणतेही टास्क चालत नाहीत. म्हणून, एकापेक्षा जास्त मशीनवर हा रोल वापरण्यापूर्वी एखादा होस्ट पोहोचण्यायोग्य नसल्यास संपूर्ण रन थांबवायचा की नाही, याचा आधीच निर्णय घ्या.
Ansible ला रोल का सापडत नाही
Ansible प्लेबुक फाईलच्या शेजारी roles/ डिरेक्टरी शोधते, त्यानंतर roles_path मध्ये शोधते. शोध घेण्याची प्रक्रिया तुमच्या शेलवर नाही, तर प्लेबुकच्या स्थानावर अवलंबून असते.
ERROR! the role 'common' was not found in /home/deploy/lonely/roles:/home/deploy/lonelyया संदेशाचा अर्थ असा आहे की site.yml आणि roles/ यांच्यात तफावत निर्माण झाली आहे. Ansible ने शोध घेतलेले मार्ग ते उपयुक्तपणे प्रिंट करते. या दोन्ही गोष्टी एकाच डिरेक्टरीमध्ये ठेवा. पॅरेंट डिरेक्टरीमधून कमांड चालवणे योग्य आहे, कारण प्लेबुकचा मार्ग महत्त्वाचा असतो:
ansible-playbook -i infra/inventory.ini infra/site.ymlयाच समस्येचे एक कमी स्पष्ट स्वरूप देखील आहे. जेव्हा एखादी डिरेक्टरी 'world writable' असते, तेव्हा Ansible त्यातील ansible.cfg कडे दुर्लक्ष करते. कारण सर्व्हरवरील कोणताही वापरकर्ता तिथे कॉन्फिगरेशन फाईल ठेवून तुमच्या रनमध्ये बदल करू शकतो.
[WARNING]: Ansible is being run in a world writable directory (/tmp/infra), ignoring it as an ansible.cfg source.अशा वेळी तुमची roles_path आणि inventory सेटिंग्ज कोणतीही सूचना न देता अनुपस्थित राहतात आणि रोल लुकअप अयशस्वी होतो, ज्याचा रोलशी काहीही संबंध नसतो. ansible --version कमांड प्रत्यक्षात लोड झालेली config file प्रिंट करते आणि ansible-config dump --only-changed कमांड डीफॉल्ट सेटिंग्जपेक्षा वेगळी असलेली प्रत्येक सेटिंग प्रिंट करते. जेव्हा रन तुमच्या कॉन्फिगरेशनशिवाय होत असल्याचे जाणवेल, तेव्हा या दोन्ही कमांड्स तपासा.
भूमिका सामायिक करणे: requirements.yml आणि पिन केलेली आवृत्ती
दुसऱ्या कोणीतरी लिहिलेली भूमिका (role) कॉपी न करता ती इन्स्टॉल केली जाते. ती एकदाच घोषित करा:
# requirements.yml
---
roles:
- name: postgres
src: https://github.com/example/ansible-role-postgres
scm: git
version: v1.4.0ansible-galaxy install -r requirements.yml -p galaxy_rolesनेहमी version सेट करा. त्याशिवाय, तुम्ही कमांड रन करता त्या दिवशी डिफॉल्ट ब्रँचमध्ये जे काही असेल ते तुम्हाला मिळते. त्यामुळे, गेल्या महिन्यात काम करणारी डिप्लॉयमेंट तुमच्या स्वतःच्या रिपॉझिटरीमध्ये कोणताही बदल न करताही बंद पडू शकते. roles_path ला डाउनलोड डिरेक्टरीकडे निर्देशित करा आणि ती डिरेक्टरी git मधून बाहेर ठेवा:
# ansible.cfg
[defaults]
inventory = inventory.ini
roles_path = ./galaxy_rolesप्लेबुकच्या शेजारील roles/ मधील भूमिका अजूनही सापडतात, कारण roles_path व्यतिरिक्त तो पाथ नेहमी शोधला जातो. त्यामुळे तुमच्या स्वतःच्या भूमिका कमिट केलेल्या आणि रिव्ह्यू केलेल्या राहतात, तर थर्ड-पार्टी भूमिका या एका टॅगला पिन केलेल्या पुनरुत्पादनीय (reproducible) डाउनलोड्स असतात.
जेव्हा roles हे उत्तर राहत नाहीत
एका Ansible रनमध्ये 'role' हे पुनर्वापराचे एक साधन आहे. ते तुमच्या प्रोव्हायडरकडे सर्व्हर किंवा DNS रेकॉर्ड तयार करत नाही. तसा प्रयत्न केल्यास playbooks अशा स्थितीत पोहोचतात ज्यांची देखभाल करणे कोणालाही शक्य नसते. सुरुवात करण्यापूर्वी Ansible आणि Terraform मधील कामाची विभागणी वाचणे फायदेशीर ठरेल. तसेच, role हे inventory डिझाइनला पर्याय नाही: जेव्हा तुमच्याकडे काही मोजक्या मशीनपेक्षा जास्त सर्व्हर असतात, तेव्हा तुम्ही सर्व्हरचे गट कसे करता आणि त्यांपर्यंत कसे पोहोचता हे टास्क कसे फाइल केले आहेत यापेक्षा अधिक महत्त्वाचे ठरते.
या common role द्वारे केले जाणारे hardening देखील स्वतंत्र निर्णयाची मागणी करते. वरील उदाहरणात फक्त दोन directives सेट केल्या आहेत, त्यापेक्षा जास्त काहीही नाही. त्यामुळे, प्रत्येक होस्टसाठी कोणत्या गोष्टी role मध्ये असाव्यात हे ठरवण्यापूर्वी कोणत्या SSH सेटिंग्ज बदलणे खरोखर फायदेशीर आहे आणि Ubuntu वर आपोआप सुरक्षा अपडेट्स कसे लागू करावेत हे वाचून घ्या.
FAQ
मी Ansible playbook चे रूपांतर role मध्ये कधी करावे?
जेव्हा कामांचा (tasks) तोच संच दुसऱ्या play मध्ये किंवा दुसऱ्या host group वर चालवायचा असतो, तेव्हा हे करावे. Playbook मधील tasks कॉपी करणे हे एक संकेत आहे की आता वेळ आली आहे, कारण त्यानंतर प्रत्येक दुरुस्ती दोनदा करावी लागेल आणि एक दिवस ती फक्त एकदाच केली जाईल. साधारणपणे 100 ओळींपेक्षा कमी असलेला आणि फक्त एकाच group ला लक्ष्य करणारा playbook role मध्ये रूपांतरित केल्याने काहीही फायदा होत नाही, उलट अतिरिक्त डिरेक्टरीजमुळे तो वाचणे कठीण होते.
एकाच play मधील tasks च्या आधी roles चालतात का?
हो. Ansible आधी pre_tasks चालवते, त्यानंतर roles: अंतर्गत सूचीबद्ध सर्व गोष्टी, मग tasks: आणि शेवटी post_tasks: चालवते. तुमच्या फाईलमध्ये या keys कोणत्या क्रमाने आहेत, याकडे Ansible दुर्लक्ष करते. tasks: ला roles: च्या वर लिहिण्याने त्या tasks आधी चालत नाहीत. जर एखादी गोष्ट role च्या आधी होणे आवश्यक असेल, तर ती pre_tasks: मध्ये ठेवा.
माझे group_vars मूल्य role ला का ओव्हरराइड करत नाही?
व्हेरिएबल role च्या defaults/main.yml ऐवजी vars/main.yml मध्ये सेट केले आहे का ते तपासा. Ansible च्या प्राधान्य क्रमानुसार (precedence order) vars/ हे group_vars आणि host_vars च्या वर असते, त्यामुळे inventory त्याला ओव्हरराइड करू शकत नाही. व्हेरिएबलला defaults/main.yml मध्ये हलवा, जे प्राधान्य क्रमाच्या तळाशी असते आणि जिथे कॉलरने बदलता येण्याजोग्या गोष्टी ठेवणे योग्य असते. टायपोऐवजी प्राधान्य क्रम हेच कारण आहे हे निश्चित करण्यासाठी, एकदा -e name=value वापरून रन करा, जे इतर सर्व स्रोतांपेक्षा वरच्या क्रमांकावर असते.
Ansible 'role सापडला नाही' असे का म्हणते?
शोध प्रक्रिया playbook फाईलच्या जवळून सुरू होते, म्हणून site.yml आणि roles/ एकाच डिरेक्टरीमध्ये असणे आवश्यक आहे. त्रुटी संदेशात त्याने तपासलेले मार्ग (paths) छापले जातात, जसे की the role 'common' was not found in /home/deploy/lonely/roles:/home/deploy/lonely मध्ये दिसते. Playbook ला पॅरेंट डिरेक्टरीमधून रन करणे ठीक आहे, कारण शोध प्रक्रिया ही तुमच्या शेलच्या वर्किंग डिरेक्टरीऐवजी playbook च्या मार्गाचे अनुसरण करते. जर तुम्ही ansible.cfg मधील roles_path वर अवलंबून असाल, तर ती फाईल ansible --version सह लोड झाली आहे का ते तपासा, कारण जर वर्किंग डिरेक्टरी सर्वांसाठी writable असेल तर Ansible त्याकडे दुर्लक्ष करते.
role तयार करण्यासाठी मला ansible-galaxy init ची गरज आहे का?
नाही. Role म्हणजे केवळ अपेक्षित नावे असलेल्या डिरेक्टरीज असतात, त्यामुळे mkdir -p roles/common/tasks आणि त्यासोबत एक tasks/main.yml असेल तर तो आधीच एक कार्यरत role असतो. ansible-galaxy init --init-path roles common मुळे टाईपिंग वाचते आणि तुम्हाला पूर्ण साचा (skeleton) मिळतो, ज्यामध्ये meta/main.yml आणि एक README स्टब समाविष्ट असतो. ज्या डिरेक्टरीज तुम्ही रिकाम्या ठेवता त्या काढून टाका, कारण रिकामी vars/main.yml फाईल role मधील कोणत्या फाईल्स प्रत्यक्षात काम करत आहेत हे लपवते.