Ansible playbook vs role: எப்போது எதைப் பயன்படுத்த
Ansible playbook மற்றும் role ஆகியவற்றின் முக்கிய வேறுபாடுகளை அறியுங்கள். எளிய பணிகளுக்கு playbook எப்போது போதுமானது மற்றும் எப்போது role-க்கு மாற வேண்டும் என்பதை விளக்குகிறோம்.
Ansible playbook மற்றும் role: இவற்றிற்கு இடையேயான வேறுபாடு என்ன
Ansible playbook என்பது நீங்கள் ansible-playbook மூலம் இயக்கும் ஒரு கோப்பாகும். இது ஒரு குறிப்பிட்ட host குழுவிற்கு செய்ய வேண்டிய பணிகளை வரைபடமாக்குகிறது. Ansible role என்பது tasks, templates, handlers மற்றும் default variables ஆகியவற்றை உள்ளடக்கிய ஒரு நிலையான அமைப்பைக் கொண்ட கோப்பகமாகும் (directory); ஒரு playbook அதை அதன் பெயரைக் கொண்டு அழைக்கும். இரண்டிலும் உள்ள task syntax ஒரே மாதிரியானது, எனவே எதைச் செய்ய முடியும் என்பது இங்கு கேள்வியல்ல. இது மறுபயன்பாடு (reuse) குறித்த கேள்வியாகும்.
முதலில் ஒரு எளிய playbook-உடன் தொடங்குங்கள். ஒரு site.yml-ல் உள்ள tasks: பட்டியல் உங்கள் முதல் automation-க்கு சரியான வடிவமாகும், மேலும் இது பெரும்பாலானோர் எதிர்பார்ப்பதை விட நீண்ட காலத்திற்கு போதுமானதாக இருக்கும். அதே பணிகளை மற்றொரு host குழுவிற்கும் செய்ய வேண்டியிருக்கும் போதோ, அல்லது கோப்பு சுமார் 100 வரிகளுக்கு மேல் வளர்ந்து, scroll செய்வதன் மூலம் ஒரு task-ஐக் கண்டறிய முடியாத நிலை ஏற்படும் போதோ அதை role-ஆக மாற்றவும்.
நீங்கள் இன்னும் எதையும் எழுதவில்லை என்றால், ஒரு VPS-க்கு எதிராக முதல் playbook-ஐ எழுதித் தொடங்குங்கள் மற்றும் அது வளரத் தொடங்கும் போது மீண்டும் வாருங்கள்.
எப்போது ஒரு flat playbook சரியான தீர்வாகிறது
வேலை ஒருமுறை மட்டுமே நடக்கும்போதோ, அல்லது ஒரே ஒரு host-ல் மட்டும் நடக்கும்போதோ, அல்லது வேறு யாரும் அதை வாசிக்கப்போவதில்லை என்றாலோ ஒரு flat playbook சரியான தேர்வாகும். ஒரு application server-ஐ provision செய்யும்போதோ அல்லது maintenance window-க்கு முன்னதாக ஒரு server-ஐ patch செய்யும்போதோ, அவற்றுக்கு ஒரு directory tree தேவையில்லை. ஒரு role-ஐ உருவாக்கினால் ஏழு directories மற்றும் ஒரு கூடுதல் மறைமுக அடுக்கு (layer of indirection) உருவாகும். அந்த role-ஐ அழைக்கும் ஒரே playbook அதன் அருகிலேயே இருந்தால், அந்த மறைமுக அடுக்கு எந்தப் பயனும் தராது; மாறாக, உண்மையில் என்ன இயங்குகிறது என்பதைப் பார்க்க ஒவ்வொரு முறையும் நீங்கள் ஒரு கோப்பிற்குத் தாவ வேண்டியிருக்கும்.
ஒரு flat playbook எப்போது தவறான தேர்வாக மாறுகிறது என்பதை எளிதாகக் கண்டறியலாம். நீங்கள் ஒரு task தொகுப்பை நகலெடுத்து இரண்டாவது playbook-ல் சேர்க்கும்போது அந்தத் தருணம் வந்துவிடுகிறது. அந்த நகல் எடுப்பதே ஒரு எச்சரிக்கை மணி. அதன் பிறகு, ஒவ்வொரு திருத்தத்தையும் நீங்கள் இரண்டு இடங்களில் செய்ய வேண்டியிருக்கும்; ஏதோ ஒரு நாளில், நீங்கள் அதை ஒரு இடத்தில் மட்டுமே செய்வீர்கள்.
ஒரு role directory எதைக் கொண்டுள்ளது
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என்பது தொடக்கப் புள்ளியாகும். ஒரு role அழைக்கப்படும்போது Ansible இந்த file-ஐ இயக்குகிறது, மற்ற அனைத்து directory-களும் விருப்பத்திற்குரியவை.defaults/main.ymlஎன்பது caller மாற்றியமைக்க வேண்டிய variables-ஐக் கொண்டுள்ளது. இது Ansible-ல் மிகக் குறைந்த முன்னுரிமை கொண்ட ஆதாரமாகும், எனவே மற்ற அனைத்தும் இதைவிட அதிக முன்னுரிமை பெறும்.vars/main.ymlஎன்பது caller மாற்றியமைக்கக் கூடாத variables-ஐக் கொண்டுள்ளது. இது inventory-ஐ விட அதிக முன்னுரிமை கொண்டது, இது ஒரு முக்கியமான கட்டுப்பாடாகும். இதை அரிதாகவே பயன்படுத்தவும்.handlers/main.ymlஎன்பதுnotifyமூலம் தூண்டப்படும் tasks-ஐக் கொண்டுள்ளது. ஒரு handler, எத்தனை tasks அதை அழைத்தாலும், play-ன் இறுதியில் ஒருமுறை மட்டுமே இயங்கும்.files/என்பதுcopymodule மூலம் அப்படியே நகலெடுக்கப்படும் files-ஐக் கொண்டுள்ளது, மற்றும்templates/என்பதுtemplatemodule மூலம் உருவாக்கப்படும் Jinja2 templates-ஐக் கொண்டுள்ளது. ஒரு role-க்குள் நீங்கள் இரண்டையும் எந்தப் பாதையும் குறிப்பிடாமல் வெறும் filename மூலம் குறிப்பிடலாம், ஏனெனில் Ansible முதலில் அந்த role-ன் சொந்த directory-களில் தேடும்.meta/main.ymlஎன்பது role dependencies மற்றும் Ansible Galaxy வாசிக்கும் metadata-வை வரையறுக்கிறது.
இந்த அமைப்பு ஒரு பாணி விருப்பம் அல்ல. Ansible இந்தத் துல்லியமான பாதைகளில்தான் தேடுகிறது, எனவே நீங்கள் roles/common/template/ (ஒருமை) என்பதில் வைக்கும் template ஒருபோதும் கண்டறியப்படாது.
ansible-galaxy init மூலம் பொதுவான role-ஐ உருவாக்குதல்
mkdir -p ~/infra/roles
cd ~/infra
ansible-galaxy init --init-path roles commonஇது roles/common-ன் கீழ் முழுமையான skeleton-ஐ உருவாக்குகிறது. இதில் நீங்கள் பயன்படுத்தாத directories மற்றும் --- மட்டுமே கொண்ட main.yml stubs-களும் அடங்கும். நீங்கள் பயன்படுத்தாதவற்றை நீக்கிவிடவும். காலியான vars/main.yml Ansible-க்கு எந்த பாதிப்பையும் ஏற்படுத்தாது, ஆனால் எந்தெந்த கோப்புகள் உண்மையில் முக்கியம் என்பதை மறைத்துவிடும்.
இப்போது செயல்பாட்டிற்குத் தேவையான கோப்புகளை நிரப்பவும். முதலில் defaults-ஐ நிரப்பவும், ஏனெனில் இதுவே அந்த role-ன் பொதுவான 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, YAML-ஐ PyYAML மூலம் பகுப்பாய்வு செய்கிறது. இது வெறும் no-ஐ boolean false என்று எடுத்துக்கொள்ளும், இதனால் உருவாக்கப்படும் config வரியானது PermitRootLogin False என்று மாறிவிடும், இதை sshd நிராகரித்துவிடும். மேற்கோள் குறிகள் அந்த மதிப்பை string-ஆகவே வைத்திருக்கும்.
# 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 unit ssh என்று அழைக்கப்படுகிறது, RHEL குடும்ப அமைப்புகளில் இது sshd ஆகும். தவறான பெயரைக்கொண்ட handler, template-ல் மாற்றம் ஏற்படும்போது மட்டுமே தோல்வியடையும்; இதனால்தான் இது பல வாரங்களுக்குப் பிறகு கவனத்திற்கு வருகிறது.
அந்த task-ல் validate வரியே மிகவும் பயனுள்ளது. Ansible template-ஐ ஒரு தற்காலிகக் கோப்பாக உருவாக்கி, அந்தப் பாதையை %s-க்கு மாற்றீடு செய்து, கட்டளையை இயக்குகிறது. கட்டளை 0 என்ற exit code-ஐ வழங்கினால் மட்டுமே இலக்குக் கோப்பு மாற்றப்படும். template-ல் ஒரு தவறான directive-ஐ இட்டு மீண்டும் இயக்கவும்: task failed to validate பிழையுடன் தோல்வியடையும், உண்மையான /etc/ssh/sshd_config.d/99-hardening.conf மாற்றப்படாமல் இருக்கும், மேலும் நீங்கள் server-க்குள் நுழைய முடியும். இந்தச் சோதனை உங்கள் syntax-ஐ மட்டும் சரிபார்க்கவில்லை என்பதை நினைவில் கொள்க. sshd -t-ஆல் host keys-ஐ வாசிக்க முடியவில்லை என்றால், அது sshd: no hostkeys available -- exiting.-ஐ வழங்கும், Ansible-ம் அதே failed to validate-ஐத் தெரிவிக்கும். எனவே, template-ஐக் குறை கூறுவதற்கு முன் அந்த module-ன் msg-ஐ வாசிக்கவும்.
ஒரு playbook ஒரு 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.ymlPlay-ன் முடிவில் recap-ல் failed=0 இருக்க வேண்டும். ஒரு role-ஐ இரண்டு host குழுக்களுக்குப் பயன்படுத்த, அழைக்கும் இடத்தில் விரிவான வடிவத்தில் (expanded form) parameters-ஐ அனுப்பவும்:
roles:
- role: common
common_admin_group: ops
common_permit_root_login: prohibit-passwordஅனைவரையும் ஆச்சரியப்படுத்தும் ஒரு வரிசைமுறை விதி உள்ளது. ஒரு play-ல் pre_tasks, roles, tasks மற்றும் post_tasks இருக்கலாம். நீங்கள் கோப்பில் எந்த வரிசையில் எழுதினாலும், Ansible அவற்றை இந்த வரிசையிலேயே இயக்கும். tasks:-ஐ roles:-க்கு மேலே வைத்தாலும், roles தான் முதலில் இயங்கும். எனவே, ஒரு role-க்கு முன்னால் ஏதேனும் நடக்க வேண்டும் என்றால், அது tasks:-ன் தொடக்கத்தில் இருக்கக்கூடாது, pre_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: postroles: key-க்கு பதிலாக task list-க்குள் இருந்து ஒரு role-ஐ அழைக்க, import_role அல்லது 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 என்பது static ஆகும். Ansible parse செய்யும் நேரத்திலேயே role-ஐ வாசித்து, அதன் tasks-ஐ play-ன் ஒரு பகுதியாக மாற்றுகிறது. எனவே, ansible-playbook --list-tasks site.yml அவற்றை பட்டியலிடும், மேலும் import-ல் உள்ள ஒரு tag அந்த role-ல் உள்ள அனைத்து tasks-க்கும் பொருந்தும். include_role என்பது dynamic ஆகும். அந்த task இயங்கும் வரை எதுவும் வாசிக்கப்படாது; இதுவே ஒரு variable அல்லது loop மூலம் role-ன் பெயரைத் தீர்மானிக்க உதவுகிறது. இதன் குறைபாடு என்னவென்றால், அந்த tasks --list-tasks மற்றும் --start-at-task-க்குத் தெரியாது.
இதில் ஒரு சிக்கல் உள்ளது. ஒரு include_role task-ல் உள்ள when:, அந்த role-ன் defaults/main.yml பயன்பாட்டிற்கு வருவதற்கு முன்பே மதிப்பீடு செய்யப்படுகிறது. நீங்கள் when: common_packages | length > 0-ஐ include-ல் எழுதினால், அந்த variable நீங்கள் include செய்யும் role-லேயே வரையறுக்கப்பட்டிருந்தாலும், 'common_packages' is undefined பிழையுடன் இயக்கம் நின்றுவிடும். இதைச் சரிசெய்ய, அந்த toggle-ஐ role-க்கு வெளியே கொண்டு வர வேண்டும்: அதை group_vars/all.yml-ல் வைக்கவும், அங்கு அது எல்லா இடங்களிலும் பயன்பாட்டில் இருக்கும். role-ன் defaults-ஐ அந்த role பயன்படுத்தும் மதிப்புகளுக்கு மட்டும் விட்டுவிடவும்.
எந்த variable முன்னுரிமை பெறும்: defaults, group_vars, vars, extra vars
Ansible-ல் இருபதுக்கும் மேற்பட்ட variable முன்னுரிமை நிலைகள் உள்ளன. நடைமுறையில் பெரும்பாலான சிக்கல்களைத் தீர்க்கும் நான்கு நிலைகள் கீழே பலவீனமானதிலிருந்து வலிமையான வரிசையில் கொடுக்கப்பட்டுள்ளன.
roles/<name>/defaults/main.ymlவரிசைமுறையின் கீழ் பகுதியில் உள்ளது. நீங்கள் வேறு எங்கு எதை அமைத்தாலும் அது இதை முறியடித்துவிடும். இதனால்தான் ஒரு role-ன் மாற்றக்கூடிய அமைப்புகளுக்கு (tunable knobs) இதுவே சரியான இடமாகும்.group_vars/மற்றும்host_vars/ஆகியவை நடுப்பகுதியில் உள்ளன. உங்கள் தளத்திற்குரிய குறிப்பிட்ட மதிப்புகளை இங்கேதான் அமைக்க வேண்டும்; இவை role defaults-ஐ எளிதாக முறியடிக்கும்.roles/<name>/vars/main.ymlஎன்பதுhost_vars-க்கு மேலே உள்ளது. இங்கே நீங்கள் அமைக்கும் மதிப்பை inventory மூலம் மாற்ற முடியாது. ஒரு package பெயர் மற்றும் service பெயர் ஒன்றாக இருக்க வேண்டியது போன்ற, role-ன் உள்நிலைத் தேவைக்காக மட்டும் இதை ஒதுக்குங்கள்.- ஒரு role-ஐ அழைக்கும் இடத்தில் (call site) வழங்கப்படும் parameter,
vars/main.yml-ஐ விட அதிக முன்னுரிமை பெறும். command line-ல் வழங்கப்படும்-e, role parameters உட்பட அனைத்தையும் விட அதிக முன்னுரிமை பெறும்.
இதை ஒரு நிமிடத்தில் நீங்கள் சரிபார்க்கலாம். ஒரு சிறிய role-க்கு ஒரு default மற்றும் ஒரு role var-ஐக் கொடுத்துவிட்டு, அதே பெயர்களை 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 அச்சிடப்படும். Inventory-ல் உள்ள மதிப்பு role default-ஐ முறியடித்தது, ஆனால் role var-க்கு முன்னால் தோல்வியடைந்தது. இரண்டாவது முறை இயக்கும்போது internal=from-cli அச்சிடப்படும், ஏனெனில் extra vars வரிசைமுறையின் உச்சியில் உள்ளது, எவராலும் அதை மாற்ற முடியாது. இதனால்தான் -e ஒருமுறை மட்டும் இயக்கும் பணிகளுக்குச் சரியானது, ஆனால் நிரந்தரமான script-களுக்குத் தவறானது: இது உங்கள் repository-ல் எடுக்கப்பட்ட அனைத்து முடிவுகளையும் அமைதியாக முறியடித்துவிடும்.
செயல்முறை விதி: ஒரு மதிப்பை மாற்றக்கூடியதாக வைத்திருக்க விரும்பினால், அதை defaults/-ல் வைக்கவும். அதை vars/-ல் வைப்பது, அந்த role-ஐப் பயன்படுத்தும் அனைவருக்கும், inventory மூலம் அதை மாற்ற முடியாது என்பதை உணர்த்தும். சில நேரங்களில் நீங்கள் இதைத்தான் விரும்பலாம், ஆனால் பெரும்பாலும் இது தவறுதலாகவே நடக்கும்.
Role-ன் idempotent தன்மையை நிரூபித்தல்: இருமுறை இயக்குதல்
நம்பகமான ஒரு Ansible run, இரண்டாவது முறை இயக்கும்போது அதே முடிவைத் தர வேண்டும் மற்றும் எந்த மாற்றமும் செய்யப்படவில்லை என்பதை உறுதிப்படுத்த வேண்டும். Playbook-ஐ இருமுறை இயக்கி, அதன் recap-ஐ கவனிக்கவும்.
ansible-playbook -i inventory.ini site.yml
ansible-playbook -i inventory.ini site.ymlஇரண்டாவது recap பின்வருமாறு இருக்க வேண்டும்:
PLAY RECAP *********************************************************************
localhost : ok=4 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0changed=0 என்பது ஒவ்வொரு module-ம் தற்போதைய நிலையை ஆய்வு செய்து, வேலை ஏற்கனவே முடிந்துவிட்டதை உறுதிப்படுத்தியது என்று பொருள். இரண்டாவது முறையில் changed=2 என்று வந்தால், அந்த இரண்டு task-களும் தற்போதைய நிலையை அறிய முடியவில்லை என்று அர்த்தம்; இதனால் அவை தொடர்ந்து கோப்புகளை மீண்டும் எழுதி, service-களை restart செய்துகொண்டே இருக்கும். இதற்கு பெரும்பாலும் command அல்லது shell காரணமாக இருக்கும், ஏனெனில் ஒரு தன்னிச்சையான 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அந்த playbook-ஐ இருமுறை இயக்கி, wc -l /tmp/grow.txt /tmp/guarded.txt உள்ள வரிகளை எண்ணுங்கள். /tmp/grow.txt இரண்டு வரிகளைக் கொண்டிருக்கும், /tmp/guarded.txt ஒரு வரியைக் கொண்டிருக்கும். இரண்டாவது முறையில், பாதுகாக்கப்பட்ட task (guarded task) இயங்காது, அதன் முடிவு skipped, since /tmp/guarded.txt exists என்ற செய்தியைக் கொண்டிருக்கும். ஏனெனில் creates அந்த module-க்கு முதலில் தேட வேண்டிய ஒரு தெளிவான பொருளை (product) வழங்குகிறது. ஒரு command அத்தகைய பொருளை உருவாக்கவில்லை என்றால், அதன் வெளியீட்டை register செய்து, changed_when மூலம் நீங்களே முடிவெடுங்கள்.
ansible-playbook --check --diff site.yml மாற்றங்களைச் செய்யாமலேயே அவற்றை முன்கூட்டியே கணிக்கும், --diff ஒரு template மாற்றப்போகும் சரியான வரிகளை அச்சிடும். இந்த வெளியீட்டைப் பார்க்கும்போது ஒரு எச்சரிக்கையை மனதில் கொள்ளுங்கள்: shell மற்றும் command task-கள் check mode-ல் தவிர்க்கப்படும், எனவே பார்ப்பதற்குச் சரியாகத் தெரியும் ஒரு திட்டம் சில வேலைகளை மறைக்கக்கூடும்.
அந்த recap-ல் உள்ள மற்றொரு column-ம் கவனத்திற்குரியது: Ansible இணைக்க முடியாத ஒரு host, failed என்பதற்குப் பதிலாக unreachable-ன் கீழ் கணக்கிடப்படும். அதன் எந்த task-ம் இயங்காது, எனவே ஒரு unreachable host முழு run-ஐயும் நிறுத்த வேண்டுமா என்பதை முன்கூட்டியே முடிவு செய்யுங்கள், இந்த role-ஐ ஒன்றுக்கும் மேற்பட்ட machines-ல் பயன்படுத்துவதற்கு முன்பு இதைச் செய்யவும்.
Ansible ஏன் role கண்டறியப்படவில்லை என்று கூறுகிறது
Ansible, playbook கோப்பிற்கு அருகில் உள்ள roles/ கோப்பகத்தையும், பின்னர் roles_path-ஐயும் தேடுகிறது. இந்தத் தேடல் உங்கள் shell-ஐ அடிப்படையாகக் கொள்ளாமல், playbook-ஐ அடிப்படையாகக் கொண்டே அமைகிறது.
ERROR! the role 'common' was not found in /home/deploy/lonely/roles:/home/deploy/lonelyஅந்தச் செய்தி, site.yml மற்றும் roles/ ஆகியவற்றுக்கு இடையே முரண்பாடு ஏற்பட்டுள்ளதைக் குறிக்கிறது; அது தேடிய பாதைகளை அதுவே தெளிவாகக் காட்டுகிறது. இரண்டையும் ஒரே கோப்பகத்தில் வைத்திருங்கள். ஒரு parent கோப்பகத்திலிருந்து இயக்குவது தவறல்ல, ஏனெனில் playbook இருக்கும் பாதையே கணக்கில் கொள்ளப்படுகிறது:
ansible-playbook -i infra/inventory.ini infra/site.ymlஇதே சிக்கலில் அமைதியான ஒரு வகையும் உள்ளது. தற்போதைய கோப்பகம் world writable நிலையில் இருந்தால், அதில் உள்ள ansible.cfg-ஐ Ansible புறக்கணிக்கும். ஏனெனில், அந்த server-ல் உள்ள எந்தவொரு பயனரும் அங்கு ஒரு config கோப்பை வைத்து, உங்கள் செயல்பாட்டை மாற்ற முடியும்.
[WARNING]: Ansible is being run in a world writable directory (/tmp/infra), ignoring it as an ansible.cfg source.அப்போது உங்கள் roles_path மற்றும் inventory அமைப்புகள் எந்த அறிவிப்பும் இன்றி செயல்படாமல் போகும், மேலும் role தேடல் தோல்வியடையும்; இதற்கும் role-களுக்கும் எந்தத் தொடர்பும் இருக்காது. ansible --version கட்டளை அது உண்மையில் ஏற்றிய config file-ஐக் காட்டும், மேலும் ansible-config dump --only-changed கட்டளை இயல்புநிலை அமைப்புகளிலிருந்து மாறுபடும் அனைத்து அமைப்புகளையும் காட்டும். உங்கள் config கோப்பு இல்லாதது போல ஒரு செயல்பாடு நடந்தால், இந்த இரண்டையும் சரிபார்க்கவும்.
பங்களிப்பு பாத்திரங்கள் (roles): requirements.yml மற்றும் pinned version
மற்றொருவர் எழுதிய ஒரு role-ஐ நகலெடுக்காமல், install செய்ய வேண்டும். அதை ஒருமுறை மட்டும் கீழே உள்ளவாறு குறிப்பிடவும்:
# 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-ஐ அமைக்கவும். இதைச் செய்யாவிட்டால், நீங்கள் கட்டளையை இயக்கும் நாளில் default branch-ல் என்ன உள்ளதோ அதுவே பதிவிறக்கப்படும். இதனால், கடந்த மாதம் சரியாக வேலை செய்த deployment, உங்கள் repository-ல் எந்த மாற்றமும் செய்யாமலேயே திடீரென செயலிழக்கக்கூடும். roles_path-ஐ பதிவிறக்கக் கோப்பகத்திற்கு (download directory) சுட்டிக்காட்டவும், அந்த கோப்பகத்தை git-ல் சேர்க்க வேண்டாம்:
# ansible.cfg
[defaults]
inventory = inventory.ini
roles_path = ./galaxy_rolesPlaybook-க்கு அருகில் உள்ள roles/-ல் இருக்கும் roles தொடர்ந்து கண்டறியப்படும், ஏனெனில் roles_path-உடன் சேர்த்து அந்த பாதையும் எப்போதும் தேடப்படும். எனவே, உங்கள் சொந்த roles-ஐ git-ல் commit செய்து ஆய்வு செய்ய முடியும், அதே சமயம் மூன்றாம் தரப்பு roles-ஐ ஒரு குறிப்பிட்ட tag-க்கு pinned செய்து மீண்டும் உருவாக்கக்கூடிய (reproducible) பதிவிறக்கங்களாக வைத்திருக்க முடியும்.
எந்த இடத்தில் roles தீர்வாக இருக்காது
ஒரு Ansible run-க்குள் மறுபயன்பாட்டிற்கான ஒரு அலகுதான் role. இது உங்கள் service provider-ல் server-களையோ அல்லது DNS record-களையோ உருவாக்காது. அவ்வாறு செய்ய முயற்சிப்பது, பராமரிக்க முடியாத சிக்கலான playbook-களை உருவாக்கும். நீங்கள் தொடங்குவதற்கு முன் Ansible மற்றும் Terraform இடையேயான பணிப்பிரிப்பு குறித்த கட்டுரையை வாசிப்பது அவசியம். ஒரு role, inventory வடிவமைப்பிற்கு மாற்றாகவும் இருக்க முடியாது: சில server-களைத் தாண்டி நீங்கள் செல்லும்போது, server-களை எவ்வாறு குழுப்படுத்துவது மற்றும் அணுகுவது என்பது, tasks எவ்வாறு கோப்பு முறையில் சேமிக்கப்பட்டுள்ளன என்பதை விட முக்கியமானது.
இந்த common role நிறுவும் hardening வசதிக்கும் தனிப்பட்ட முடிவுகள் தேவை. மேலே உள்ள drop-in இரண்டு directives-ஐ மட்டுமே அமைக்கிறது. எனவே, நீங்கள் வைத்திருக்கும் ஒவ்வொரு host-க்கும் எவை தேவை என்பதை முடிவு செய்வதற்கு முன், எந்த SSH அமைப்புகளை மாற்றுவது பயனுள்ளது மற்றும் Ubuntu-வில் பாதுகாப்பு மேம்படுத்தல்களை தானாகவே எவ்வாறு செயல்படுத்துவது என்பதை வாசிக்கவும்.
FAQ
Ansible playbook-ஐ எப்போது role-ஆக மாற்ற வேண்டும்?
ஒரே மாதிரியான tasks தொகுப்பை இரண்டாவது play-ல் அல்லது இரண்டாவது host குழுவில் இயக்க வேண்டியிருக்கும் போது இதைச் செய்ய வேண்டும். Playbook-களுக்கு இடையே tasks-ஐ நகலெடுப்பது ஒரு எச்சரிக்கை அறிகுறியாகும்; ஏனெனில், ஒரு திருத்தத்தை இரண்டு இடங்களில் செய்ய வேண்டியிருக்கும் போது, ஏதேனும் ஒரு இடத்தில் அதைச் செய்ய மறந்துவிட வாய்ப்புள்ளது. சுமார் 100 வரிகளுக்குக் குறைவாகவும், ஒரே ஒரு குழுவை மட்டும் இலக்காகக் கொண்ட ஒரு playbook-க்கு role-ஆல் எந்தப் பயனும் இல்லை; மாறாக, கூடுதல் directories கோப்புகளைப் படிப்பதைக் கடினமாக்கும்.
Roles, அதே play-ல் உள்ள tasks-க்கு முன்னதாக இயங்குமா?
ஆம். Ansible முதலில் pre_tasks-ஐ இயக்கும், பிறகு roles:-ன் கீழ் உள்ள அனைத்தையும், அதன் பின் tasks: மற்றும் post_tasks:-ஐ இயக்கும். உங்கள் கோப்பில் இந்த keys எந்த வரிசையில் இருந்தாலும், Ansible இந்த வரிசையையே பின்பற்றும். tasks:-ஐ roles:-க்கு மேலே எழுதினாலும், அந்த tasks முதலில் இயங்காது. ஒரு role-க்கு முன்னால் ஏதேனும் ஒன்று நடக்க வேண்டும் என்றால், அதை pre_tasks:-ல் சேர்க்கவும்.
எனது group_vars மதிப்பு ஏன் role-ஐ override செய்யவில்லை?
அந்த variable, defaults/main.yml-க்கு பதிலாக role-ன் vars/main.yml-ல் அமைக்கப்பட்டுள்ளதா என்று சரிபார்க்கவும். Ansible-ன் முன்னுரிமை வரிசையில் (precedence order) vars/, group_vars மற்றும் host_vars-க்கு மேலே இருப்பதால், inventory-ஆல் அதை override செய்ய முடியாது. அந்த variable-ஐ defaults/main.yml-க்கு மாற்றவும்; இது வரிசையின் இறுதியில் இருப்பதால், caller மாற்ற விரும்பும் எதற்கும் இதுவே சரியான இடமாகும். இது எழுத்துப் பிழையா அல்லது முன்னுரிமைப் பிரச்சினையா என்பதை உறுதிப்படுத்த, மற்ற அனைத்து ஆதாரங்களையும் விட அதிக முன்னுரிமை கொண்ட -e name=value-ஐப் பயன்படுத்தி ஒருமுறை இயக்கவும்.
Role கண்டறியப்படவில்லை என்று Ansible ஏன் கூறுகிறது?
தேடல் playbook கோப்பிற்கு அருகிலேயே தொடங்கும், எனவே site.yml மற்றும் roles/ ஒரே directory-ல் இருக்க வேண்டும். பிழைச் செய்தியில் the role 'common' was not found in /home/deploy/lonely/roles:/home/deploy/lonely-ல் காட்டப்படுவது போல, அது தேடிய பாதைகள் குறிப்பிடப்பட்டிருக்கும். Playbook-ஐ ஒரு parent directory-லிருந்து இயக்குவது தவறல்ல, ஏனெனில் தேடல் உங்கள் shell-ன் தற்போதைய directory-ஐப் பின்பற்றாமல், playbook-ன் பாதையைப் பின்பற்றும். நீங்கள் ansible.cfg-லிருந்து roles_path-ஐச் சார்ந்திருந்தால், அது ansible --version மூலம் ஏற்றப்பட்டதா என்பதை உறுதிப்படுத்தவும்; ஏனெனில், எவரும் எழுதக்கூடிய (world writable) directory-ல் இருந்தால் Ansible அதைத் தவிர்க்கும்.
Role-ஐ உருவாக்க ansible-galaxy init அவசியமா?
இல்லை. ஒரு role என்பது எதிர்பார்க்கப்படும் பெயர்களைக் கொண்ட directories மட்டுமே, எனவே mkdir -p roles/common/tasks மற்றும் ஒரு tasks/main.yml இருந்தாலே அது ஒரு செயல்படும் role ஆகும். ansible-galaxy init --init-path roles common தட்டச்சு செய்வதைக் குறைத்து, meta/main.yml மற்றும் README stub உள்ளிட்ட முழுமையான கட்டமைப்பை வழங்குகிறது. காலியாக இருக்கும் directories-ஐ நீக்கிவிடவும், ஏனெனில் காலியான vars/main.yml, role-ல் எந்தெந்த கோப்புகள் உண்மையில் செயல்படுகின்றன என்பதை மறைத்துவிடும்.