Wat ik heb geleerd van het testen van 200 regels infrastructuurcode

Wat ik heb geleerd van het testen van 200 regels infrastructuurcode

Een aanpak IaC (Infrastructure as Code) bestaat niet alleen uit de code die in de repository is opgeslagen, maar ook uit de mensen en processen die deze code omringen. Is het mogelijk om benaderingen van softwareontwikkeling tot infrastructuurbeheer en -beschrijving te hergebruiken? Het is een goed idee om dit idee in gedachten te houden terwijl u het artikel leest.

Engels versie

Dit is een transcriptie van mijn optredens op DevopsConf 2019-05-28.

Dia's en video's

Infrastructuur als bash-geschiedenis

Wat ik heb geleerd van het testen van 200 regels infrastructuurcode

Stel je voor dat je bij een nieuw project komt en ze zeggen: “dat hebben we gedaan Infrastructuur als code". In werkelijkheid blijkt Infrastructuur als bash-geschiedenis of bijvoorbeeld Documentatie als bash-geschiedenis. Dit is een zeer reële situatie, een soortgelijk geval werd bijvoorbeeld door Denis Lysenko in een toespraak beschreven Hoe je de hele infrastructuur kunt vervangen en lekker kunt gaan slapen, vertelde hij hoe ze uit de geschiedenis van bash een samenhangende infrastructuur voor het project kregen.

Met enig verlangen kunnen we dat zeggen Infrastructuur als bash-geschiedenis dit is als code:

  1. reproduceerbaarheid: Je kunt de bash-geschiedenis nemen, de opdrachten vanaf daar uitvoeren, en je zou trouwens een werkende configuratie als uitvoer kunnen krijgen.
  2. versiebeheer: je weet wie er binnenkwamen en wat ze deden, nogmaals, het is geen feit dat dit je naar een werkende configuratie bij de uitgang zal leiden.
  3. история: het verhaal van wie wat deed. alleen kunt u het niet gebruiken als u de server kwijtraakt.

Wat te doen?

Infrastructuur als code

Wat ik heb geleerd van het testen van 200 regels infrastructuurcode

Zelfs zo'n vreemd geval als Infrastructuur als bash-geschiedenis je kunt hem bij de oren trekken Infrastructuur als code, maar als we iets ingewikkelders willen doen dan de goede oude LAMP-server, zullen we tot de conclusie komen dat deze code op de een of andere manier moet worden aangepast, veranderd, verbeterd. Vervolgens willen we de parallellen tussen beide bekijken Infrastructuur als code en softwareontwikkeling.

DROOG.

Wat ik heb geleerd van het testen van 200 regels infrastructuurcode

Bij een ontwikkelingsproject voor opslagsystemen was er een subtaak configureer periodiek SDS: we brengen een nieuwe release uit - deze moet worden uitgerold voor verder testen. De taak is uiterst eenvoudig:

  • log hier in via ssh en voer het commando uit.
  • kopieer het bestand daarheen.
  • corrigeer de configuratie hier.
  • start daar de dienst
  • ...
  • WINST!

Voor de beschreven logica is bash meer dan genoeg, vooral in de vroege stadia van het project, wanneer het nog maar net begint. Dit het is niet slecht dat je bash gebruikt, maar na verloop van tijd zijn er verzoeken om iets soortgelijks, maar iets anders, in te zetten. Het eerste dat in je opkomt is kopiëren en plakken. En nu hebben we al twee zeer vergelijkbare scripts die bijna hetzelfde doen. In de loop van de tijd groeide het aantal scripts en werden we geconfronteerd met het feit dat er een bepaalde bedrijfslogica is voor het inzetten van een installatie die gesynchroniseerd moet worden tussen verschillende scripts, dit is behoorlijk ingewikkeld.

Wat ik heb geleerd van het testen van 200 regels infrastructuurcode

