Ես շատ ակնարկներ եմ անում այլ մարդկանց Ansible կոդի վերաբերյալ և ինքս շատ բան գրում: Սխալների վերլուծության ընթացքում (ինչպես ուրիշների, այնպես էլ իմ սեփական), ինչպես նաև մի շարք հարցազրույցների ընթացքում ես հասկացա Ansible-ի օգտատերերի հիմնական սխալը. նրանք մտնում են բարդ բաների մեջ՝ չյուրացնելով հիմնականը:
Այս համընդհանուր անարդարությունը շտկելու համար ես որոշեցի գրել Ansible-ի ներածություն նրանց համար, ովքեր արդեն գիտեն այն: Զգուշացնում եմ ձեզ, սա մարդկանց վերապատմում չէ, սա վաղուց արդեն շատ տառերով և առանց նկարների:
Ընթերցողի ակնկալվող մակարդակն այն է, որ մի քանի հազար տող յամլա արդեն գրված է, ինչ-որ բան արդեն արտադրվում է, բայց «ինչ-որ կերպ ամեն ինչ ծուռ է»:
Վերնագրեր
Հիմնական սխալը, որը թույլ է տալիս Ansible օգտվողը, այն է, որ չգիտի, թե ինչ է կոչվում ինչ-որ բան: Եթե դուք չգիտեք անունները, չեք կարող հասկանալ, թե ինչ է գրված փաստաթղթերում: Կենդանի օրինակ. հարցազրույցի ժամանակ մի անձ, ով թվում էր, թե ասում է, որ շատ է գրել Ansible-ում, չի կարողացել պատասխանել «ինչ տարրերից է բաղկացած խաղագիրքը» հարցին: Եվ երբ ես առաջարկեցի, որ «սպասելի էր պատասխանը, որ խաղագիրքը բաղկացած է խաղից», հետևեց «մենք դա չենք օգտագործում» պախարակելի մեկնաբանությունը։ Մարդիկ Ansible-ը գրում են փողի համար և չեն օգտագործում խաղը: Նրանք իրականում օգտագործում են այն, բայց չգիտեն, թե դա ինչ է:
Այսպիսով, եկեք սկսենք մի պարզ բանից. ինչ է դա կոչվում: Գուցե դուք գիտեք սա, կամ գուցե չգիտեք, որովհետև ուշադրություն չէիք դարձնում փաստաթղթերը կարդալիս:
ansible-playbook-ը կատարում է խաղագիրքը: Playbook-ը yml/yaml ընդլայնմամբ ֆայլ է, որի ներսում կա այսպիսի բան.
---
- hosts: group1
roles:
- role1
- hosts: group2,group3
tasks:
- debug:
Մենք արդեն հասկացանք, որ այս ամբողջ ֆայլը խաղագիրք է: Մենք կարող ենք ցույց տալ, թե որտեղ են դերերը և որտեղ են առաջադրանքները: Բայց որտեղ է խաղը: Իսկ ո՞րն է խաղի և դերի կամ խաղային գրքի տարբերությունը:
Այդ ամենը փաստաթղթերում է: Ու կարոտում են։ Սկսնակներ - քանի որ շատ բան կա, և դուք միանգամից չեք հիշի ամեն ինչ: Փորձառու, քանի որ «չնչին բաներ»: Եթե փորձառու եք, վերընթերցեք այս էջերը առնվազն վեց ամիսը մեկ անգամ, և ձեր կոդը կդառնա դասի առաջատար:
Այսպիսով, հիշեք. Playbook-ը ցուցակ է, որը բաղկացած է խաղից և import_playbook
.
Սա մեկ պիես է.
- hosts: group1
roles:
- role1
և սա նաև մեկ այլ պիես է.
- hosts: group2,group3
tasks:
- debug:
Ի՞նչ է խաղը: Ինչու՞ է նա:
Խաղը խաղային գրքի հիմնական տարրն է, քանի որ խաղը և միայն խաղը կապում է դերերի և/կամ առաջադրանքների ցանկը հյուրընկալողների ցանկի հետ, որոնց վրա դրանք պետք է կատարվեն: Փաստաթղթերի խորքում կարող եք հիշատակել delegate_to
, տեղային որոնումների պլագիններ, ցանցի-cli-ի հատուկ կարգավորումներ, jump hosts և այլն: Նրանք թույլ են տալիս մի փոքր փոխել առաջադրանքների կատարման վայրը: Բայց, մոռացեք դրա մասին: Այս խելացի տարբերակներից յուրաքանչյուրն ունի շատ կոնկրետ կիրառություն, և դրանք հաստատ համընդհանուր չեն: Իսկ մենք խոսում ենք տարրական բաների մասին, որոնք բոլորը պետք է իմանան ու օգտագործեն։
Եթե ուզում ես «ինչ-որ բան» կատարել «ինչ-որ տեղ», ապա գրում ես պիես: Դեր չէ: Ոչ դեր մոդուլների և պատվիրակների հետ: Դու վերցնում ես ու գրում պիես: Որում hosts դաշտում նշում եք, թե որտեղ է պետք կատարել, իսկ դերերում/առաջադրանքներում՝ ինչ կատարել:
Պարզ, չէ՞: Ինչպե՞ս կարող էր այլ կերպ լինել:
Հատկանշական պահերից մեկը, երբ մարդիկ ցանկություն ունեն դա անել ոչ թե խաղի միջոցով, դա «դերը, որը կարգավորում է ամեն ինչ»: Ես կցանկանայի ունենալ մի դեր, որը կարգավորում է ինչպես առաջին տիպի, այնպես էլ երկրորդ տիպի սերվերները:
Արխետիպային օրինակ է մոնիտորինգը: Ես կցանկանայի ունենալ մոնիտորինգի դեր, որը կկարգավորի մոնիտորինգը: Մոնիտորինգի դերը վերապահված է մոնիտորինգի հյուրընկալողներին (ըստ խաղի): Բայց պարզվում է, որ մոնիտորինգի համար մենք պետք է փաթեթներ հասցնենք հյուրընկալողներին, որոնք մենք վերահսկում ենք։ Ինչու չօգտագործել պատվիրակ: Դուք նաև պետք է կարգավորեք iptable-ները: պատվիրակ? Դուք նաև պետք է գրեք/ուղղեք կոնֆիգուրացիա DBMS-ի համար՝ մոնիտորինգը միացնելու համար: պատվիրակ! Իսկ եթե կրեատիվությունը պակասում է, ապա կարող ես պատվիրակություն կազմել include_role
ներդիր հանգույցում՝ օգտագործելով բարդ զտիչ խմբերի ցանկում և ներսում include_role
դուք կարող եք ավելին անել delegate_to
կրկին. Եվ մենք հեռանում ենք ...
Բարի ցանկությունը՝ ունենալ մեկ մոնիտորինգի դեր, որն «ամեն ինչ անում է», մեզ տանում է դեպի լիակատար դժոխք, որտեղից ամենից հաճախ միայն մեկ ելք կա՝ ամեն ինչ վերաշարադրել զրոյից։
Որտե՞ղ է տեղի ունեցել սխալը այստեղ: Այն պահին, երբ դուք հայտնաբերեցիք, որ X հաղորդավարի վրա «x» առաջադրանքը կատարելու համար դուք պետք է գնայիք Y վարողին և այնտեղ «y» անեիք, դուք պետք է կատարեիք մի պարզ վարժություն՝ գնացեք և գրեք play, որը Y վարողին անում է y: «x»-ին ինչ-որ բան մի ավելացրեք, այլ գրեք զրոյից: Նույնիսկ կոշտ կոդավորված փոփոխականներով:
Թվում է, թե վերևի պարբերություններում ամեն ինչ ճիշտ է ասված։ Բայց սա քո դեպքը չէ։ Քանի որ դուք ցանկանում եք գրել բազմակի օգտագործման կոդ, որը չոր է և գրադարանի նման, և դուք պետք է փնտրեք մեթոդ, թե ինչպես դա անել:
Այստեղ է թաքնվում ևս մեկ լուրջ սխալ. Սխալ, որը շատ նախագծերից հանդուրժելի գրվածից (կարող էր ավելի լավ լինել, բայց ամեն ինչ աշխատում է և հեշտ է ավարտվում) վերածեց մի ամբողջական սարսափի, որը նույնիսկ հեղինակը չի կարող հասկանալ: Աշխատում է, բայց Աստված մի արասցե ինչ-որ բան փոխես։
Սխալն այն է. դերը գրադարանային ֆունկցիա է: Այս անալոգիան այնքան լավ սկիզբ է փչացրել, որ դիտելը պարզապես տխուր է: Դերը գրադարանային գործառույթ չէ: Նա չի կարող հաշվարկներ անել և չի կարող որոշումներ կայացնել խաղի մակարդակի վրա: Հիշեցրու ինձ, թե ինչ որոշումներ է կայացնում խաղը:
Շնորհակալություն, դու ճիշտ ես: Play-ը որոշում է կայացնում (ավելի ճիշտ՝ այն պարունակում է տեղեկատվություն) այն մասին, թե որ առաջադրանքները և դերերը պետք է կատարվեն հյուրընկալողների վրա:
Եթե դուք այս որոշումը պատվիրակում եք որևէ դերի, և նույնիսկ հաշվարկներով, դուք ինքներդ ձեզ (և նրան, ով կփորձի վերլուծել ձեր ծածկագիրը) դատապարտում եք թշվառ գոյության: Դերը չի որոշում, թե որտեղ է այն կատարվում։ Այս որոշումը կայացվում է խաղով։ Դերը անում է այն, ինչ ասում են, որտեղ ասում են:
Ինչու է վտանգավոր Ansible-ում ծրագրավորելը և ինչու է COBOL-ն ավելի լավը, քան Ansible-ը, մենք կխոսենք փոփոխականների և jinja-ի մասին գլխում: Առայժմ ասենք մի բան՝ ձեր յուրաքանչյուր հաշվարկ թողնում է գլոբալ փոփոխականների փոփոխությունների անջնջելի հետք, և դուք ոչինչ չեք կարող անել դրա դեմ: Հենց երկու «հետքերը» հատվեցին, ամեն ինչ վերացավ։
Նշում ճղճիմների համար. դերը, անշուշտ, կարող է ազդել վերահսկողության հոսքի վրա: Ուտել delegate_to
և այն ունի ողջամիտ օգտագործում: Ուտել meta: end host/play
. Բայց! Հիշո՞ւմ եք, որ մենք սովորեցնում ենք հիմունքները: Մոռացել է delegate_to
. Խոսքը ամենապարզ և ամենագեղեցիկ Ansible կոդի մասին է։ Որը հեշտ է կարդալ, հեշտ է գրել, հեշտ է վրիպազերծել, հեշտ է փորձարկել և հեշտ է լրացնել: Այսպիսով, ևս մեկ անգամ.
խաղալ և միայն խաղն է որոշում, թե որ հյուրընկալողներին ինչ է կատարվում:
Այս բաժնում մենք անդրադարձանք խաղի և դերի հակադրությանը: Հիմա եկեք խոսենք առաջադրանքների և դերային հարաբերությունների մասին:
Առաջադրանքներ և դերեր
Մտածեք խաղալ.
- hosts: somegroup
pre_tasks:
- some_tasks1:
roles:
- role1
- role2
post_tasks:
- some_task2:
- some_task3:
Եկեք ասենք, որ դուք պետք է անեք հիմար: Եվ կարծես թե foo: name=foobar state=present
. Որտեղ գրեմ սա? նախապես? գրառում? Դեր ստեղծե՞լ:
...Իսկ ո՞ւր գնացին առաջադրանքները։
Մենք նորից սկսում ենք հիմունքներից՝ խաղային սարքից: Եթե դուք լողում եք այս հարցում, ապա չեք կարող խաղալ որպես հիմք մնացած ամեն ինչի համար, և ձեր արդյունքը կլինի «երերուն»:
Խաղալ սարք. հյուրընկալող հրահանգներ, ինքնին խաղի կարգավորումներ և նախնական առաջադրանքներ, առաջադրանքներ, դերեր, post_tasks բաժիններ: Խաղի համար մնացած պարամետրերն այժմ մեզ համար կարևոր չեն։
Նրանց բաժինների կարգը առաջադրանքներով և դերերով. pre_tasks
, roles
, tasks
, post_tasks
. Քանի որ իմաստային առումով կատարման կարգը միջև է tasks
и roles
պարզ չէ, ապա լավագույն փորձը ասում է, որ մենք ավելացնում ենք բաժին tasks
, միայն թե ոչ roles
... Եթե կա roles
, ապա բոլոր կից առաջադրանքները տեղադրվում են բաժիններով pre_tasks
/post_tasks
.
Մնում է, որ ամեն ինչ իմաստային առումով պարզ է. նախ pre_tasks
, ապա roles
, ապա post_tasks
.
Բայց մենք դեռ չենք պատասխանել հարցին. որտե՞ղ է մոդուլի կանչը: foo
գրել? Արդյո՞ք մենք պետք է մի ամբողջ դեր գրենք յուրաքանչյուր մոդուլի համար: Թե՞ ավելի լավ է ամեն ինչի համար հաստ դեր ունենալ։ Իսկ եթե ոչ դեր, ապա որտե՞ղ գրեմ՝ նախա՞, թե՞ գրառման մեջ։
Եթե այս հարցերին չկա հիմնավորված պատասխան, ապա սա ինտուիցիայի պակասի նշան է, այսինքն՝ այդ նույն «երերուն հիմքերը»։ Եկեք պարզենք այն: Նախ, անվտանգության հարց. Եթե խաղն ունի pre_tasks
и post_tasks
(և չկան առաջադրանքներ կամ դերեր), ապա կարող է ինչ-որ բան կոտրվել, եթե ես կատարեմ առաջին առաջադրանքը post_tasks
Կտեղափոխեմ մինչև վերջ pre_tasks
?
Իհարկե, հարցի ձեւակերպումը հուշում է, որ այն կկոտրվի։ Բայց կոնկրետ ի՞նչ։
... Կառավարիչներ. Հիմնական բաները կարդալը բացահայտում է մի կարևոր փաստ. բոլոր կարգավորիչները ավտոմատ կերպով լվացվում են յուրաքանչյուր հատվածից հետո: Նրանք. բոլոր առաջադրանքները սկսած pre_tasks
, ապա բոլոր մշակողները, որոնք ծանուցվել են: Այնուհետև բոլոր դերերը և բոլոր մշակողները, որոնք ծանուցվել են դերերում, կատարվում են: հետո post_tasks
և նրանց կառավարողները։
Այսպիսով, եթե քաշեք առաջադրանքը post_tasks
в pre_tasks
, ապա հնարավոր է, որ դուք այն կկատարեք նախքան մշակողի գործարկումը: օրինակ, եթե ներս pre_tasks
վեբ սերվերը տեղադրված և կազմաձևված է, և post_tasks
ինչ-որ բան ուղարկվում է դրան, այնուհետև փոխանցեք այս առաջադրանքը բաժին pre_tasks
կհանգեցնի նրան, որ «ուղարկելու» պահին սերվերը դեռ չի աշխատի և ամեն ինչ կփչանա:
Հիմա եկեք նորից մտածենք, թե ինչու է մեզ անհրաժեշտ pre_tasks
и post_tasks
? Օրինակ, որպեսզի ավարտին հասցնեք այն ամենը, ինչ անհրաժեշտ է (այդ թվում՝ մշակողները) մինչև դերը կատարելը։ Ա post_tasks
թույլ կտա մեզ աշխատել դերերի կատարման արդյունքների հետ (ներառյալ մշակողները):
Ansible-ի խորաթափանց փորձագետը մեզ կասի, թե ինչ է դա: meta: flush_handlers
, բայց ինչո՞ւ են մեզ անհրաժեշտ flush_handlers, եթե մենք կարող ենք հիմնվել խաղի ընթացքում հատվածների կատարման կարգի վրա: Ավելին, մետա. when
у block
և այլն: Որքան լավ իմանաք հասկանալիը, այնքան ավելի շատ նրբերանգներ կարող եք անվանել «բարդ» լուծման համար: Իսկ պարզ լուծումը՝ օգտագործելով բնական բաժանում նախա/դերերի/հետո-ի միջեւ, նրբերանգներ չի առաջացնում:
Եվ վերադառնանք մեր «foo»-ին: Որտեղ պետք է այն դնեմ: Նախա, պաշտոնում, թե՞ դերերում: Ակնհայտ է, որ դա կախված է նրանից, թե արդյոք մեզ անհրաժեշտ են կառավարչի արդյունքները foo-ի համար: Եթե դրանք չկան, ապա foo-ն պետք չէ տեղադրել ոչ նախընտրական, ոչ էլ փոստում, այս բաժինները հատուկ նշանակություն ունեն՝ առաջադրանքների կատարում կոդի հիմնական մասից առաջ և հետո:
Այժմ «դերը կամ առաջադրանքը» հարցի պատասխանը հանգում է նրան, թե ինչն արդեն խաղում է. եթե այնտեղ առաջադրանքներ կան, ապա պետք է դրանք ավելացնել առաջադրանքներին: Եթե կան դերեր, դուք պետք է դեր ստեղծեք (թեկուզ մեկ առաջադրանքից): Հիշեցնեմ, որ առաջադրանքներն ու դերերը միաժամանակ չեն օգտագործվում։
Ansible-ի հիմունքները հասկանալը ողջամիտ պատասխաններ է տալիս ճաշակի թվացող հարցերին:
Առաջադրանքներ և դերեր (մաս երկրորդ)
Հիմա եկեք քննարկենք իրավիճակը, երբ դուք նոր եք սկսում գրել խաղագիրք: Դուք պետք է պատրաստեք ֆու, բար և բազ: Այս երեք առաջադրանքները մե՞կ դեր են, թե՞ երեք դեր: Ամփոփելու համար հարցը՝ ո՞ր պահից պետք է սկսել դերեր գրել: Ի՞նչ իմաստ ունի դերեր գրելը, երբ կարող ես առաջադրանքներ գրել... Ի՞նչ է դերը:
Ամենամեծ սխալներից մեկը (ես արդեն խոսեցի այս մասին) այն է, որ կարծենք, որ դերը նման է ծրագրի գրադարանի ֆունկցիայի: Ինչպիսի՞ն է ընդհանուր ֆունկցիայի նկարագրությունը: Այն ընդունում է մուտքային փաստարկները, փոխազդում է կողմնակի պատճառների հետ, անում է կողմնակի ազդեցությունները և վերադարձնում արժեք:
Հիմա ուշադրություն. Ի՞նչ կարելի է անել սրանից դերում: Դուք միշտ ողջունելի եք անվանել կողմնակի ազդեցություններ, սա ամբողջ Ansible-ի էությունն է՝ ստեղծել կողմնակի ազդեցություններ: Ունե՞ք կողմնակի պատճառներ: Տարրական. Բայց «փոխանցեք արժեքը և վերադարձրեք այն» - այստեղ այն չի աշխատում: Նախ, դուք չեք կարող արժեք փոխանցել դերին: Դուք կարող եք սահմանել գլոբալ փոփոխական՝ խաղալու ողջ կյանքի չափով, vars բաժնում դերի համար: Դուք կարող եք սահմանել գլոբալ փոփոխական՝ դերի ներսում ողջ կյանքի ընթացքում: Կամ նույնիսկ խաղային գրքերի կյանքի ընթացքում (set_fact
/register
) Բայց դուք չեք կարող ունենալ «տեղական փոփոխականներ»: Չի կարելի «արժեք վերցնել» ու «վերադարձնել»։
Սրանից բխում է հիմնականը՝ Ansible-ում չես կարող ինչ-որ բան գրել առանց կողմնակի բարդություններ առաջացնելու։ Գլոբալ փոփոխականների փոփոխությունը միշտ կողմնակի ազդեցություն է ֆունկցիայի համար: Rust-ում, օրինակ, գլոբալ փոփոխական փոխելն է unsafe
. Իսկ Ansible-ում դա դերի արժեքների վրա ազդելու միակ մեթոդն է: Ուշադրություն դարձրեք օգտագործված բառերին. ոչ թե «մի արժեք փոխանցեք դերին», այլ «փոխեք այն արժեքները, որոնք օգտագործում է դերը»: Դերերի միջև մեկուսացում չկա. Չկա մեկուսացում առաջադրանքների և դերերի միջև:
Ընդամենը: դերը ֆունկցիա չէ.
Ի՞նչն է լավ դերի մեջ: Նախ, դերն ունի լռելյայն արժեքներ (/default/main.yaml
), երկրորդը, դերն ունի լրացուցիչ տեղեկատու ֆայլեր պահելու համար:
Որո՞նք են լռելյայն արժեքների առավելությունները: Քանի որ Մասլոուի բուրգում, Ansible-ի փոփոխական առաջնահերթությունների բավականին խեղաթյուրված աղյուսակում, դերերի լռելյայններն ամենից ցածր առաջնահերթությունն են (հանած Ansible հրամանի տողի պարամետրերը): Սա նշանակում է, որ եթե դուք պետք է տրամադրեք լռելյայն արժեքներ և չանհանգստանաք, որ դրանք գերակայում են գույքագրման կամ խմբի փոփոխականների արժեքները, ապա դերերի լռելյայնները միակ ճիշտ տեղն են ձեզ համար: (Ես մի փոքր ստում եմ. կան ավելին |d(your_default_here)
, բայց եթե խոսենք անշարժ վայրերի մասին, ապա միայն դերերի լռելյայն):
Էլ ի՞նչն է հիանալի դերերի մեջ: Քանի որ նրանք ունեն իրենց սեփական կատալոգները: Սրանք դիրեկտորիաներ են փոփոխականների համար՝ և՛ հաստատուն (այսինքն՝ հաշվարկված դերի համար), և՛ դինամիկ (կա կամ օրինաչափություն կամ հակաօրինաչափություն. include_vars
հետ {{ ansible_distribution }}-{{ ansible_distribution_major_version }}.yml
.). Սրանք դիրեկտորիաներ են files/
, templates/
. Նաև այն թույլ է տալիս ունենալ ձեր սեփական մոդուլներն ու պլագինները (library/
) Բայց, համեմատած խաղային գրքույկի առաջադրանքների հետ (որը կարող է նաև ունենալ այս ամենը), այստեղ միակ առավելությունն այն է, որ ֆայլերը թափվում են ոչ թե մեկ կույտի, այլ մի քանի առանձին կույտերի մեջ:
Եվս մեկ մանրամասն. կարող եք փորձել ստեղծել դերեր, որոնք հասանելի կլինեն կրկնակի օգտագործման համար (գալակտիկայի միջոցով): Հավաքածուների գալուստով, դերերի բաշխումը կարելի է համարել գրեթե մոռացված:
Այսպիսով, դերերն ունեն երկու կարևոր առանձնահատկություն. դրանք ունեն լռելյայն (եզակի հատկանիշ) և թույլ են տալիս կառուցվածքը կազմել ձեր կոդը:
Վերադառնալով սկզբնական հարցին՝ ե՞րբ կատարել առաջադրանքներ և ե՞րբ կատարել դերեր: Խաղատախտակի առաջադրանքները առավել հաճախ օգտագործվում են կամ որպես «սոսինձ» դերերից առաջ/հետո, կամ որպես անկախ շինարարական տարր (այդ դեպքում կոդում դերեր չպետք է լինեն): Դերերի հետ խառնված նորմալ առաջադրանքների կույտը միանշանակ անփութություն է: Դուք պետք է հավատարիմ մնաք կոնկրետ ոճին՝ կա՛մ առաջադրանք, կա՛մ դեր: Դերերն ապահովում են սուբյեկտների և լռելյայն տարանջատում, առաջադրանքները թույլ են տալիս ավելի արագ կարդալ կոդը: Սովորաբար ավելի «ստացիոնար» (կարևոր և բարդ) ծածկագիրը դրվում է դերերի մեջ, և օժանդակ սցենարները գրվում են առաջադրանքի ոճով:
Կարելի է import_role-ը կատարել որպես առաջադրանք, բայց եթե գրում եք սա, ապա պատրաստ եղեք բացատրել ձեր գեղեցկության զգացողությանը, թե ինչու եք ուզում դա անել:
Խորամիտ ընթերցողը կարող է ասել, որ դերերը կարող են ներմուծել դերեր, դերերը կարող են կախվածություն ունենալ galaxy.yml-ի միջոցով, և կա նաև սարսափելի և սարսափելի include_role
— Հիշեցնում եմ, որ մենք կատարելագործում ենք հիմնական Ansible-ի հմտությունները, այլ ոչ թե գեղարվեստական մարմնամարզության:
Գործողներ և առաջադրանքներ
Քննարկենք մեկ այլ ակնհայտ բան՝ կարգավորիչներ: Իմանալը, թե ինչպես դրանք ճիշտ օգտագործել, գրեթե արվեստ է: Ո՞րն է տարբերությունը կարգավորիչի և քաշելու միջև:
Քանի որ մենք հիշում ենք հիմունքները, ահա մի օրինակ.
- hosts: group1
tasks:
- foo:
notify: handler1
handlers:
- name: handler1
bar:
Դերի մշակիչները գտնվում են rolename/handlers/main.yaml-ում: Հանդիսավորները պտտվում են խաղի բոլոր մասնակիցների միջև. pre/post_tasks-ը կարող է դուրս բերել դերերի մշակողներին, իսկ դերը կարող է հանել զբաղվողներին խաղից: Այնուամենայնիվ, մշակողներին ուղղված «խաչ դերային» զանգերը շատ ավելի մեծ վտանգ են առաջացնում, քան չնչին կարգավորիչի կրկնությունը: (Լավագույն փորձի մեկ այլ տարր է փորձել չկրկնել մշակողների անունները):
Հիմնական տարբերությունն այն է, որ առաջադրանքը միշտ կատարվում է (անհզոր) (գումարած/մինուս պիտակներ և when
), իսկ կառավարիչը՝ ըստ վիճակի փոփոխության (հրդեհների մասին տեղեկացնել միայն այն դեպքում, եթե այն փոխվել է): Ինչ է սա նշանակում? Օրինակ, այն, որ երբ դուք վերագործարկեք, եթե փոփոխություն չի եղել, ապա չի լինի կարգավորող: Ինչու՞ կարող է լինել, որ մենք պետք է գործարկենք կարգավորիչը, երբ գեներացնող առաջադրանքում փոփոխություն չկար: Օրինակ, քանի որ ինչ-որ բան կոտրվեց և փոխվեց, բայց կատարումը չհասավ կառավարողին: Օրինակ, քանի որ ցանցը ժամանակավորապես անջատված էր: Կազմաձևը փոխվել է, ծառայությունը չի վերագործարկվել: Հաջորդ անգամ, երբ այն սկսեք, կազմաձևն այլևս չի փոխվում, և ծառայությունը մնում է կազմաձևի հին տարբերակով:
Կազմաձևի հետ կապված իրավիճակը չի կարող լուծվել (ավելի ճիշտ, դուք կարող եք ձեզ համար հատուկ վերագործարկման արձանագրություն հորինել ֆայլերի դրոշներով և այլն, բայց սա այլևս «հիմնական անիմաստ» չէ որևէ ձևով): Բայց կա ևս մեկ ընդհանուր պատմություն՝ մենք տեղադրեցինք հավելվածը, ձայնագրեցինք .service
-ֆայլ, և հիմա մենք դա ենք ուզում daemon_reload
и state=started
. Եվ դրա բնական տեղը, կարծես, տնօրինողն է: Բայց եթե դուք այն դարձնեք ոչ թե մշակող, այլ առաջադրանք առաջադրանքների ցանկի կամ դերի վերջում, ապա այն ամեն անգամ անզոր կերպով կկատարվի: Թեկուզ խաղատախտակը մեջտեղից կոտրվեր։ Սա բացարձակապես չի լուծում վերագործարկված խնդիրը (վերագործարկված հատկանիշով առաջադրանք չեք կարող կատարել, քանի որ անզորությունը կորել է), բայց հաստատ արժե անել state=started, playbooks-ի ընդհանուր կայունությունը մեծանում է, քանի որ միացումների քանակը և դինամիկ վիճակը նվազում է:
Բեռնարկիչի մեկ այլ դրական հատկություն այն է, որ այն չի խցանում ելքը: Փոփոխություններ չեղան. ավելորդ բաց թողնված կամ լավ արդյունք չկա, ավելի հեշտ է կարդալ: Դա նաև բացասական հատկություն է. եթե դուք տառասխալ եք գտնում գծային կերպով կատարված առաջադրանքում հենց առաջին իսկ գործարկման ժամանակ, ապա մշակողները կկատարվեն միայն այն դեպքում, երբ փոխվեն, այսինքն. որոշ պայմաններում - շատ հազվադեպ: Օրինակ՝ կյանքումս առաջին անգամ հինգ տարի անց։ Եվ, իհարկե, անվանման մեջ տառասխալ կլինի ու ամեն ինչ կկոտրվի։ Եվ եթե դրանք երկրորդ անգամ չգործարկեք, փոփոխություն չկա:
Առանձին-առանձին, մենք պետք է խոսենք փոփոխականների առկայության մասին: Օրինակ, եթե դուք ծանուցում եք առաջադրանքի մասին հանգույցով, ի՞նչ կլինեն փոփոխականներում: Դուք կարող եք վերլուծական կերպով գուշակել, բայց դա միշտ չէ, որ աննշան է, հատկապես, եթե փոփոխականները գալիս են տարբեր վայրերից:
... Այսպիսով, մշակողները շատ ավելի քիչ օգտակար և շատ ավելի խնդրահարույց են, քան թվում է: Եթե դուք կարող եք ինչ-որ բան գեղեցիկ գրել (առանց ծալքերի) առանց կարգավորիչների, ավելի լավ է դա անել առանց նրանց: Եթե դա գեղեցիկ չի ստացվում, ավելի լավ է նրանց հետ:
Քայքայիչ ընթերցողը իրավացիորեն նշում է, որ մենք չենք քննարկել listen
որ մշակողը կարող է զանգահարել ծանուցում մեկ այլ մշակողի համար, որ մշակողը կարող է ներառել import_tasks (որոնք կարող են ներառել_role with_items-ի հետ), որ Ansible-ի մշակման համակարգը Turing-complete է, որ կարգավորիչները ներառում են_role-ից հետաքրքիր կերպով հատվում են խաղի մշակողների հետ, և այլն: դ. - այս ամենը ակնհայտորեն «հիմունքները» չեն):
Թեև կա մեկ հատուկ WTF, որն իրականում հատկանիշ է, որը դուք պետք է հիշեք: Եթե ձեր առաջադրանքը կատարվում է delegate_to
և այն ծանուցել է, այնուհետև համապատասխան մշակողը գործարկվում է առանց delegate_to
, այսինքն. հաղորդավարի վրա, որտեղ խաղը նշանակված է: (Չնայած կառավարիչը, իհարկե, կարող է ունենալ delegate_to
Նույնը):
Առանձին-առանձին ուզում եմ մի քանի խոսք ասել բազմակի օգտագործման դերերի մասին։ Մինչ հավաքածուների հայտնվելը, կար մի գաղափար, որ դուք կարող եք ստեղծել ունիվերսալ դերեր, որոնք կարող են լինել ansible-galaxy install
ու գնաց։ Աշխատում է բոլոր տարբերակների բոլոր ՕՀ-երի վրա՝ բոլոր իրավիճակներում: Այնպես որ, իմ կարծիքն է՝ չի ստացվում։ Զանգվածի հետ ցանկացած դեր include_vars
, աջակցելով 100500 գործին, դատապարտված է անկյունային գործի սխալների անդունդին: Դրանք կարող են ծածկվել զանգվածային փորձարկումներով, բայց ինչպես ցանկացած փորձարկման դեպքում, կա՛մ դուք ունեք մուտքային արժեքների դեկարտյան արտադրյալ և ընդհանուր գործառույթ, կա՛մ ունեք «անհատական սցենարներ»: Իմ կարծիքն այն է, որ շատ ավելի լավ է, եթե դերը գծային է (ցիկլոմատիկ բարդություն 1):
Ավելի քիչ եթեներ (բացահայտ կամ հռչակագրային՝ ձևով when
կամ ձև include_vars
ըստ փոփոխականների խմբի), այնքան ավելի լավ է դերը: Երբեմն պետք է ճյուղեր պատրաստել, բայց, կրկնում եմ, ինչքան քիչ լինեն, այնքան լավ։ Այսպիսով, թվում է, թե գալակտիկայի հետ լավ դեր է (այն աշխատում է) մի փունջով when
հինգ առաջադրանքներից կարող է ավելի քիչ նախընտրելի լինել, քան «սեփական» դերը: Այն պահը, երբ դերը գալակտիկայի հետ ավելի լավ է, այն է, երբ սկսում ես ինչ-որ բան գրել: Այն պահը, երբ վատանում է, այն է, երբ ինչ-որ բան կոտրվում է, և քեզ մոտ կասկած է առաջանում, որ դա «գալակտիկայի հետ ունեցած դերի» պատճառով է: Դուք բացում եք այն, և կան հինգ ներդիրներ, ութ առաջադրանքների թերթիկներ և մի կույտ when
«օվ... Եվ մենք պետք է դա պարզենք: 5 առաջադրանքների փոխարեն գծային ցուցակ, որում կոտրելու բան չկա։
Հետևյալ մասերում
- Մի փոքր գույքագրման, խմբային փոփոխականների, host_group_vars հավելվածի, hostvars-ի մասին: Ինչպես կապել գորդյան հանգույցը սպագետտիով. Շրջանակի և գերակայության փոփոխականներ, Ansible հիշողության մոդել: «Ուրեմն որտեղ ենք մենք պահում տվյալների բազայի օգտվողի անունը»:
jinja: {{ jinja }}
— nosql notype nosense փափուկ պլաստիլին։ Այն ամենուր է, նույնիսկ այնտեղ, որտեղ չես սպասում: Մի քիչ մասին!!unsafe
և համեղ յամլ:
Source: www.habr.com