
Kjo është një shpjegim në :
Duke filluar nga komiti i dytë, çdo kod bëhet legjendë, sepse ide të fillimit fillojnë të ndryshojnë nga realiteti i ashpër. Kjo nuk është e mirë dhe as e keqe, është një realitet me të cilin është e vështirë të debatohet dhe i cili duhet pranuar. Një pjesë e këtij procesi është refaktorizimi. Refaktorizimi i Infrastructure as Code. Le të fillojë historia se si të refaktorizosh Ansible për një vit pa rënë nga binarët.
Lindja e Legjendës
Dita â 1: Pacienti Zero

Ishte një projekt i kushtëzuar. Kishte një ekip zhvillimi Dev dhe inxhinierë Ops. Ata zgjidhnin të njëjtën detyrë: si të hapnin serverat dhe të lansonin aplikacionin. Problemi ishte se secila ekip zgjidhte këtë detyrë sipas mënyrës së saj. Në projekt u mor vendim të përdorej Ansible për të sinkronizuar informacionin mes ekipeve Dev dhe Ops.
Dita â 89: Lindja e LegjendĂ«s

Pa e kuptuar, donin të bënin sa më mirë, por rezultoi legjendë. Si ndodhi këtu?
- Kemi njĂ« detyrĂ« urgjente kĂ«tu, do tĂ« bĂ«jmĂ« njĂ« hack tĂ« papĂ«rpunuar â mĂ« pas do ta rregullojmĂ«.
- Dokumentacioni mund të mos shkruhet, është e qartë se çfarë po ndodh këtu.
- Unë e di Ansible / Python / Bash / Terraform! Shikoni si mund të spordohem!
- Un Full Stack Overflow Developer e kam kopjuar këtë nga stackoverflow, nuk di si funksionon, por duket mirë dhe zgjidh problemat.
Si rezultat, mund të merrni një kod me pamje të çuditshme, për të cilin nuk ka dokumentacion, nuk është e qartë se çfarë bën, a është i nevojshëm, por problemi është se duhet ta zhvilloni, ta përmirësoni, të shtoni mbështetje, duke e bërë situatën vetëm edhe më të keqe.
- hosts: localhost
tasks:
- shell: echo -n Z >> a.txt && cat a.txt
register: output
delay: 1
retries: 5
until: not output.stdout.find("ZZZ")Dita â 109: Ndjenja e problemit

Modeli i menduar dhe i realizuar fillimisht i IaC ndalon së përmbushuri realitetin me kërkesat e përdoruesve / biznesit / ekipeve të tjera, koha për të bërë ndryshime në infrastrukturë ndalon së qenë e pranueshme. Në këtë moment, vjen kuptimi se është koha për të ndërmarrë masa.
Refaktorimi i IaC
Dita â 139: A Ă«shtĂ« vĂ«rtet e nevojshme refaktorimi pĂ«r ju?

Para se të filloni të refaktoroni, duhet të përgjigjeni në disa pyetje të rëndësishme:
- Pse ju nevojitet gjithçka kjo?
- Keni kohë?
- A keni njohuri të mjaftueshme?
Nëse nuk e dini si të përgjigjeni në këto pyetje, atëherë refaktorimi do të përfundojë pa filluar ose mund të rezultojë vetëm më keq. Sepse ka pasur përvojë( ), atëherë projekti kërkoi ndihmë për të korrigjuar rolet dhe për t'i mbuluar ato me teste.
Dita â 149: PĂ«rgatitja pĂ«r refaktorim

E para është që duhet të përgatitemi. Të vendosim se çfarë do të bëjmë. Për këtë, komunikojmë, gjejmë pikat problematike dhe mendojmë për rrugët e zgjidhjes. Konceptet e marra i regjistrojmë ndonjëherë, për shembull në një artikull në confluence, në mënyrë që kur të dalë pyetja "çfarë është më mirë?" ose "si është më e saktë?" të mos dalim nga kursi. Në rastin tonë, kemi ndjekur idenë përça dhe sundo: e coptojmë infrastrukturën në copa të vogla / tulla. Ky qasje na lejon të marrim një copë të izoluar të infrastrukturës, të kuptojmë se çfarë bën, ta mbulojmë me teste dhe ta ndryshojmë pa pasur frikë se do të prishim diçka.

