TSM - Livrarea soluțiilor .NET folosind Octopus Deploy

Alexandru Ivanov - Senior DevOps Engineer @ Endava


Continuous Integration este o practică DevOps din domeniul dezvoltării de software prin care fiecare membru al echipei de programatori își integrează munca cu ceilalți colegi în codul sursă de mai multe ori pe zi. Ea este considerată o formă de control al calității. Integrările sunt verificare de un build automat care este utilizat pentru a detecta erorile de integrare cât mai repede posibil și pentru a testa aplicația.

În acest cadru intră Jenkins, o unealtă de Continuous Integration și Continuous Deployment, folosită pe mai multe platforme (cross-platforms) de dezvoltare.

Jenkins permite programatorilor de software să își integreze modificările codului în proiect și să creeze un nou build pe care îl pot folosi în procesul de Continuous Delivery, oferindu-le astfel posibilitatea de a se încorpora într-un număr mare de tehnologii de testare și Continuous Deployment.

Prin intermediul a diferite platforme de build, Jenkins poate împacheta codul în mai multe feluri, dar cea mai potrivită pentru un proiect Microsoft .NET cu distribuire continuă sunt pachetele NuGet sau ".nupkg".

Procesul de build trece prin diferiți pași:

  1. Pachetele NuGet sunt restaurate pentru ca toate dependințele de proiect să fie actualizate;

  2. Se face build la proiect;

  3. Teste Nunit pot fi rulate pentru a asigura un cod lipsit de erori;

  4. Librăriile sunt împachetate;

  5. Rezultatele sunt publicate.

Rezultatul, un pachet ".nupkg", este apoi preluat de serverul de Continuous Deployment și trimis mediilor de dezvoltare, testare și producție.

Dar continuarea logică din acest "drum" este Continuous Delivery. Continuous Delivery este extensia naturală a Continuous Integration, permițând pachetului să fie testat automat, însă distribuirea pachetului spre medii este una decizională și, prin urmare, manuală.

Ne putem întreba: care e similaritatea dintre Continuous Delivery și Continuous Deployment? Aici intră Continuous Deployment, drept completare a pipeline-ului, practică din cadrul DevOps în care fiecare schimbare de cod ajunge în producție automat, rezultând în mai multe deploymenturi de cod în producție pe zi.

În momentul actual, pe piață există o mare varietate de unelte pe care le putem folosi. Continuarea acestui articol se va concentra asupra Octopus Deploy.

Octopus Deploy este o aplicație de Continuous Deployment, foarte ușor de instalat și folosit, ce permite distribuirea automată a aplicațiilor web modelate prin ASP.NET în mediile de dezvoltare, test și producție.

Principalele caracteristici ale Octopus Deploy:

Dezvoltat de/și pentru programatorii .NET - Octopus Deploy este dezvoltat de programatori .NET pentru soluții .NET fără a chinui utilizatorii la editarea workflow-ului. Octopus poate distribui aplicații ASP.NET Webforms, aplicații WebAPI si WCF, servicii Windows etc. .

Intervenții manuale și aprobări de distribuire - Intervențiile manuale permit utilizatorilor să pună pauză în modelul de distribuire a aplicației pentru a adăuga comentarii, a anunța end-userii când are loc o distribuire a aplicației sau, pur și simplu, pentru a cere aprobarea de la un superior.

Introducerea de scripturi și modificarea de configurări - În procesul de distribuire, Octopus Deploy este foarte flexibil, fiind posibilă modificarea configurațiilor de tip ".config" cu alte variabile decât cele cu care au venit în pachet. Astfel, diferite puncte cheie din aplicație pot fi modificate înainte ca aplicația să fie disponibilă utilizatorilor finali. De asemenea, fiecare environment, fie că acesta este unul de dezvoltare sau test, va avea propriile lui fișiere de configurare.

Distribuirea in-cloud sau local - Octopus Deploy se conectează la fiecare mașină virtuală printr-un agent numit Tentacle, instalat în fiecare mașină virtuala și securizat prin SSL. De asemenea, există suport nativ pentru Active Directory, astfel nefiind necesară crearea de utilizatori separați.

Toate distribuțiile în același loc - Panoul principal al Octopus Deploy este foarte intuitiv, permițând vizionarea fiecărui chiriaș (eng. Tenant) care accesează serverul Octopus, cât și al fiecărui pachet distribuit către fiecare environment în parte.

Interfață și conexiune securizată - Conexiunea dintre Server și Client este realizată prin două căi: TSL 1.2 și SSL. De asemenea, conexiunea la serverul Octopus poate fi securizată prin certificat și HTTPS (port 443).

Distribuție multi-tenant - Începând cu versiunea 3.4, Octopus Deploy oferă clienților săi posibilitatea de a avea propria lor secțiune din același server Octopus, acesta putând fi folosit de mai mulți clienți în modelul multi-tenant. Fiecare client are propriul set de variabile, pipeline, inclusiv proiecte separate.

Într-unul din proiectele în care sunt implicat, aceste două unelte au schimbat radical felul în care codul compilat în pachete NuGet ajung în instanțele Sitecore. Atât Jenkins cât și Octopus Deploy au realizat o linie de deployment complet automată, de la împingerea codului din Visual Studio, direct în directorul paginii web. Fiecare pas a fost optimizat pentru a folosi cât mai puține resurse, generând o economisire considerabilă de timp a pipeline-ului. Astfel, de la un deployment de aproximativ 5-6 ore în orice environment, prin automatizarea build-ului și crearea de release și deploy, s-a ajuns la un deployment de 45 minute per fiecare environment în parte.

