Tofauti kati ya Ansible playbook na role
Jifunze wakati mwafaka wa kutumia playbook ya kawaida dhidi ya Ansible role. Tunachambua mpangilio wa saraka, matumizi ya ansible-galaxy init, na kanuni za kipaumbele za vigezo.
Tofauti kati ya Ansible playbook na role
Ansible playbook ni faili unaloliendesha kwa kutumia ansible-playbook. Linahusisha kundi la hosts na kazi zinazopaswa kufanyika. Ansible role ni saraka yenye mpangilio maalum inayohifadhi tasks, templates, handlers na default variables, na playbook huiita kwa jina lake. Sintaksia ya task ndani ya zote mbili inafanana, kwa hivyo hii si swali la kile unachoweza kuelezea. Ni swali la matumizi ya kurudia (reuse).
Anza na playbook ya kawaida. site.yml moja inayoshikilia orodha ya tasks: ndiyo umbo sahihi kwa ajili ya otomatiki yako ya kwanza, na inabaki kuwa sahihi kwa muda mrefu kuliko watu wengi wanavyotarajia. Badilisha kuwa role wakati kundi lilelile la tasks linapohitajika kuendeshwa kwa kundi la pili la hosts, au wakati faili linapozidi takriban mistari 100 na huwezi tena kupata task kwa kusogeza ukurasa.
Ikiwa bado hujaandika hata moja, anza na playbook ya kwanza dhidi ya VPS moja na urudi hapa wakati inapoanza kukua.
Wakati playbook ya kawaida inapofaa
Playbook ya kawaida (flat playbook) inafaa wakati kazi inafanyika mara moja, au kwenye host moja, au wakati hakuna mtu mwingine atakayeisoma. Kusanidi seva moja ya programu, au kufanya patching ya seva kabla ya muda wa matengenezo: hakuna kati ya hayo linalohitaji muundo wa saraka (directory tree). Role huongeza saraka saba na safu moja ya ziada ya kurejelea (indirection). Ikiwa mpigaji simu pekee ni playbook iliyo karibu nayo, kurejelea huko hakuna faida yoyote na kunakulazimisha kuruka kurasa kila wakati unapotaka kusoma kile kinachoendeshwa kihalisi.
Playbook ya kawaida huacha kuwa sahihi katika wakati maalum, na wakati huo ni rahisi kuutambua. Unapokopi kizuizi cha tasks kwenye playbook ya pili. Kopi hiyo ndiyo ishara. Kuanzia hapo, kila marekebisho lazima yafanyike mara mbili, na siku moja yatafanywa mara moja tu.
Yaliyomo halisi kwenye saraka ya role
roles/common/
defaults/main.yml
vars/main.yml
tasks/main.yml
handlers/main.yml
templates/99-hardening.conf.j2
files/
meta/main.ymltasks/main.ymlndiyo sehemu ya kuanzia. Ansible huendesha faili hili wakati role inapoitwa, na kila saraka nyingine ni ya hiari.defaults/main.ymlhuhifadhi vigezo (variables) ambavyo anayetoa wito anatarajiwa kuvibadilisha. Hii ndiyo chanzo chenye kipaumbele cha chini kabisa katika Ansible, kwa hivyo karibu kila kitu kingine huizidi kwa nguvu.vars/main.ymlhuhifadhi vigezo ambavyo anayetoa wito hatarajiwi kuvibadilisha. Inakaa juu ya inventory katika kipaumbele, jambo ambalo ni agizo zito. Itumie kwa nadra.handlers/main.ymlhuhifadhi tasks zinazochochewa nanotify. Handler huendeshwa mwishoni mwa play, mara moja tu, bila kujali ni tasks ngapi zimeiita.files/huhifadhi faili zinazonakiliwa kama zilivyo na moduli yacopy, natemplates/huhifadhi Jinja2 templates zinazotafsiriwa na moduli yatemplate. Ndani ya role, unarejelea zote mbili kwa jina la faili pekee bila njia (path), kwa sababu Ansible hutafuta kwenye saraka za role yenyewe kwanza.meta/main.ymlhutangaza utegemezi wa role (dependencies) na metadata inayosomwa na Ansible Galaxy.
Mpangilio huu si suala la upendeleo wa mtindo. Ansible hutafuta katika njia hizi kamili, kwa hivyo template unayoiweka kwenye roles/common/template/ (umoja) haitapatikana kamwe.
Jenga role ya kawaida kwa kutumia ansible-galaxy init
mkdir -p ~/infra/roles
cd ~/infra
ansible-galaxy init --init-path roles commonAmri hiyo huandika muundo mzima wa faili chini ya roles/common, ikijumuisha saraka ambazo hutazitumia na stubs za main.yml zenye --- pekee. Futa zile unazoziaacha tupu. Faili tupu ya vars/main.yml haina madhara kwa Ansible, lakini huficha ni faili zipi ndani ya role hiyo ambazo ni muhimu.
Sasa jaza faili zinazotekeleza kazi. Anza na defaults, kwa sababu ndizo interface ya umma ya role hiyo.
# roles/common/defaults/main.yml
---
common_packages:
- ufw
- fail2ban
- unattended-upgrades
common_admin_group: admins
common_permit_root_login: "no"
common_password_authentication: "no"Weka alama za kunukuu kwenye "no" na "yes". Ansible huchakata YAML kwa kutumia PyYAML, ambayo husoma no tupu kama boolean false, kwa hivyo mstari wa usanidi unaotokana huwa PermitRootLogin False na sshd huukataa. Alama za kunukuu huhakikisha thamani hiyo inabaki kama 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 }}Kwenye Debian na Ubuntu, unit ya systemd inaitwa ssh, na kwenye mifumo ya familia ya RHEL inaitwa sshd. Handler inayotaja jina lisilo sahihi itafeli tu wakati kitu fulani kinapobadilisha template, ndiyo maana tatizo hili mara nyingi hujitokeza wiki kadhaa baadaye.
Mstari wa validate ndio kitu muhimu zaidi katika task hiyo. Ansible huchakata template na kuiweka kwenye faili ya muda, hubadilisha njia ya faili hiyo na %s, kisha huendesha amri hiyo. Faili ya mwisho hubadilishwa tu ikiwa amri itatoka na exit code 0. Weka directive isiyo na maana kwenye template na uendeshe tena: task itafeli na failed to validate, faili halisi ya /etc/ssh/sshd_config.d/99-hardening.conf haitaguswa, na bado utakuwa na seva unayoweza kuingia. Fahamu kuwa ukaguzi huu hujaribu zaidi ya syntax yako. Ikiwa sshd -t haiwezi kusoma host keys, itatoka na sshd: no hostkeys available -- exiting. na Ansible itaripoti failed to validate hiyohiyo, kwa hivyo soma msg ya module hiyo kabla ya kulaumu template.
Jinsi playbook inavyoita 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 inapaswa kumalizika na failed=0 katika muhtasari. Pitisha vigezo (parameters) kwenye sehemu ya mwito kwa kutumia fomu iliyopanuliwa, ambayo ndiyo njia ya role moja kuhudumia makundi mawili ya hosts:
roles:
- role: common
common_admin_group: ops
common_permit_root_login: prohibit-passwordKuna kanuni moja ya mpangilio inayowashangaza karibu watu wote. Play inaweza kuwa na pre_tasks, roles, tasks na post_tasks, na Ansible huzitekeleza kwa mpangilio huo bila kujali mpangilio uliouandika kwenye faili. Weka tasks: juu ya roles: na roles bado zitatekelezwa kwanza. Kwa hivyo, ikiwa kitu lazima kitokee kabla ya role, kinapaswa kuwa ndani ya pre_tasks:, siyo juu ya 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: postIli kuita role kutoka ndani ya orodha ya tasks badala ya kutumia ufunguo wa roles:, tumia import_role au 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 ni tuli (static). Ansible husoma role wakati wa kuchanganua (parse time) na tasks zake huwa sehemu ya play, kwa hivyo ansible-playbook --list-tasks site.yml huziorodhesha na tag iliyowekwa kwenye import huathiri kila task iliyo ndani. include_role ni dinamiki (dynamic). Hakuna kinachosomwa hadi task itekelezwe, jambo ambalo hukuruhusu kuendesha jina la role kutoka kwa variable au loop. Gharama yake ni kwamba tasks hizo hazionekani na --list-tasks na --start-at-task.
Mtego mmoja upo hapa. when: kwenye task ya include_role hutathminiwa kabla ya defaults/main.yml ya role iliyojumuishwa (included) kuwa katika wigo (scope). Andika when: common_packages | length > 0 kwenye include na utekelezaji utasitishwa na 'common_packages' is undefined, ingawa variable hiyo imefafanuliwa ndani ya role yenyewe unayoiingiza. Suluhisho ni kuondoa kigezo hicho nje ya role: kiweke kwenye group_vars/all.yml, ambapo kinapatikana kila mahali, na uache defaults za role kwa ajili ya thamani ambazo role yenyewe huzitumia.
Which variable wins: defaults, group_vars, vars, extra vars
Ansible documents more than twenty levels of variable precedence. Four of them settle nearly every real argument, and here they are from weakest to strongest.
roles/<name>/defaults/main.ymlsits near the bottom. Almost anything you set anywhere else beats it, which is exactly why it is the right home for a role's tunable knobs.group_vars/andhost_vars/sit in the middle. This is where your site's own answers belong, and they cleanly override role defaults.roles/<name>/vars/main.ymlsits abovehost_vars. A value you put here cannot be overridden from inventory. Reserve it for things the role needs to stay internally consistent, such as a package name that has to match a service name.- A role parameter passed at the call site beats
vars/main.yml, and-eon the command line beats everything, including role parameters.
You can watch this resolve in about a minute. Give a small role one default and one role var, then set the same names in 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-cliThe first run prints tunable=from-hostvars internal=from-rolevars. Inventory beat the role default and lost to the role var. The second run prints internal=from-cli, because extra vars sit at the very top and nothing below can push back. That is also why -e is fine for a one-off run and wrong in a script you keep: it silently outranks every considered decision in your repository.
The working rule: if you want a value to be settable, it goes in defaults/. Putting it in vars/ tells every future user of the role that inventory may not change it. That is occasionally what you meant, and usually an accident.
Thibitisha kuwa role ni idempotent: iendeshe mara mbili
Ansible playbook inayotegemeka hutoa matokeo sawa katika jaribio la pili na kuripoti kuwa hakuna kilichobadilika. Endesha playbook mara mbili na usome muhtasari wake.
ansible-playbook -i inventory.ini site.yml
ansible-playbook -i inventory.ini site.ymlMuhtasari wa pili unapaswa kuonekana hivi:
PLAY RECAP *********************************************************************
localhost : ok=4 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0changed=0 inamaanisha kila moduli ilikagua hali ya sasa na kugundua kuwa kazi imeshakamilika. changed=2 katika jaribio la pili inamaanisha kuna tasks mbili ambazo haziwezi kutofautisha hali ya sasa na inayotakiwa, hivyo zitaendelea kuandika upya faili na kuanzisha upya huduma bila kikomo. Sababu ya kawaida ni command au shell, kwa sababu Ansible haina njia ya kujua nini amri ya kiholela imefanya.
# 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.txtEndesha playbook hiyo mara mbili, kisha uhesabu mistari yenye wc -l /tmp/grow.txt /tmp/guarded.txt. /tmp/grow.txt ina mistari miwili na /tmp/guarded.txt ina mstari mmoja. Katika jaribio la pili, task iliyolindwa haikutekelezwa kabisa, na matokeo yake yana ujumbe skipped, since /tmp/guarded.txt exists, kwa sababu creates huipa moduli kitu kinachoonekana cha kukagua kwanza. Amri inaposhindwa kuacha kitu kama hicho, hifadhi matokeo yake (register) na uamue mwenyewe kwa kutumia changed_when.
ansible-playbook --check --diff site.yml hutabiri mabadiliko bila kuyafanya, na --diff huchapisha mistari kamili ambayo template ingeandika upya. Soma matokeo hayo kwa kuzingatia tahadhari moja: tasks za shell na command hurukwa katika check mode, kwa hivyo mpango unaoonekana kuwa safi unaweza bado kuficha kazi inayopaswa kufanyika.
Kwa nini Ansible inasema role haikupatikana
Ansible hutafuta saraka ya roles/ karibu na faili ya playbook, kisha katika roles_path. Utafutaji hufuata playbook, si shell yako.
ERROR! the role 'common' was not found in /home/deploy/lonely/roles:/home/deploy/lonelyUjumbe huo unamaanisha kuwa site.yml na roles/ zimetofautiana, na inachapisha njia ilizojaribu kwa manufaa yako. Weka faili hizo mbili katika saraka moja. Kuendesha kutoka saraka kuu ni sawa, kwa sababu njia ya playbook ndiyo inayozingatiwa:
ansible-playbook -i infra/inventory.ini infra/site.ymlKuna toleo tulivu zaidi la tatizo hilo hilo. Ansible hupuuza ansible.cfg katika saraka ya sasa wakati saraka hiyo ina ruhusa ya kuandikwa na kila mtu (world writable), kwa sababu mtumiaji yeyote kwenye seva anaweza kuweka usanidi hapo na kubadilisha utendaji wa run yako.
[WARNING]: Ansible is being run in a world writable directory (/tmp/infra), ignoring it as an ansible.cfg source.Mipangilio yako ya roles_path na inventory inakuwa haipo kimyakimya, na utafutaji wa role unashindwa kwa sababu isiyo na uhusiano wowote na roles. ansible --version huchapisha config file iliyopakia, na ansible-config dump --only-changed huchapisha kila mpangilio unaotofautiana na chaguo-msingi za mfumo. Kagua zote mbili wakati wowote run inapoonekana kama usanidi wako haupo.
Kushiriki roles: mahitaji ya requirements.yml na toleo lililofungwa (pinned)
Role iliyoandikwa na mtu mwingine husakinishwa, hainakiliwi. Itangaze mara moja:
# 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_rolesWeka version kila wakati. Bila hiyo, utapata toleo lolote lililopo kwenye branch chaguo-msingi siku unayotekeleza amri hiyo, hivyo deployment iliyofanya kazi mwezi uliopita itafeli bila mabadiliko yoyote kwenye repository yako. Elekeza roles_path kwenye saraka ya kupakua, na uweke saraka hiyo nje ya git:
# ansible.cfg
[defaults]
inventory = inventory.ini
roles_path = ./galaxy_rolesRoles zilizo ndani ya roles/ karibu na playbook bado hupatikana, kwa sababu njia hiyo hutafutwa kila wakati pamoja na roles_path. Kwa hivyo, roles zako mwenyewe hubaki zikiwa zimefanyiwa commit na kupitiwa, huku roles za watu wengine zikiwa ni vipakuliwa vinavyoweza kurudiwa na vilivyofungwa kwenye tag fulani.
Wakati roles zinapoacha kuwa suluhisho
Role ni kitengo cha matumizi ya mara kwa mara ndani ya Ansible run moja. Haitengenezi seva au DNS records kwa mtoa huduma wako, na kujaribu kuilazimisha kufanya hivyo ndiyo njia inayofanya playbooks kugeuka kuwa kitu ambacho hakuna mtu anayetaka kukitunza. mgawanyo wa kazi kati ya Ansible na Terraform inafaa kusomwa kabla ya kuanza. Pia, role haichukui nafasi ya usanifu wa inventory: ukishavuka idadi ndogo ya mashine, jinsi unavyozipanga na kuzifikia seva hizo ni muhimu zaidi kuliko jinsi tasks zinavyohifadhiwa kwenye faili.
Uimarishaji wa usalama (hardening) ambao role hii ya common inasakinisha unastahili maamuzi yake yenyewe pia. Usanidi wa haraka hapo juu unaweka maelekezo mawili tu na si zaidi, kwa hivyo soma ni mipangilio ipi ya SSH inayostahili kubadilishwa kweli na jinsi ya kuifanya Ubuntu itekeleze masasisho ya usalama yenyewe kabla ya kuamua ni nini kinachopaswa kuwemo kwenye role kwa kila host unayomiliki.
FAQ
Ni lini ninapaswa kubadilisha Ansible playbook kuwa role?
Wakati kundi lilelile la tasks linapohitajika kutekelezwa katika play ya pili, au dhidi ya kundi la pili la hosts. Kunakili tasks kati ya playbooks ndiyo ishara ya kufanya hivyo, kwa sababu kuanzia wakati huo kila marekebisho yatalazimika kufanywa mara mbili na siku moja yatafanywa mara moja tu. Playbook moja yenye takriban mistari 100 ambayo inalenga kundi moja tu haipati faida yoyote kutoka kwa role, na saraka za ziada hufanya iwe vigumu kusoma.
Je, roles hutekelezwa kabla ya tasks katika play moja?
Ndiyo. Ansible hutekeleza pre_tasks, kisha kila kitu kilichoorodheshwa chini ya roles:, kisha tasks:, kisha post_tasks:, na hupuuza mpangilio ambao funguo hizo zinaonekana kwenye faili yako. Kuandika tasks: juu ya roles: hakufanyi tasks hizo kutekelezwa kwanza. Ikiwa kitu lazima kitokee kabla ya role, kiweke ndani ya pre_tasks:.
Kwa nini thamani yangu ya group_vars haibatilishi role?
Angalia kama variable imewekwa ndani ya vars/main.yml ya role badala ya defaults/main.yml. vars/ iko juu ya group_vars na host_vars katika mpangilio wa kipaumbele wa Ansible, kwa hivyo inventory haiwezi kuibatilisha. Hamisha variable hiyo kwenda defaults/main.yml, ambayo iko karibu na chini ya mpangilio na ndiyo mahali sahihi kwa chochote ambacho mwitaji anapaswa kuwa na uwezo wa kukibadilisha. Ili kuthibitisha kuwa kipaumbele ndiyo sababu badala ya kosa la uchapaji, tekeleza mara moja kwa kutumia -e name=value, ambayo inazidi kila chanzo kingine.
Kwa nini Ansible inasema role haikupatikana?
Utafutaji huanzia karibu na faili ya playbook, kwa hivyo site.yml na roles/ lazima viwe katika saraka moja. Ujumbe wa kosa huchapisha njia zilizojaribiwa, kama ilivyo katika the role 'common' was not found in /home/deploy/lonely/roles:/home/deploy/lonely. Kutekeleza playbook kutoka saraka kuu ni sawa, kwa sababu utafutaji hufuata njia ya playbook na si saraka ya kazi ya shell yako. Ikiwa unategemea roles_path kutoka ansible.cfg, thibitisha kuwa faili hiyo ilipakiwa na ansible --version, kwa kuwa saraka ya kazi inayoweza kuandikwa na kila mtu (world writable) huifanya Ansible kuipuuza.
Je, ninahitaji ansible-galaxy init ili kuunda role?
Hapana. Role ni saraka tu zenye majina yanayotarajiwa, kwa hivyo mkdir -p roles/common/tasks pamoja na tasks/main.yml tayari ni role inayofanya kazi. ansible-galaxy init --init-path roles common huokoa muda wa kuandika na kukupa muundo kamili, ikijumuisha meta/main.yml na sehemu ya README. Futa saraka unazoziaacha wazi, kwa sababu vars/main.yml tupu huficha ni faili zipi ndani ya role zinazofanya kazi kweli.