Ansible playbook आणि role मधील फरक: कधी काय वापरावे?
Ansible playbook आणि role मधील मुख्य फरक जाणून घ्या. साध्या कामासाठी प्लेबुक कधी पुरेसे असते आणि जटिल ऑटोमेशनसाठी role ची रचना व व्हेरिएबल प्रेसिडेन्स कधी वापरावे हे येथे शिका.
Ansible playbook आणि role: यातील फरक काय आहे
Ansible playbook ही एक फाईल आहे जी तुम्ही ansible-playbook वापरून चालवता. ती होस्ट्सच्या समूहाला त्यांच्यासाठी आवश्यक असलेल्या कामांशी जोडते. Ansible role म्हणजे एक निश्चित मांडणी असलेली डिरेक्टरी, ज्यामध्ये tasks, templates, handlers आणि default variables असतात; playbook त्याला नावाने कॉल करते. दोन्हीमधील task सिंटॅक्स सारखाच असतो, त्यामुळे तुम्ही काय करू शकता हा प्रश्न नाही. हा प्रश्न पुनर्वापराचा (reuse) आहे.
सुरुवात एका साध्या playbook पासून करा. एका site.yml मध्ये असलेली tasks: लिस्ट तुमच्या पहिल्या ऑटोमेशनसाठी योग्य आहे आणि ती बऱ्याच काळापर्यंत पुरेशी ठरते. जेव्हा कामांचा तोच संच दुसऱ्या होस्ट्सच्या समूहासाठी चालवावा लागतो, किंवा फाईल 100 ओळींच्या पुढे जाते आणि तुम्हाला स्क्रोल करून task शोधणे कठीण होते, तेव्हा त्याचे रूपांतर role मध्ये करा.
जर तुम्ही अजून एकही playbook लिहिली नसेल, तर एका सिंगल VPS साठी पहिल्या playbook पासून सुरुवात करा आणि जेव्हा ती मोठी होऊ लागेल तेव्हा परत या.
जेव्हा फ्लॅट प्लेबुक योग्य पर्याय असतो
जेव्हा एखादे काम एकदाच करायचे असते, किंवा एकाच होस्टवर करायचे असते, किंवा जेव्हा ते प्लेबुक इतर कोणीही वाचणार नाही, तेव्हा फ्लॅट प्लेबुक वापरणे योग्य असते. एका सिंगल ॲप्लिकेशन सर्व्हरचे प्रोव्हिजनिंग करणे किंवा मेंटेनन्स विंडोच्या आधी एखादा बॉक्स पॅच करणे: यापैकी कशासाठीही डिरेक्टरी ट्रीची गरज नसते. एक रोल सात डिरेक्टरीज आणि इनडायरेक्शनचा एक स्तर वाढवतो. जर त्या प्लेबुकचा एकमेव वापरकर्ता त्याच्या शेजारी असलेले प्लेबुक असेल, तर त्या इनडायरेक्शनचा काहीही फायदा होत नाही आणि प्रत्यक्षात काय रन होत आहे हे पाहण्यासाठी तुम्हाला प्रत्येक वेळी एक जंप घ्यावी लागते.
फ्लॅट प्लेबुक कधी अयोग्य ठरते, हे एका विशिष्ट क्षणी समजते आणि तो क्षण ओळखणे सोपे असते. जेव्हा तुम्ही टास्कचा एक ब्लॉक दुसऱ्या प्लेबुकमध्ये कॉपी करता, तेव्हा तो क्षण येतो. ती कॉपी म्हणजे एक इशारा असतो. त्यानंतर प्रत्येक फिक्स दोनदा करावा लागतो आणि एके दिवशी तो फक्त एकदाच केला जाईल.
रोल डिरेक्टरीमध्ये नेमके काय असते
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" ला अवतरण चिन्हांमध्ये (quotes) ठेवा. Ansible, PyYAML वापरून YAML पार्स करते, जे रिकाम्या no ला बुलियन '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 मध्ये व्हेरिएबल प्राधान्यासाठी वीसपेक्षा जास्त स्तर आहेत. त्यापैकी चार स्तर जवळजवळ सर्व व्यावहारिक प्रश्नांचे निराकरण करतात. खाली ते सर्वात कमकुवत ते सर्वात शक्तिशाली अशा क्रमाने दिले आहेत.
roles/<name>/defaults/main.ymlहे सर्वात खालच्या स्तरावर असते. इतर कोणत्याही ठिकाणी सेट केलेले मूल्य याला ओव्हरराइड करते, म्हणूनच रोलसाठी आवश्यक असणारे ट्युन करण्यायोग्य पर्याय ठेवण्यासाठी ही योग्य जागा आहे.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 प्रिंट करते, कारण extra vars हे सर्वात वरच्या स्तरावर असतात आणि खालचा कोणताही स्तर त्यांना बदलू शकत नाही. म्हणूनच -e हे एकदाच चालवायच्या रनसाठी ठीक आहे, परंतु कायमस्वरूपी स्क्रिप्टमध्ये वापरणे चुकीचे आहे: ते तुमच्या रिपॉझिटरीमधील सर्व विचाराधीन निर्णयांना शांतपणे मागे टाकते.
कार्यरत नियम: जर तुम्हाला एखादे मूल्य बदलण्यायोग्य ठेवायचे असेल, तर ते 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 हे असते, कारण एखादी मनमानी कमांड (arbitrary command) काय करते हे 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 task) अजिबात कार्यान्वित झाला नाही आणि त्याच्या निकालामध्ये skipped, since /tmp/guarded.txt exists हा संदेश येतो, कारण creates मॉड्यूलला शोधण्यासाठी एक दृश्य उत्पादन (visible product) आधीच देते. जेव्हा एखादी कमांड असे कोणतेही उत्पादन मागे ठेवत नाही, तेव्हा त्याचे आउटपुट रजिस्टर करा आणि changed_when वापरून स्वतः निर्णय घ्या.
ansible-playbook --check --diff site.yml बदल न करता ते बदल काय असतील याचे भाकीत करते आणि --diff टेम्पलेटद्वारे पुन्हा लिहिल्या जाणाऱ्या अचूक ओळी प्रिंट करते. हे आउटपुट वाचताना एक गोष्ट लक्षात ठेवा: shell आणि command टास्क चेक मोडमध्ये वगळले जातात, त्यामुळे जे प्लॅन स्वच्छ दिसतात, त्यातही काही काम लपलेले असू शकते.
Ansible मध्ये 'role not found' अशी त्रुटी का येते
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) वापरणे थांबवावे
रोल (role) हे एका Ansible रनमधील पुनर्वापराचे (reuse) एक युनिट आहे. ते तुमच्या प्रोव्हायडरकडे सर्व्हर्स किंवा DNS रेकॉर्ड्स तयार करत नाही. तसा प्रयत्न केल्यास प्लेबुक्स अशा स्वरूपात बदलतात, ज्यांची देखभाल करणे कोणालाही शक्य नसते. तुम्ही सुरुवात करण्यापूर्वी Ansible आणि Terraform मधील कामाची विभागणी वाचणे फायदेशीर ठरेल. तसेच, रोल (role) हे इन्व्हेंटरी डिझाइनला पर्याय ठरू शकत नाही: जेव्हा तुमच्याकडे काही मोजक्या मशीनपेक्षा जास्त मशीन असतात, तेव्हा तुम्ही सर्व्हर्सचे गट कसे करता आणि त्यांपर्यंत कसे पोहोचता हे टास्क कसे फाइल केले आहेत यापेक्षा जास्त महत्त्वाचे ठरते.
हा common रोल जो हार्डनिंग (hardening) लागू करतो, त्यासाठी स्वतंत्र निर्णय घेणे आवश्यक आहे. वरील ड्रॉप-इन (drop-in) फक्त दोन डिरेक्टिव्ह्ज सेट करते, त्यापेक्षा जास्त काहीही नाही. त्यामुळे, तुम्ही तुमच्या मालकीच्या प्रत्येक होस्टसाठी रोलमध्ये काय असावे हे ठरवण्यापूर्वी कोणत्या SSH सेटिंग्ज बदलणे खरोखर फायदेशीर आहे आणि Ubuntu वर सुरक्षा अपडेट्स आपोआप कसे लागू करावेत हे वाचून घ्या.
FAQ
Ansible playbook चे रूपांतर role मध्ये कधी करावे?
जेव्हा कामांचा (tasks) एकच संच दुसऱ्या play मध्ये किंवा दुसऱ्या host गटावर चालवायचा असतो, तेव्हा हे करावे. एका playbook मधून दुसऱ्या playbook मध्ये tasks कॉपी करणे हे याचे लक्षण आहे, कारण अशा वेळी प्रत्येक दुरुस्ती दोनदा करावी लागते आणि एक दिवस ती फक्त एकदाच केली जाण्याची शक्यता असते. साधारणपणे 100 ओळींपेक्षा कमी लांबीचा आणि फक्त एकाच गटावर चालणारा playbook role मध्ये रूपांतरित केल्याने कोणताही फायदा होत नाही, उलट अतिरिक्त डिरेक्टरीजमुळे तो वाचणे कठीण होते.
एकाच play मधील tasks च्या आधी roles चालतात का?
हो. Ansible आधी pre_tasks चालवते, त्यानंतर roles: अंतर्गत सूचीबद्ध सर्व काही, मग tasks:, आणि शेवटी post_tasks: चालवते. तुमच्या फाईलमध्ये या की (keys) कोणत्या क्रमाने आहेत, याकडे ते दुर्लक्ष करते. 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/ एकाच डिरेक्टरीमध्ये असणे आवश्यक आहे. त्रुटी संदेशात त्याने तपासलेले मार्ग the role 'common' was not found in /home/deploy/lonely/roles:/home/deploy/lonely प्रमाणे दिसतात. पॅरेंट डिरेक्टरीमधून playbook रन करणे ठीक आहे, कारण शोध प्रक्रिया playbook च्या मार्गाचे अनुसरण करते, तुमच्या शेलच्या वर्किंग डिरेक्टरीचे नाही. जर तुम्ही ansible.cfg मधील roles_path वर अवलंबून असाल, तर ती फाईल ansible --version द्वारे लोड झाली आहे याची खात्री करा, कारण वर्किंग डिरेक्टरी 'world writable' असल्यास Ansible त्याकडे दुर्लक्ष करते.
role तयार करण्यासाठी ansible-galaxy init वापरणे आवश्यक आहे का?
नाही. role म्हणजे केवळ अपेक्षित नावे असलेल्या डिरेक्टरीज असतात, त्यामुळे mkdir -p roles/common/tasks आणि त्यासोबत एक tasks/main.yml आधीच एक कार्यरत role असते. ansible-galaxy init --init-path roles common मुळे टाईपिंग वाचते आणि तुम्हाला meta/main.yml व README स्टबसह पूर्ण साचा (skeleton) मिळतो. ज्या डिरेक्टरीज तुम्ही रिकाम्या ठेवता त्या काढून टाका, कारण रिकामी vars/main.yml फाईल role मधील कोणत्या फाईल्स प्रत्यक्षात काम करतात हे लपवते.