Het blijkt dat er zo'n praktijk bestaat als D.R.Y. (Herhaal jezelf niet). Het idee is om bestaande code te hergebruiken. Het klinkt eenvoudig, maar hier zijn we niet meteen op gekomen. In ons geval was het een banaal idee: configuraties scheiden van scripts. Die. bedrijfslogica van hoe de installatie afzonderlijk wordt geïmplementeerd, configuraties afzonderlijk.

STEVIG. voor CFM

Wat ik heb geleerd van het testen van 200 regels infrastructuurcode

In de loop van de tijd groeide het project en natuurlijke voortzetting was de opkomst van Ansible. De belangrijkste reden voor zijn verschijning is dat er expertise in het team zit en dat bash niet is ontworpen voor complexe logica. Ansible begon ook complexe logica te bevatten. Om te voorkomen dat complexe logica in chaos verandert, zijn er principes voor het organiseren van code bij softwareontwikkeling STEVIG. Ook stelde Grigory Petrov in het rapport "Waarom heeft een IT-specialist een persoonlijk merk nodig" de vraag op dat een persoon zo is ontworpen dat het voor hem gemakkelijker is om met sommige sociale entiteiten samen te werken, bij de ontwikkeling van software zijn deze zijn objecten. Als we deze twee ideeën combineren en verder ontwikkelen, zullen we merken dat we er ook gebruik van kunnen maken STEVIG. om het gemakkelijker te maken deze logica in de toekomst te onderhouden en aan te passen.

Het principe van gezamenlijke verantwoordelijkheid

Wat ik heb geleerd van het testen van 200 regels infrastructuurcode

Elke klas voert slechts één taak uit.

Het is niet nodig om code te mixen en monolithische goddelijke spaghettimonsters te maken. De infrastructuur moet uit eenvoudige stenen bestaan. Het blijkt dat als je het Ansible-speelboek in kleine stukjes opsplitst en Ansible-rollen leest, ze gemakkelijker te onderhouden zijn.

Het open gesloten principe

Wat ik heb geleerd van het testen van 200 regels infrastructuurcode

Open/gesloten principe.

  • Open voor uitbreiding: betekent dat het gedrag van een entiteit kan worden uitgebreid door nieuwe entiteitstypen te creëren.
  • Gesloten voor verandering: als gevolg van het uitbreiden van het gedrag van een entiteit mogen er geen wijzigingen worden aangebracht in de code die deze entiteiten gebruikt.

In eerste instantie hebben we de testinfrastructuur op virtuele machines geïmplementeerd, maar omdat de bedrijfslogica van de implementatie los stond van de implementatie, hebben we zonder problemen de uitrol naar baremetall toegevoegd.

Het Liskov-substitutieprincipe

Wat ik heb geleerd van het testen van 200 regels infrastructuurcode

Het substitutieprincipe van Barbara Liskov. objecten in een programma moeten vervangbaar zijn door instanties van hun subtypes zonder de correcte uitvoering van het programma te veranderen

Als je het breder bekijkt, is het geen kenmerk van een bepaald project dat daar kan worden toegepast STEVIG., het gaat over het algemeen over CFM, bij een ander project is het bijvoorbeeld nodig om een ​​Java-applicatie in een box te implementeren bovenop verschillende Java-applicaties, applicatieservers, databases, besturingssystemen, enz. Aan de hand van dit voorbeeld zal ik verdere principes bespreken STEVIG.

In ons geval is er binnen het infrastructuurteam een ​​afspraak dat als we de imbjava- of oraclejava-rol hebben geïnstalleerd, we een binair uitvoerbaar Java-bestand hebben. Dit is nodig omdat Upstream-rollen zijn afhankelijk van dit gedrag; ze verwachten Java. Tegelijkertijd stelt dit ons in staat de ene Java-implementatie/-versie te vervangen door een andere zonder de implementatielogica van de applicatie te veranderen.

Het probleem hierbij schuilt in het feit dat het onmogelijk is om dit in Ansible te implementeren, waardoor er binnen het team enkele afspraken ontstaan.