Începând cu Jenkins, pachetele NuGet sunt realizate automat din momentul în care developerul comite codul în Source code repository (SCM). Acesta este preluat de Jenkins printr-un webhook implementat în GitLab și compilat în fișiere de tip ". nupkg" cu ajutorul MSBuild și Octopack. Octopack este o librărie open-source creată și menținută de echipa Octopus Deploy care împachetează serviciile Windows și aplicațiile ASP.NET în momentul în care MSBuild rulează. Această librărie folosește nuget.exe pack pentru a clădi pachetele NuGet și nuget.exe push pentru a le publica. Al doilea pas este opțional.

După crearea pachetului NuGet, Jenkins se folosește de plug-in-ul SonarQube pentru a face măsura și analiza calitatea codului sursă. Informația rezultată este apoi trimisă spre serverul SonarQube și disponibilă developerilor de cod.

Deoarece serverul de Octopus Deploy se află în locația clientului, am optat pentru a face pachetele NuGet disponibile unui server sFTP și preluate de acesta printr-un tool de sincronizare numit JAMS. JAMS copiază pachetele și le publică serverului Octopus printr-un API.

O dată publicate, pachetele pot fi distribuite oricărui environment dorit. Octopus folosește terminologia de Lifecycle, o modalitate de controla ordinea de promovare a pachetelor cât și de automatizare a deploymentului către medii. Fiecare lifecycle este construit din faze, fiecare putând avea unul sau mai multe medii. Astfel, lifecycle-ul principal ne permite să distribuim pachetele de la environmentul de Development spre Production, trecând prin QA și UAT.

În diagrama de mai jos, putem vedea diferitele proiecte asociate cu acest server de Octopus. Am ales să avem un proiect de Development și unul de Production, în funcție de branchul din care vine fiecare pachet. De asemenea, proiectul de Automation este separat. Inițial, aceste teste au fost implementate in Jenkins, însă vizibilitatea pentru client este scăzută, iar timpul testului se întinde pe o perioadă mai mare de 1-2 ore. Astfel, cea mai bună opțiune, având în vedere că serverul Octopus se afla în locația clientului, a fost să implementăm testele în Octopus Deploy.

Fiecare proiect în parte are pipeline-ul lui, fiecare cu un pachet diferit din punct de vedere al numelui pentru a le putea identifica mai ușor. Însă, pentru a avea o structură cât mai ușor de urmărit, am optat pentru a partaja variabilele între cele cinci proiecte, obținându-se astfel un număr de seturi de variabile disponibile pentru toate cinci.

Un alt substrat important fiecărui proiect în Octopus îl reprezintă seturile de Step templates. Step templates fac parte din librăria Octopus și oferă posibilitatea de a templetiza diferiți pași din deploymentul fiecărui pachet. În acest fel, nu mai este necesar să reinventăm roata fiecărei acțiuni care se desfășoară la momentul deploymentului de cod compilat. Un exemplu foarte bun este oprirea de Application Pool în IIS. Fiecare template este scris cu proprii lui parametri și instrucțiuni în JSON ce poate fi importat în Octopus via meniul Library. Începând cu versiunea 3.7, Octopus verifică o dată pe zi template-urile din Community Library și le actualizează pe cele existente. Cu versiunea 3.7.2, aceste template-uri pot fi testate înainte de a le integra în procesul de deployment al codului.

Pe lângă alte atuuri ale sale, Octopus Deploy oferă clienților posibilitatea de a dezvolta, testa și implementa mai multe instanțe ale aceluiași proiect în fiecare environment. Astfel, fiecare deploy poate fi izolat în fiecare environment în care fiecare tester poate lucra pe datele sale de test, când dorește să facă upgrade și să aducă îmbunătățiri.

Deși Octopus vine cu o varietate mare de features, considerăm că Multi-tenant unul dintre cele mai importante începând cu versiunea 3.4.

Așa cum am expus mai devreme în caracteristicile aplicației, multi-tenant oferă clienților să facă deployment la mai multe instanțe ale aplicației pe același environment. Acum nu mai e necesar să creăm directoare diferite pentru diferite variante ale aceluiași software. Fiecare tenant vine cu propriul lui set de variabile, cu lifecycle-ul lui unic și cu propriul set de reguli de securitate. Astfel, fiecare environment devine o felie din cel original, permițându-i tenantului să își izoleze codul și să facă toate testele necesare înainte ca acesta să fie implementat în producție.

De asemenea, multi-tenant nu se rezumă doar la un singur mediu într-o singură regiune. Prin tenant, Octopus ne permite să distribuim pachetele pe mai multe regiuni geografice, evitând astfel crearea de mai mult environmente în loc să modelăm fiecare regiune ca un tenant în același environment.

Concluzie

Pe termen lung, Octopus Deploy reprezintă o investiție pentru orice echipă care dorește să dezvolte un cod sănătos. Deși nu e software perfect, i se pot aduce îmbunătățiri în fiecare zi cu ajutorul comunității. Sper că acest articol v-a convins că Octopus merită încercat.