Vanaf de tweede commit wordt elke code verouderd, omdat De oorspronkelijke ideeën beginnen af te wijken van de harde werkelijkheid. Dit is noch goed, noch slecht; het is een gegeven waar moeilijk over te discussiëren valt en waar mee geleefd moet worden. Een deel van dit proces is refactoring. Infrastructuur herstructureren als code. Laat het verhaal beginnen over hoe je Ansible binnen een jaar kunt herstructureren en niet gek wordt.
De geboorte van erfenis
Dag #1: Patiënt nul
Er was eens een voorwaardelijk project. Het had een Dev-ontwikkelteam en Ops-ingenieurs. Ze waren hetzelfde probleem aan het oplossen: hoe je servers moest inzetten en een applicatie moest draaien. Het probleem was dat elk team dit probleem op zijn eigen manier oploste. Bij het project werd besloten om Ansible in te zetten om kennis tussen de Dev- en Ops-teams te synchroniseren.
Dag #89: De geboorte van erfenis
Zonder het zelf te merken wilden ze het zo goed mogelijk doen, maar het bleek erfenis. Hoe gebeurde dit?
We hebben hier een dringende taak, laten we een vuile hack uitvoeren en deze vervolgens repareren.
Je hoeft geen documentatie te schrijven en alles is duidelijk wat hier aan de hand is.
Ik ken Ansible/Python/Bash/Terraform! Kijk hoe ik kan ontwijken!
Ik ben een Full Stack Overflow-ontwikkelaar en heb dit gekopieerd van StackOverflow. Ik weet niet hoe het werkt, maar het ziet er cool uit en lost het probleem op.
Als gevolg hiervan kun je een onbegrijpelijk type code krijgen waarvoor geen documentatie bestaat, het is niet duidelijk wat het doet, of het nodig is, maar het probleem is dat je het moet ontwikkelen, aanpassen, krukken en ondersteuningen moet toevoegen , waardoor de situatie nog erger wordt.
Het aanvankelijk bedachte en geïmplementeerde IaC-model voldoet niet langer aan de eisen van gebruikers/business/andere teams, en de tijd om wijzigingen aan te brengen in de infrastructuur is niet meer acceptabel. Op dit moment komt het besef dat het tijd is om actie te ondernemen.
IaC-refactoring
Dag #139: Heeft u echt refactoring nodig?
Voordat u zich haast tot refactoring, moet u een aantal belangrijke vragen beantwoorden:
Waarom heb je dit allemaal nodig?
Heb je tijd?
Is kennis voldoende?
Als u niet weet hoe u de vragen moet beantwoorden, zal de refactoring eindigen voordat deze zelfs maar is begonnen, of kan het alleen maar erger worden. Omdat ervaring gehad( Wat ik heb geleerd van het testen van 200 regels infrastructuurcode), vervolgens ontving het project een verzoek om hulp om de rollen op te lossen en deze met tests te bedekken.
Dag #149: Voorbereiding van de refactoring
Het eerste is voorbereiding. Bepaal wat we gaan doen. Om dit te doen, communiceren we, vinden we probleemgebieden en bedenken we manieren om ze op te lossen. We leggen de resulterende concepten op de een of andere manier vast, bijvoorbeeld een samenvloeiend artikel, zodat wanneer de vraag rijst “wat is het beste?” of "wat is juist?" Wij zijn de weg niet kwijtgeraakt. In ons geval bleven we bij het idee verdeel en heers: we breken de infrastructuur op in kleine stukjes/stenen. Met deze aanpak kun je een geïsoleerd stukje infrastructuur nemen, begrijpen wat het doet, het bedekken met tests en het veranderen zonder bang te hoeven zijn iets kapot te maken.
Het blijkt dat het testen van infrastructuur de hoeksteen wordt en hier is het de moeite waard om de piramide voor het testen van infrastructuur te noemen. Precies hetzelfde idee dat in ontwikkeling is, maar dan voor infrastructuur: we gaan van goedkope snelle tests die simpele zaken controleren, zoals inspringen, naar dure volwaardige tests die de hele infrastructuur inzetten.
Ansible-testpogingen
Voordat we gaan beschrijven hoe we Ansible-tests in het project hebben behandeld, zal ik de pogingen en benaderingen beschrijven die ik eerder heb kunnen gebruiken om de context van de genomen beslissingen te begrijpen.
Dag nr. -997: SDS-voorziening
De eerste keer dat ik Ansible testte, was tijdens een project om SDS (Software Defined Storage) te ontwikkelen. Er is een apart artikel over dit onderwerp Hoe u fietsen over krukken kunt breken bij het testen van uw distributie, maar kortom, we eindigden met een omgekeerde testpiramide en bij het testen hebben we 60-90 minuten aan één rol besteed, wat lang is. De basis waren e2e-tests, d.w.z. we hebben een volwaardige installatie neergezet en vervolgens getest. Wat nog erger was, was de uitvinding van zijn eigen fiets. Maar ik moet toegeven dat deze oplossing werkte en een stabiele release mogelijk maakte.
Dag # -701: Ansible en testkeuken
De ontwikkeling van het Ansible-testidee was het gebruik van kant-en-klare tools, namelijk testkeuken/keuken-ci en inspec. De keuze werd bepaald door kennis van Ruby (zie voor meer details het artikel over Habré: Dromen YML-programmeurs ervan Ansible te testen?) werkte sneller, ongeveer 40 minuten voor 10 rollen. We hebben een pakket virtuele machines gemaakt en daarbinnen tests uitgevoerd.
Over het algemeen werkte de oplossing, maar er was wat sediment vanwege de heterogeniteit. Toen het aantal geteste mensen werd verhoogd tot 13 basisrollen en 2 metarollen die kleinere rollen combineerden, begonnen de tests plotseling 70 minuten te duren, wat bijna twee keer zo lang is. Het was moeilijk om over XP-praktijken (extreme programming) te praten, omdat... niemand wil 2 minuten wachten. Dit was de reden om de aanpak te veranderen
Dag # -601: Ansible en molecuul
Conceptueel gezien is dit vergelijkbaar met testkitchen, alleen hebben we het testen van rollen naar Docker verplaatst en de stapel gewijzigd. Als gevolg hiervan werd de tijd teruggebracht tot een stabiele 20-25 minuten voor 7 rollen.
Door het aantal geteste rollen te verhogen naar 17 en 45 rollen te linten, hebben we dit in 28 minuten uitgevoerd op 2 Jenkins-slaven.
Dag #167: Ansible-tests toevoegen aan het project
Hoogstwaarschijnlijk zal het niet mogelijk zijn om de refactoring-taak snel uit te voeren. De taak moet meetbaar zijn, zodat je hem in kleine stukjes kunt breken en de olifant stukje voor stukje kunt opeten met een theelepel. Er moet inzicht zijn of u zich in de goede richting beweegt en hoe lang u nog moet gaan.
Over het algemeen maakt het niet uit hoe het gedaan zal worden, je kunt op een vel papier schrijven, je kunt stickers op de kast plakken, je kunt taken aanmaken in Jira, of je kunt Google Docs openen en de huidige status opschrijven. daar. De benen groeien door het feit dat het proces niet onmiddellijk is, het zal lang en vervelend zijn. Het is onwaarschijnlijk dat iemand wil dat je geen ideeën meer hebt, moe wordt en overweldigd raakt tijdens het refactoring.
De refactoring is eenvoudig:
Eten.
Slapen.
Code.
IaC-test.
herhaling
en dit herhalen we totdat we het beoogde doel bereiken.
Het is misschien niet mogelijk om alles meteen te testen, dus onze eerste taak was om te beginnen met het linten en het controleren van de syntaxis.
Dag #181: Groene bouwmeester
Linting is een kleine eerste stap richting Green Build Master. Dit zal vrijwel niets kapot maken, maar het geeft je wel de mogelijkheid om processen te debuggen en groene builds te maken in Jenkins. Het idee is om gewoonten binnen het team te ontwikkelen:
Rode tests zijn slecht.
Ik kwam om iets te repareren en tegelijkertijd de code een beetje beter te maken dan vóór jou.
Dag #193: Van pluisjes tot unit-tests
Nadat u het proces heeft ingebouwd om de code in de master te krijgen, kunt u beginnen met het proces van stapsgewijze verbetering - door linting te vervangen door startrollen, kunt u het zelfs doen zonder idempotentie. U moet begrijpen hoe u rollen moet toepassen en hoe ze werken.
Dag #211: Van unit- naar integratietesten
Wanneer de meeste rollen zijn bedekt met unit-tests en alles in de war is, kunt u doorgaan met het toevoegen van integratietests. Die. het testen van geen enkele baksteen in de infrastructuur, maar een combinatie daarvan, bijvoorbeeld een volledige instanceconfiguratie.
Met behulp van Jenkins hebben we veel fasen gegenereerd waarin rollen/playbooks parallel werden samengevoegd, vervolgens unit-tests in containers en ten slotte integratietests.
Jenkins + Docker + Ansible = Testen
Bekijk de opslagplaats en genereer bouwfasen.
Voer lint-playbook-fasen parallel uit.
Voer lintrolfasen parallel uit.
Voer syntaxiscontrolerolfasen parallel uit.
Voer testrolfasen parallel uit.
Lint rol.
Controleer de afhankelijkheid van andere rollen.
Controleer de syntaxis.
Docker-instantie maken
Voer molecule/default/playbook.yml uit.
Controleer de idempotentie.
Voer integratietests uit
Finish
Dag #271: Busfactor
In eerste instantie werd de refactoring uitgevoerd door een kleine groep van twee of drie personen. Ze hebben de code in de master beoordeeld. In de loop van de tijd ontwikkelde het team kennis over het schrijven van code en codebeoordeling droeg bij aan de verspreiding van kennis over de infrastructuur en hoe deze werkt. Het hoogtepunt hierbij was dat de reviewers één voor één werden geselecteerd, volgens een schema, d.w.z. met een zekere mate van waarschijnlijkheid klim je in een nieuw stuk infrastructuur.
En het moet hier comfortabel zijn. Het is handig om een evaluatie uit te voeren, te zien in het kader van welke taak het is uitgevoerd en de geschiedenis van de discussies. We hebben jenkins + bitbucket + jira geïntegreerd.
Maar als zodanig is een recensie geen wondermiddel; op de een of andere manier kwamen we in de mastercode terecht, waardoor we floptests kregen:
In de loop van de tijd waren er meer tests en verliepen de builds langzamer, in het ergste geval tot een uur. Op een van de retro’s stond een zin als “het is goed dat er tests zijn, maar die zijn traag.” Als gevolg hiervan hebben we de integratietests op virtuele machines stopgezet en deze aangepast zodat Docker deze sneller maakt. We hebben ook testinfra vervangen door een ansible verifier om het aantal gebruikte tools te verminderen.
Strikt genomen was er een reeks maatregelen:
Schakel over naar docker.
Verwijder roltesten, die dubbel worden uitgevoerd vanwege afhankelijkheden.
Verhoog het aantal slaven.
Bestelling proefdraaien.
Vermogen om te pluizen ALLEMAAL lokaal met één commando.
Als gevolg hiervan werd Pipeline op Jenkins ook verenigd
Genereer bouwfasen.
Lint allemaal parallel.
Voer testrolfasen parallel uit.
Finish.
Lessen uit het verleden
Vermijd globale variabelen
Ansible gebruikt globale variabelen, er is een gedeeltelijke oplossing in het formulier private_role_vars, maar dit is geen wondermiddel.
Laat me je een voorbeeld geven. Laat ons hebben role_a и role_b
Het grappige is dat het resultaat van draaiboeken zal afhangen van zaken die niet altijd voor de hand liggen, zoals de volgorde waarin rollen worden vermeld. Helaas is dit de aard van Ansible en het beste wat je kunt doen is een soort overeenkomst gebruiken, bijvoorbeeld om binnen een rol alleen de variabele te gebruiken die in deze rol wordt beschreven.
GOED: Gebruik in rollen voor variabelen variabelen voorafgegaan door de rolnaam; dit, door naar de inventaris te kijken, zal het gemakkelijker maken om te begrijpen wat er gebeurt.
We hebben afgesproken om variabele voorvoegsels te gebruiken; het zou niet overbodig zijn om te controleren of deze zijn gedefinieerd zoals we verwachten en bijvoorbeeld niet zijn overschreven door een lege waarde
GOED: Variabelen controleren.
- name: "Verify that required string variables are defined"
assert:
that: ahs_var is defined and ahs_var | length > 0 and ahs_var != None
fail_msg: "{{ ahs_var }} needs to be set for the role to work "
success_msg: "Required variables {{ ahs_var }} is defined"
loop_control:
loop_var: ahs_var
with_items:
- ahs_item1
- ahs_item2
- ahs_item3
Vermijd hashes-woordenboeken, gebruik een platte structuur
Als een rol een hash/woordenboek in een van zijn parameters verwacht, moeten we, als we een van de onderliggende parameters willen wijzigen, de hele hash/woordenboek overschrijven, wat de configuratiecomplexiteit zal vergroten.
Rollen en draaiboeken moeten idempotent zijn, omdat vermindert configuratiedrift en de angst om iets kapot te maken. Maar als u moleculen gebruikt, is dit het standaardgedrag.
Vermijd het gebruik van opdrachtshellmodules
Het gebruik van een shell-module resulteert in een imperatief beschrijvingsparadigma, in plaats van het declaratieve paradigma, wat de kern is van Ansible.
Test je rollen via molecuul
Moleculen zijn heel flexibel. Laten we eens naar een paar scenario's kijken.
Molecuul Meerdere exemplaren
В molecule.yml in sectie platforms je kunt veel hosts beschrijven die je kunt inzetten.
In molecule is het mogelijk om ansible te gebruiken om te controleren of de instantie correct is geconfigureerd, bovendien is dit de standaard sinds release 3. Het is niet zo flexibel als testinfra/inspec, maar we kunnen wel controleren of de inhoud van het bestand aan onze verwachtingen voldoet:
Of zet de dienst in, wacht tot deze beschikbaar komt en doe een rooktest:
---
- name: Verify
hosts: solr
tasks:
- command: /blah/solr/bin/solr start -s /solr_home -p 8983 -force
- uri:
url: http://127.0.0.1:8983/solr
method: GET
status_code: 200
register: uri_result
until: uri_result is not failed
retries: 12
delay: 10
- name: Post documents to solr
command: /blah/solr/bin/post -c master /exampledocs/books.csv
Zet complexe logica in modules en plug-ins
Ansible pleit voor een declaratieve aanpak, dus als je codevertakkingen, datatransformaties en shell-modules uitvoert, wordt de code moeilijk leesbaar. Om dit tegen te gaan en het eenvoudig te begrijpen te houden, zou het niet overbodig zijn om deze complexiteit te bestrijden door uw eigen modules te maken.
Vat tips en trucs samen
Vermijd globale variabelen.
Geef rolvariabelen een voorvoegsel.
Gebruik luscontrolevariabele.
Controleer invoervariabelen.
Vermijd hashes-woordenboeken, gebruik een platte structuur.
Creëer idempotente draaiboeken en rollen.
Vermijd het gebruik van opdrachtshellmodules.
Test je rollen via molecuul.
Zet complexe logica in modules en plug-ins.
Conclusie
Je kunt niet zomaar de infrastructuur van een project herstructureren, zelfs als je over IaC beschikt. Dit is een lang proces dat geduld, tijd en kennis vereist.
UPD1 2020.05.01 20:30 — Voor primaire profilering van draaiboeken die u kunt gebruiken callback_whitelist = profile_tasks om lange tijd te begrijpen wat precies werkt. Dan gaan wij door Ansible-acceleratieklassiekers. Je kunt het ook proberen mitogeen UPD2 2020.05.03 16:34 - Engels versie