Het interfacesegregatieprincipe

Wat ik heb geleerd van het testen van 200 regels infrastructuurcode

Interface-scheidingsprincipe: “Veel klantspecifieke interfaces zijn beter dan één interface voor algemene doeleinden.

Aanvankelijk probeerden we alle variabiliteit van de applicatie-implementatie in één Ansible-playbook onder te brengen, maar het was moeilijk te ondersteunen, en de aanpak als we een externe interface specificeerden (de klant verwacht poort 443), dan kan een infrastructuur worden samengesteld uit individuele stenen voor een specifieke implementatie.

Het principe van afhankelijkheidsinversie

Wat ik heb geleerd van het testen van 200 regels infrastructuurcode

Het principe van afhankelijkheidsinversie. Modules op hogere niveaus mogen niet afhankelijk zijn van modules op lagere niveaus. Beide typen modules moeten afhankelijk zijn van abstracties. Abstracties mogen niet afhankelijk zijn van details. Details moeten afhankelijk zijn van abstracties.

Hier zal het voorbeeld gebaseerd zijn op een antipatroon.

  1. Eén van de klanten beschikte over een private cloud.
  2. We hebben virtuele machines in de cloud besteld.
  3. Maar vanwege de aard van de cloud was de implementatie van applicaties afhankelijk van de hypervisor waarop de VM stond.

Die. De logica voor applicatie-implementatie op hoog niveau stroomde met afhankelijkheden naar lagere niveaus van de hypervisor, en dit betekende problemen bij het hergebruik van deze logica. Doe dit niet zo.

Wisselwerking

Wat ik heb geleerd van het testen van 200 regels infrastructuurcode

Infrastructuur als code gaat niet alleen over code, maar ook over de relatie tussen code en mensen, over interacties tussen infrastructuurontwikkelaars.

Bus-factor

Wat ik heb geleerd van het testen van 200 regels infrastructuurcode

Laten we aannemen dat je Vasya in je project hebt. Vasya weet alles over uw infrastructuur, wat gebeurt er als Vasya plotseling verdwijnt? Dit is een zeer reële situatie, omdat hij door een bus zou kunnen worden aangereden. Soms gebeurt het. Als dit gebeurt en de kennis over de code, de structuur ervan, hoe deze werkt, het uiterlijk en de wachtwoorden niet onder het team is verdeeld, kunt u een aantal vervelende situaties tegenkomen. Om deze risico’s te minimaliseren en kennis binnen het team te verspreiden, kun je gebruik maken van verschillende aanpakken

Paar-devopsing

Wat ik heb geleerd van het testen van 200 regels infrastructuurcode

Het is niet zoals als een grap, dat de beheerders bier dronken, wachtwoorden veranderden en een analoog van paarprogrammering. Die. twee engineers zitten achter één computer, één toetsenbord en beginnen samen met het opzetten van uw infrastructuur: een server opzetten, een Ansible-rol schrijven, etc. Het klinkt leuk, maar voor ons werkte het niet. Maar speciale gevallen van deze praktijk werkten. Er komt een nieuwe medewerker, zijn mentor neemt samen met hem een ​​echte taak op zich, werkt en draagt ​​kennis over.

Een ander speciaal geval is een incidentoproep. Bij een probleem komt een groep dienstdoende en betrokkenen bij elkaar, er wordt één leider aangesteld, die zijn scherm deelt en de gedachtegang vertolkt. Andere deelnemers volgen de gedachten van de leider, bespioneren trucs vanaf de console, controleren of ze geen regel in het logboek hebben gemist en leren nieuwe dingen over het systeem. Deze aanpak werkte vaker wel dan niet.

Code recensie

Wat ik heb geleerd van het testen van 200 regels infrastructuurcode

Subjectief gezien was het effectiever om kennis over de infrastructuur en hoe deze werkt te verspreiden met behulp van code review:

  • De infrastructuur wordt beschreven met code in de repository.
  • Wijzigingen vinden plaats in een aparte vestiging.
  • Tijdens een samenvoegverzoek kunt u de delta van wijzigingen in de infrastructuur zien.

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.