Kështu, testimi i infrastrukturës bëhet thelbësor dhe këtu duhet përmendur piramida e testimit të infrastrukturës. E njëjta ide si në zhvillim, por për infrastrukturën: kalojmë nga testet e lira dhe të shpejta që kontrollojnë gjëra të thjeshta, për shembull distancat, në teste të shtrenjta që zgjerojnë një infrastrukturë të tërë.
Përpjekjet për testimin e Ansible
Para se të shkojmë për të përshkruar se si e mbulonim testimin e Ansible në projekt, do të përshkruaj përpjekjet dhe qasjet që kishim përdorur më parë, për të kuptuar kontekstin e vendimeve të marra.
Dita â -997: Prodhimi i SDS

Herën e parë që kam testuar Ansible ishte në një projekt për zhvillimin e SDS (Storage i Definuar nga Softueri). Ka një artikull të veçantë mbi këtë temë.
, por nëse e shpreh shkurt, kemi pasur një piramidë të përmbysur testimi dhe testimi zgjaste 60-90 minuta për një rol, që është shumë. Baza ishin testet e e2e, dmth. ne shpërndanim një instalim të plotë dhe pastaj e testonim atë. Një tjetër vështirësi ishte shpikja e biçikletës sonë. Por duhet pranuar se kjo zgjidhje funksiononte dhe na lejonte të lëshonim versionet në mënyrë të qëndrueshme.
Dita â -701: Ansible dhe test kitchen

Zhvillimi i idesë së testimit të Ansible u bë përdorimi i mjeteve të gatshme, konkretisht test kitchen / kitchen-ci dhe inspec. Zgjedhja u bazua në njohuritë për Ruby (më shumë në artikullin në Habr: ) punoi më shpejt për rreth 40 minuta për 10 role. Krijuam një grup makinash virtuale dhe brenda tyre ekzekutuam teste.

Në përgjithësi, zgjidhja funksionoi, por kishte një ndjenjë të shpejtë për shkak të heterogjenitetit. Kur rritëm numrin e testeve në 13 role bazë dhe 2 meta-role që kombinonin role më të vogla, testet papritmas u zgjatën në 70 minuta, e cila është pothuajse dyfishi i kohës. Kishim vështirësi të flisnim për praktikat e XP (programimit ekstrem) pasi askush nuk do të donte të priste 70 minuta. Kjo ishte një arsyetim për të ndryshuar qasjen.
Dita â -601: Ansible dhe molecule

Konceptualisht, është e ngjashme me testkitchen, vetëm se ne e transferuam testimin e roleve në docker dhe ndryshuam stek. Si rezultat, koha u reduktua në 20-25 minuta të stabilizuara për 7 role.

Duke rritur numrin e roleve të testuara në 17 dhe linjën e 45 roleve, ne e realizuam këtë brenda 28 minutash në 2 slave të Jenkins.
Dita â 167: ShtojmĂ« teste Ansible nĂ« projekt

Për një përpjekje e shpejtë, ka shumë të ngjarë që të refaktoroni detyrën. Detyra duhet të jetë e matshme, në mënyrë që ta ndani atë në copëza të vogla dhe ta hani elefantin me lugë. Duhet të keni një kuptim nëse po lëvizni në drejtimin e duhur dhe sa kohë duhet të ecni.

NĂ« pĂ«rgjithĂ«si, nuk ka rĂ«ndĂ«si se si do tĂ« bĂ«het, mund tĂ« shkruhet nĂ« njĂ« letĂ«r, mund tĂ« vendosen stikera nĂ« dollap, mund tĂ« krijohen detyra nĂ« Jira, ose mund tĂ« hapen dokumente Google dhe tĂ« shkruhet aty statusi aktual. Problemi Ă«shtĂ« se procesi nuk Ă«shtĂ« njĂ« moment; do tĂ« jetĂ« i gjatĂ« dhe i lodhshĂ«m. ĂshtĂ« pak e mundshme qĂ« dikush tĂ« dĂ«shirojĂ« qĂ« gjatĂ« kohĂ«s sĂ« ristrukturimit tĂ« humbasĂ« interes dhe tĂ« lodhet.
Ristrukturimi është i thjeshtë:
- Hani.
- Flini.
- Programoni.
- Testi IaC.
- Përsëritni.
dhe kështu përsërisim derisa të arrijmë qëllimin e caktuar.

Nuk do të jetë e mundur të testoni gjithçka menjëherë, prandaj detyra jonë e parë ishte të fillonim me lintimin dhe kontrollin e sintaksës.
Dita â 181: Green Build Master