Code stijl

Wat ik heb geleerd van het testen van 200 regels infrastructuurcode

Na verloop van tijd begonnen er ruzies te verschijnen tijdens recensies, omdat... reviewers hadden hun eigen stijl en de rotatie van reviewers stapelde ze op met verschillende stijlen: 2 spaties of 4, camelCase of snake_case. Het was niet mogelijk om dit meteen in praktijk te brengen.

  • Het eerste idee was om het gebruik van linter aan te bevelen, iedereen is immers een ingenieur, iedereen is slim. Maar verschillende editors, besturingssystemen, zijn niet handig
  • Dit evolueerde naar een bot die voor elke problematische commit schreef en de linter-uitvoer bijvoegde. Maar in de meeste gevallen waren er belangrijkere dingen te doen en bleef de code onopgelost.

Groene bouwmeester

Wat ik heb geleerd van het testen van 200 regels infrastructuurcode

De tijd verstrijkt en we zijn tot de conclusie gekomen dat commits die bepaalde tests niet doorstaan, niet kunnen worden toegelaten tot de master. Voila! We hebben de Green Build Master uitgevonden, die al heel lang in de softwareontwikkeling wordt toegepast:

  • De ontwikkeling vindt plaats in een aparte tak.
  • Er worden tests uitgevoerd op dit draadje.
  • Als de tests mislukken, komt de code niet in de master.

Het nemen van deze beslissing was erg pijnlijk, omdat... veroorzaakte veel controverse, maar het was het waard, omdat... Recensies begonnen verzoeken om fusies te ontvangen zonder stijlverschillen, en na verloop van tijd begon het aantal probleemgebieden af ​​te nemen.

IaC-testen

Wat ik heb geleerd van het testen van 200 regels infrastructuurcode

Naast stijlcontrole kunt u met andere zaken bijvoorbeeld controleren of uw infrastructuur daadwerkelijk inzetbaar is. Of controleer of veranderingen in de infrastructuur niet tot geldverlies leiden. Waarom zou dit nodig kunnen zijn? De vraag is complex en filosofisch, het is beter om te antwoorden met een verhaal dat er op de een of andere manier een auto-scaler op Powershell was die de randvoorwaarden niet controleerde => er werden meer VM's gemaakt dan nodig => de klant gaf meer geld uit dan gepland. Dit is niet erg prettig, maar het zou heel goed mogelijk zijn om deze fout in een eerder stadium te ontdekken.

Je zou je kunnen afvragen: waarom zou je complexe infrastructuur nog complexer maken? Testen voor infrastructuur gaan, net als voor code, niet over vereenvoudiging, maar over weten hoe je infrastructuur zou moeten werken.

IaC-testpiramide

Wat ik heb geleerd van het testen van 200 regels infrastructuurcode

IaC-testen: statische analyse

Als u de gehele infrastructuur in één keer implementeert en controleert of deze werkt, zult u merken dat dit veel tijd kost en veel tijd vergt. Daarom moet de basis iets zijn dat snel werkt, er is veel van, en het bestrijkt veel primitieve plaatsen.

Bas is lastig

Laten we een triviaal voorbeeld bekijken. selecteer alle bestanden in de huidige map en kopieer naar een andere locatie. Het eerste dat in je opkomt:

for i in * ; do 
    cp $i /some/path/$i.bak
done

Wat moet ik doen als er een spatie in de bestandsnaam staat? Nou, oké, we zijn slim, we weten hoe we aanhalingstekens moeten gebruiken:

for i in * ; do cp "$i" "/some/path/$i.bak" ; done

Goed gedaan? Nee! Wat als er niets in de map staat, d.w.z. globben zal niet werken.

find . -type f -exec mv -v {} dst/{}.bak ;

Nu goed gedaan? Nee... Vergat wat er in de bestandsnaam kan staan n.