Lintimi është një hap i vogël drejt Green Build Master. Një gjë e tillë nuk do të dëmtojë shumë, por do të lejojë që proceset të përshtaten dhe të krijohen build-e të gjelbra në Jenkins. Ideja është të formohen zakone te ekipi:
- Testet e kuqe janë të këqija.
- Kur arrini për të korrigjuar diçka, bëjeni kodin pak më të mirë se sa ishte përpara.
Dita â 193: Nga lintimi nĂ« testet unitare.

Duke organizuar procesin e kalimit tĂ« kodit nĂ« master, mund tĂ« filloni procesin e pĂ«rmirĂ«simit tĂ« hap pas hapi â duke zĂ«vendĂ«suar linfimin me ekzekutimin e rolĂ«ve, madje edhe pa idempotencĂ«. ĂshtĂ« e nevojshme tĂ« kuptohet se si tĂ« aplikohen rollet, si funksionojnĂ« ato.
Dita â 211: Nga testet unit nĂ« testet e integrimit

Kur testet unit mbulojnë shumicën e rolëve dhe gjithçka është e linfuar, mund të kaloni në shtimin e testeve të integrimit. Kjo nënkupton testimin e një kombinimi të komponentëve në infrastrukture, për shembull një konfigurim të plotë të një instancë.

Në Jenkins, ne gjeneronim shumë etapa, të cilat paralelisht linfonin rolët/plementet, pastaj testet unit në kontejnerë dhe në fund testet e integrimit.
Jenkins + Docker + Ansible = Testet

- Kontrolloni repo dhe gjeneroni etapat e ndërtimit.
- Ekzekutoni etapat e linfimit të plëybokëve në paralel.
- Ekzekutoni etapat e linfimit të rolëve në paralel.
- Ekzekutoni etapat e kontrollit të sintaksës të rolëve në paralel.
- Ekzekutoni etapat e testeve të rolëve në paralel.
- Linfoni rol.
- Kontrolloni varësinë nga rollet e tjera.
- Kontrolloni sintaksën.
- Krijoni instancë docker
- Ekzekutoni molecule/default/playbook.yml.
- Kontrolloni idempotencën.
- Ekzekutoni testet e integrimit
- Përfundimi
Dita â 271: Bus Factor

Në fillim, një grup i vogël prej disa personash merrej me ristrukturimin. Ata bënin rishikimin e kodit në master. Me kalimin e kohës, ekipi zhvilloi njohuri mbi kodin, dhe rishikimi i kodit ndihmoi në përhapjen e njohurive mbi infrastrukturën dhe si funksionon ajo. E veçanta këtu ishte se rishikuesit zgjidheshin me radhë, sipas një grafiku, pra, me një probabilitet të caktuar mund të jepesh në një pjesë të re të infrastrukturës.

Dhe këtu duhet të jetë e përshtatshme. E përshtatshme për të bërë rishikime, për të parë për çfarë detyre është bërë, historinë e diskutimeve. Ne integrova jenkins + bitbucket + jira.
Por rishikimi si një e tillë nuk është një panacë, ndodhi që në master kaloi një kod që na solli teste të paqëndrueshme:
- get_url:
url: "{{ actk_certs }}/{{ item.1 }}"
dest: "{{ actk_src_tmp }}/"
username: "{{ actk_mvn_user }}"
password: "{{ actk_mvn_pass }}"
with_subelements:
- "{{ actk_cert_list }}"
- "{{ actk_certs }}"
delegate_to: localhost
- copy:
src: "{{ actk_src_tmp }}/{{ item.1 }}"
dest: "{{ actk_dst_tmp }}"
with_subelements:
- "{{ actk_cert_list }}"
- "{{ actk_certs }}"Më pas, e korrigovuam këtë, por mbeti një shije e keqe.
get_url:
url: "{{ actk_certs }}\/{{ actk_item }}"
dest: "{{ actk_src_tmp }}\/{{ actk_item }}"
username: "{{ actk_mvn_user }}"
password: "{{ actk_mvn_pass }}"
loop_control:
loop_var: actk_item
with_items: "{{ actk_cert_list }}"
delegate_to: localhost
- copy:
src: "{{ actk_src_tmp }}\/{{ actk_item }}"
dest: "{{ actk_dst_tmp }}"
loop_control:
loop_var: actk_item
with_items: "{{ actk_cert_list }}"Dita â 311: Shpejtoni provimet

Me rritjen e testeve, ndërtimet ishin ngadalësuar, duke zgjatur deri në një orë në rastin më të keq. Në një nga retrospektivat kishte një frazë si "mirë që kemi teste, por ato janë të ngadalta". Në përfundim, heqëm testet integruese në makinat virtuelle dhe i përshtatëm për docker, për ta bërë më të shpejtë. Po ashtu zëvendësuam testinfra me ansible verifier për të zvogëluar numrin e veglave të përdorura.