touch x
mv x  "$(printf "foonbar")"
find . -type f -print0 | xargs -0 mv -t /path/to/target-dir

Statische analysehulpmiddelen

Het probleem uit de vorige stap kan worden opgelost als we de aanhalingstekens vergeten zijn. Hiervoor zijn er veel oplossingen in de natuur Shellcheck, over het algemeen zijn er veel, en hoogstwaarschijnlijk kun je onder je IDE een linter voor je stapel vinden.

Taal
Gereedschap

slaan
Shellcheck

Ruby
RuboCop

python
pylint

Ansible
Ansibel Lint

IaC-testen: eenheidstests

Wat ik heb geleerd van het testen van 200 regels infrastructuurcode

Zoals we uit het vorige voorbeeld hebben gezien, zijn linters niet almachtig en kunnen ze niet alle probleemgebieden aanwijzen. Verder kunnen we, naar analogie met testen bij softwareontwikkeling, unit-tests in herinnering brengen. Wat meteen in je opkomt is shunit, juni, rspec, vraag. Maar wat te doen met weerwort, chef-kok, saltstack en anderen zoals zij?

Helemaal aan het begin hadden we het erover STEVIG. en dat onze infrastructuur uit kleine bouwstenen moet bestaan. Hun tijd is gekomen.

  1. De infrastructuur is opgedeeld in kleine stenen, bijvoorbeeld Ansible-rollen.
  2. Er wordt een soort omgeving geïmplementeerd, of het nu een docker of een VM is.
  3. Op deze testomgeving passen wij onze Ansible-rol toe.
  4. We controleren of alles werkte zoals we hadden verwacht (we voeren tests uit).
  5. Wij beslissen: oké of niet oké.

IaC-testen: tools voor het testen van eenheden

Vraag, wat zijn tests voor CFM? U kunt eenvoudig het script uitvoeren, of u kunt hiervoor kant-en-klare oplossingen gebruiken:

CFM
Gereedschap

Ansible
testinfra

Chef
Inspecteren

Chef
Serverspecificatie

zoutberg
Goss

Voorbeeld voor testinfra, controleren of gebruikers test1, test2 bestaan ​​en bevinden zich in een groep sshusers:

def test_default_users(host):
    users = ['test1', 'test2' ]
    for login in users:
        assert host.user(login).exists
        assert 'sshusers' in host.user(login).groups

Wat te kiezen? De vraag is complex en dubbelzinnig, hier is een voorbeeld van veranderingen in projecten op github voor 2018-2019:

Wat ik heb geleerd van het testen van 200 regels infrastructuurcode

IaC-testframeworks

De vraag rijst: hoe moet je alles samenbrengen en lanceren? Kan neem het en doe het zelf als er voldoende ingenieurs zijn. Of u kunt kant-en-klare oplossingen nemen, hoewel er niet veel van zijn:

CFM
Gereedschap

Ansible
molecule

Chef
Test keuken

Terraform
Terratest

Voorbeeld van wijzigingen in projecten op github voor 2018-2019:

Wat ik heb geleerd van het testen van 200 regels infrastructuurcode

Molecuul versus Testkeuken

Wat ik heb geleerd van het testen van 200 regels infrastructuurcode

Aanvankelijk wij geprobeerd met testkitten:

  1. Maak parallel een VM.
  2. Pas Ansible-rollen toe.
  3. Voer inspectie uit.

Voor 25-35 rollen werkte het 40-70 minuten, wat lang was.

Wat ik heb geleerd van het testen van 200 regels infrastructuurcode

De volgende stap was de overstap naar jenkins/docker/ansible/molecule. Idiologisch is alles hetzelfde

  1. Lint-speelboeken.
  2. Zet de rollen op een rij.
  3. Lanceer container
  4. Pas Ansible-rollen toe.
  5. Voer testinfra uit.
  6. Controleer de idempotentie.

Wat ik heb geleerd van het testen van 200 regels infrastructuurcode