Saktësisht, këtu kishte një kompleks masash:
- Kalimi në docker.
- Heqja e testimit të roleve, që dyfishohet për shkak të varësive.
- Rritja e numrit të slave-ve.
- Rendi i ekzekutimit të testeve.
- Mundësia për të krijuar lintim Tà GJITHA lokalisht me një komandë.

Në përfundim, Pipeline në jenkins gjithashtu u unifikua
- Gjeneroni fazat e ndërtimit.
- Lint gjithçka në paralel.
- Ekzekutoni etapat e testeve të rolëve në paralel.
- K заĐČĐ”ŃŃаŃ.
Mësimet e nxjerra
Shmangni variablat globale
Ansible përdor variabla globale, ka një workaround të pjesshëm në formën e , por kjo nuk është një zgjidhje e plotë.
Dua të jap një shembull. Le të themi se kemi role_a dhe role_b
# cat role_a/defaults/main.yml
---
msg: a
# cat role_a/tasks/main.yml
---
- debug:
msg: role_a={{ msg }}# cat role_b/defaults/main.yml
---
msg: b
# cat role_b/tasks/main.yml
---
- set_fact:
msg: b
- debug:
msg: role_b={{ msg }}- hosts: localhost
vars:
msg: hello
roles:
- role: role_a
- role: role_b
tasks:
- debug:
msg: play={{msg}}
Një gjë e çuditshme është se rezultati i ekzekutimit të playbook-ëve do të varet nga gjëra që nuk janë gjithmonë të qarta, si për shembull renditja e roleve. Fatkeqësisht, kjo është natyra e Ansible dhe gjëja më e mirë që mund të bëni është të përdorni disa marrëveshje, për shembull, brenda rolit të përdorni vetëm variablat e përshkruara në këtë rol.
KEQ: përdorni një variabël globale.
# cat roles/some_role/tasks/main.yml
---
debug:
var: java_homeBENE: Në defaults përcaktoni variablën e nevojshme dhe më pas përdorni vetëm ato.
# cat roles/some_role/defaults/main.yml
---
r__java_home:
"{{ java_home | default('/path') }}"
# cat roles/some_role/tasks/main.yml
---
debug:
var: r__java_home
Variablat e rolit me prefiks
KEQ: përdorni një variabël globale.
# cat roles/some_role/defaults/main.yml
---
db_port: 5432BENE: Në rol për variablat, përdorni variablat me prefiksin e emrit të rolit, që do ta lehtësojë kuptimin e asaj që po ndodh kur shikoni inventarin.
# cat roles/some_role/defaults/main.yml
---
some_role__db_port: 5432Përdorni variablin e kontrollit të ciklit
KEQ: Përdorni në cikle variablin standard item, nëse ky detyrë/playbook do të përfshihet diku, mund të çojë në sjellje të paparashikueshme
---
- hosts: localhost
tasks:
- debug:
msg: "{{ item }}"
loop:
- item1
- item2
BENE: Rishkruani variablin në cikël përmes loop_var.
---
- hosts: localhost
tasks:
- debug:
msg: "{{ item_name }}"
loop:
- item1
- item2
loop_control:
loop_var: item_name
Kontrolloni variablat e inputit
Kemi dakorduar të përdorim prefikset e variablave, nuk do të ishte e tepërt të kontrollonim nëse ato janë të përcaktuara siç e presim dhe, për shembull, nuk janë mbuluar nga një vlerë e zbrazët.
BENE: Kontrolloni variablat.
- name: "Verifikoni që variablat e nevojshme të tipit string janë të përcaktuara"
assert:
that: ahs_var is defined and ahs_var | length > 0 and ahs_var != None
fail_msg: "{{ ahs_var }} duhet të vendoset për rolin të funksionojë "
success_msg: "Variablat e nevojshme {{ ahs_var }} janë të përcaktuara"
loop_control:
loop_var: ahs_var
with_items:
- ahs_item1
- ahs_item2
- ahs_item3Shmangni fjalorët hash, përdorni strukturë të thjeshtë.
Nëse roli pret një hash/fjalor në njërin nga parametrat, atëherë nëse dëshirojmë të korrigjojmë njërin nga parametrat fëmijë, na nevojitet të ripërcaktojmë të gjithë hash/fjalorin, që do të rrisë kompleksitetin e konfigurimit.
KEQ: Përdorni hash/fjalor.
---
user:
name: admin
group: adminBENE: Përdorni strukturën e thjeshtë të variablave.
---
user_name: admin
user_group: "{{ user_name }}"Krijoni playbooks & role idempotente.
Rolat dhe playbook-at duhet të jenë idempotente, pasi kjo zvogëlon drift-in e konfigurimit dhe frikën për të thyer diçka. Por nëse përdorni molecule, atëherë kjo sjellje është e paracaktuar.
Shmangni përdorimin e moduleve të shell.
Përdorimi i modulit shell çon në një paradigëm imperativ të përshkrimit, në vend të një paradigme deklarative, e cila është thelbësore për Ansible.
Testoni rolat tuaja përmes molecule.
Molecule është një mjet tepër fleksibël, le të shqyrtojmë disa skenarë.
Molecule Shumë instance
Në molecule.yml në seksionin platformat mund të përshkruajë shumë host-e që do të vendosen.
---
driver:
name: docker
platforms:
- name: postgresql-instance
hostname: postgresql-instance
image: registry.example.com/postgres10:latest
pre_build_image: true
override_command: false
network_mode: host
- name: app-instance
hostname: app-instance
pre_build_image: true
image: registry.example.com/docker_centos_ansible_tests
network_mode: hostPër pasojë, këto host-e mund të përdoreshin më vonë në converge.yml për të përdorur:
---
- name: Converge all
hosts: all
vars:
ansible_user: root
roles:
- role: some_role
- name: Converge db
hosts: db-instance
roles:
- role: some_db_role
- name: Converge app
hosts: app-instance
roles:
- role: some_app_roleVerifikues Ansible
Në molecule ka mundësinë të përdorë ansible për të verifikuar se instanca është konfiguruar siç duhet, madje që nga versioni 3 është kjo opcione e parazgjedhur. Nuk është aq fleksibël sa testinfra/inspec, por mund të verifikojë se përmbajtja e skedarit përputhet me pritshmëritë tona:
---
- name: Verify
hosts: all
tasks:
- name: copy config
copy:
src: expected_standalone.conf
dest: /root/wildfly/bin/standalone.conf
mode: "0644"
owner: root
group: root
register: config_copy_result
- name: Certify that standalone.conf changed
assert:
that: not config_copy_result.changedOse të hapni shërbimin, prisni që të jetë në dispozicion dhe bëni testin e vogël:
---
- emri: Verifiko
host-et: solr
detyra:
- komandë: /blah/solr/bin/solr start -s /solr_home -p 8983 -force
- uri:
url: http://127.0.0.1:8983/solr
metoda: GET
status_code: 200
regjistro: uri_result
deri: uri_result është jo dështuar
përpjekje: 12
vonesë: 10
- emri: Posto dokumente në solr
komandë: /blah/solr/bin/post -c master /exampledocs/books.csvVendosni logjikën komplekse në module & plugina
Ansible predikon një qasje deklarative, prandaj kur bëni dega të kodit, transformim të të dhënave, module shell, kodi bëhet i vështirë për t'u lexuar. Për ta luftuar këtë dhe për ta mbajtur të thjeshtë për t'u kuptuar, do të ishte e dobishme të luftoni me këtë kompleksitet duke krijuar modulet tuaja.
Përmbledhni Këshilla & Trikë
- Shmangni variablat globale.
- Prefiksoni variablat e rolit.
- Përdorni variablin e kontrollit të ciklit.
- Kontrolloni variablat e inputit.
- Shmangni hashes dictionaries, përdorni strukturë të sheshtë.
- Krijoni playbooks & role idempotente.
- Shmangni përdorimin e moduleve të komandës shell.
- Testoni rolet tuaja përmes molekulës.
- Vendosni logjikën komplekse në module & plugina.
Përfundimi

Nuk mund të merrni dhe të refaktoroni infrastrukturën në projekt, madje edhe nëse keni IaC. Ky është një proces i gjatë që kërkon durim, kohë dhe njohuri.
Links
- Prezantimet
- Video
UPD1 2020.05.01 20:30 â PĂ«r profilizimin fillestar tĂ« playbook-Ă«ve mund tĂ« pĂ«rdoret callback_whitelist = profile_tasks pĂ«r tĂ« kuptuar se çfarĂ« funksionon ngadalĂ«. Pas kĂ«saj kalojmĂ« te . Mund tĂ« provoni
UPD2 2020.05.03 16:34 â
Burimi: habr.com