Het pluizen van 40 rollen en het testen van een tiental rollen duurden ongeveer 15 minuten.

Wat ik heb geleerd van het testen van 200 regels infrastructuurcode

Wat je moet kiezen, hangt van veel factoren af, zoals de gebruikte stapel, de expertise in het team, enz. hier beslist iedereen zelf hoe hij de Unit-testvraag sluit

IaC-testen: integratietests

Wat ik heb geleerd van het testen van 200 regels infrastructuurcode

De volgende stap in de infrastructuurtestpiramide zijn integratietests. Ze zijn vergelijkbaar met eenheidstests:

  1. De infrastructuur is opgedeeld in kleine bouwstenen, bijvoorbeeld Ansible-rollen.
  2. Er wordt een soort omgeving geïmplementeerd, of het nu een docker of een VM is.
  3. Voor deze testomgeving geldt veel Ansible-rollen.
  4. We controleren of alles werkte zoals we hadden verwacht (we voeren tests uit).
  5. Wij beslissen: oké of niet oké.

Grofweg controleren we niet de prestaties van een afzonderlijk element van het systeem, zoals bij unit-tests, maar hoe de server als geheel is geconfigureerd.

IaC-testen: end-to-end-tests

Wat ik heb geleerd van het testen van 200 regels infrastructuurcode

Bovenaan de piramide worden we begroet door End-to-End-tests. Die. We controleren niet de prestaties van een afzonderlijke server, een afzonderlijk script of een afzonderlijke steen van onze infrastructuur. We controleren of er veel servers met elkaar verbonden zijn, onze infrastructuur werkt zoals we verwachten. Helaas heb ik nog nooit kant-en-klare oplossingen in dozen gezien, waarschijnlijk omdat... De infrastructuur is vaak uniek en moeilijk te ontwerpen en een raamwerk voor testen te creëren. Hierdoor creëert iedereen zijn eigen oplossingen. Er is een vraag, maar er is geen antwoord. Daarom zal ik je vertellen wat er is om anderen tot gezonde gedachten te brengen of om in mijn neus te wrijven over het feit dat alles lang geleden vóór ons is uitgevonden.

Wat ik heb geleerd van het testen van 200 regels infrastructuurcode

Een project met een rijke historie. Het wordt gebruikt in grote organisaties en waarschijnlijk is ieder van jullie er indirect mee in aanraking gekomen. De applicatie ondersteunt vele databases, integraties, enz. Weten hoe de infrastructuur eruit zou kunnen zien, is een hoop docker-compose-bestanden, en weten welke tests in welke omgeving moeten worden uitgevoerd is Jenkins.

Wat ik heb geleerd van het testen van 200 regels infrastructuurcode

Dit schema werkte een hele tijd, tot binnen het kader onderzoek we hebben niet geprobeerd dit over te zetten naar Openshift. De containers blijven hetzelfde, maar de startomgeving is veranderd (hallo D.R.Y. nogmaals).

Wat ik heb geleerd van het testen van 200 regels infrastructuurcode

Het onderzoeksidee ging verder en in openshift vonden ze zoiets als APB (Ansible Playbook Bundle), waarmee je kennis over het inzetten van infrastructuur in een container kunt stoppen. Die. er is een herhaalbaar, testbaar kennispunt over hoe de infrastructuur moet worden ingezet.

Wat ik heb geleerd van het testen van 200 regels infrastructuurcode

Dit klonk allemaal goed totdat we tegen een heterogene infrastructuur aanliepen: we hadden Windows nodig voor tests. Als gevolg hiervan bevindt de kennis van wat, waar, hoe te implementeren en te testen zich in Jenkins.

Conclusie

Wat ik heb geleerd van het testen van 200 regels infrastructuurcode

Infrastructuur zoals Code is

  • Code in de repository.
  • Menselijke interactie.
  • Testen van de infrastructuur.

links

Bron: www.habr.com

Voeg een reactie