Featured image of post Aan de slag met Azure Pipelines

Aan de slag met Azure Pipelines

Azure DevOps is een SaaS-oplossing voor gitrepository’s, wiki’s, artifact repository en meer. Eén onderdeel ervan is Azure Pipelines voor je CI/CD-pipelines. We laten zien hoe je hier snel mee aan de slag kan.

Azure Pipelines is een onderdeel van Azure DevOps waarmee je via yaml CI- en CD-pipelines kunt bouwen. Je doet dat door een yaml file in je gitrepository te maken. Vaak heet dat bestand azure-pipelines.yml. Je kunt zoveel pipelines in een repository maken als je wilt, zoals bijvoorbeeld twee pipelines via een azure-pipelines-ci.yml- en een azure-pipelines-cd.yml-bestand. Vervolgens maak je in Pipelines een nieuwe pipeline aan waarbij je die verwijst naar het yml-bestand in je gitrepository. Azure Pipelines pakt dat bestand op, parset het en maakt er een pipeline van.

Je eerste pipeline

Om ermee aan de slag te gaan, klink je links in het menu op Pipelines in Azure DevOps en kies je voor New. Vervolgens kun je kiezen waar je code leeft, dat kan in Azure Repos zijn, maar ook in GitHub, Bitbucket Cloud of elke andere git-server die Azure DevOps kan bereiken. Kies daarna je repository en dan kun je je template kiezen. Er zijn templates voor allerlei soorten projecten, Node.js, Java, Python, .NET. Als je blanco wilt beginnen, kies je voor Starter pipeline. Heb je al een pipelines-yml in je repo, kies dan voor Existing Azure Pipelines YAML file.

Wij starten een blanco pipeline. Je ziet dan de yml-teksteditor met daarin code voor een trigger, een lijst van branches waarvoor een build start, een pool en de stappen van de pipeline. Onder stappen kun je nu je pipeline uitwerken. Klik rechts op Show assistant om te zien wat voor stappen je toe kunt voegen. Hier vind je allerlei buildtools, zoals Maven, Visual Studio Build, Python, Node maar ook simpelweg bash, een stap om een map te zippen, PowerShell en meer.

Als je stappen mist, dan kun je via de Azure DevOps Marketplace extensies installeren die meer stappen toevoegen. Daar vind je bijvoorbeeld een AWS Toolkit, Cloud Foundry, SonarQube en meer.

Elke stap heeft een set unieke attributen, waarmee je 'm kunt configureren, maar Pipelines heeft ook een reeks ingebouwde attributen voor elke stap. Een daarvan is bijvoorbeeld displayName, waarmee je de stap een duidelijke naam in de interface geeft, en ook condition. Met condition wordt de stap alleen uitgevoerd als aan die conditie wordt voldaan. Je vindt de syntax daarvan in Azure Pipelines-documentatie, maar als je bijvoorbeeld een stap alleen wilt uitvoeren op de master-branch, dan ziet dat er zo uit:

condition: eq(variables['Build.SourceBranch'], 'refs/heads/master')

Verder is het belangrijk te weten dat je variabelen kunt gebruiken in Azure Pipelines. Standaard zijn er een set ingebouwd: de volledige lijst vind je hier. Je kunt ook zelf variabelen maken, door deze bovenin je pipeline te definiëren als volgt:

variables:
  - name: myVariable
    value: valueOfVariable

Voor secret variables klik je in de pipeline editor op de knop Variables en voeg je er een toe. Vink de optie Keep this value secret aan zodat die geheim blijft. Je kunt de variabele dan gebruiken via $(mySecretVariable). Je kunt ook variabele-groepen maken, handig voor als je veel secrets hebt, of secrets ophalen uit Azure KeyVaults. Daarvoor check je deze pagina.

Je kunt ook parameters in je pipeline gebruiken, die je dan moet invoeren voordat je de pipeline start.

Stages en jobs

Als je pipeline groeit, krijg je veel stappen en wordt het misschien onoverzichtelijk. Daarvoor kun je je steps verdelen over jobs en je jobs kun je weer verdelen over een set van stages. Een stage is bijvoorbeeld bouw deze app, voer de (integration) tests uit of release de app naar productie. Een job is een verzameling van steps, bijvoorbeeld een job om alle unit tests uit te voeren en een om alle integration tests uit te voeren. Je kunt condities ook gebruiken voor jobs en stages.

Je hoeft niet per se stages en jobs te gebruiken in je yml-file: je kunt ook gewoon steps neerzetten. Je krijgt dan een impliciete stage en job die Azure Pipelines vanzelf voor je aanmaakt. Het voordeel van het gebruik van jobs en stages is dat je ze op aparte agents kunt uitvoeren. Alle steps in een job worden op dezelfde agent uitgevoerd.

Tussen verschillende stages kun je informatie uitwisselen. Je kunt een variabele in de ene stage definiëren en in de andere uitlezen. Dat geldt ook voor bestanden. Je kunt dit ook bereiken voor jobs.

Stages kunnen afhankelijk zijn van andere stages en jobs van andere jobs. Ook kun je stages en jobs in parallel uitvoeren. Standaard depent een stage op de vorige stage. Als je aan een stage toevoegt: dependsOn: [] dan haal je die impliciete afhankelijkheid weg. Je kunt hier natuurlijk ook andere stages aan de lijst toevoegen.

Pipelines vs Releases

In Azure DevOps vind je naast de sectie Pipelines ook een onderdeel Releases. Pipelines kun je zien als de opvolger van Releases: die laatste is eigenlijk deprecated. We zeggen 'eigenlijk', omdat het lijkt alsof Microsoft nog niet zeker weet wat het met Releases wil doen. Het verschil tussen beide is dat Releases alleen bedoeld is voor het releasen van je applicatie en je daarmee je pipeline met een GUI bouwt. Je Release-pipeline kun je niet onder version control in git plaatsen. Dat is een groot nadeel.

Bovendien brengt Microsoft geen nieuwe functies meer uit voor Releases en vindt de meeste ontwikkeling plaats aan Pipelines. Pipelines schrijf je helemaal in yml en plaats je onder version control, wat ze veel meer geschikt maakt voor DevOps waarbij je infrastructure-code ook onderdeel is van je version control, daardoor beter beheersbaar is en changes gereviewd kunnen worden door teamleden.

Tip: gebruik de code-editor van Azure Pipelines zelf

Als je een yml-bestand van Azure Pipelines bewerkt, dan raden we aan om de code-editor te gebruiken in Azure Pipelines zelf. Je vindt die door bij een pipeline op de drie puntjes rechtsboven te klikken en de pipeline dan te bewerken. Door deze editor te gebruiken, krijg je syntax highlighting en validation van de Azure Pipelines YML. Ook kun je in de editor rechtsboven op de drie puntjes klikken en dan een file valideren. Op die manier weet je zeker dat wat je schrijft geldig is voor Azure Pipelines en de pipeline uitgevoerd kan worden.

Pipeline artifacts & triggers

In je Azure Pipeline kun je je gebouwde artifact laten vastleggen in de pipeline. Daarvoor gebruik je de stap Publish Pipeline Artifact-stap. Je geeft dan aan welke map het artifact bevat en hoe je artifact moet heten.

Stel je maakt nu een aparte deployment-pipeline, dan kun je nu eenvoudig de artifact binnenhalen door gebruik te maken van de Download Pipeline Artifact-stap. Vul dan bij artifactName dezelfde naam in als je bij de publish-stap gebruikt en vul ook de andere gevraagde gegevens in.

Nu willen we als laatste nog dat onze release-pipeline automatisch gestart wordt nadat de CI-pipeline succesvol is afgerond. Dat kunnen we configureren door de CI-pipeline als resource toe te voegen en de trigger-property op true te zetten. Hoe dat er precies uitziet, lees je hier.

4-ogenprincipe

Voor veel organisaties is het wenselijk dat je niet alleen zomaar iets live kunt zetten, maar dat dat goedgekeurd wordt door iemand anders. Je kunt dat in Azure DevOps op verschillende manieren opzetten: bijvoorbeeld bij elke pull request naar master, maar ook in de pipeline zelf kun je een toestemmingstap inbouwen, maar dat is helaas niet zo eenvoudig.

Om zo'n stap in Azure Pipelines toe te voegen, maak je eerst een nieuwe Environment (in de linkerbalk onder Pipelines). Wij noemen de onze Prod. Bij Resource kies je dan voor None. Vervolgens kun je op je nieuwe environment rechtsboven op de drie puntjes klikken en kiezen voor Approvals and checks. Klik dan op de plus-knop rechtsboven en kies voor Approvals. Vul de gebruikers in of de groep die moet goedkeuren. Let op dat bij een groep één approver van de groep genoeg is. Stel je hebt een audit-trail nodig dat echt twee mensen approved hebben, dan kun je hier beter gebruikers los invullen. Zorg ervoor dat je de optie om eigen runs te approven uitgevinkt hebt en zet de minimum number of approvals op 2. Klik op Create om de check te maken.

In je pipeline kun je nu je nieuwe Environment gebruiken. Dat doe je als volgt:

- stage: deploy
  jobs:
  - deployment: DeployWeb
    displayName: deploy Web App
    environment: 'Prod'
    strategy:
      runOnce:
        deploy:
          steps:
            - script: echo Hello world
            ... de rest van je deploy-stappen ...

Je ziet hier dat we aan de job een aantal property's toevoegen. Het is buiten de scope van dit artikel om op de property's in te gaan, maar hier vind je de docs erover. Het belangrijkste wat je moet weten is dat we op de environment genaamd 'Prod' een deployment registreren, dat doen we via de strategy/runOnce/deploy property's. Op deze manier worden de regels van die environment geladen en wordt ons gevraagd om approvals om de stappen uit te voeren. Ook kunnen we hierdoor deployments naar deze environment volgen in de environment zelf in de Azure DevOps-interface. Wil je er meer over lezen, check dan deze docs.

Screenshot: Approvals and checks van een Environment
Aan onze Environment koppelen we onze approvers.

Conclusie

We hebben je laten zien hoe je je eerste Azure Pipeline kunt opbouwen uit verschillende taken en meer taken kunt toevoegen via de Marketplace. Ook hebben we je laten zien hoe je condities kunt toevoegen aan je stappen en hoe je artifacts kunt publiceren en consumeren. Als laatste voor een echte 'productiepipeline' heb je natuurlijk een 4-ogenprincipe nodig. Dat werkt wat minder fijn in Azure Pipelines, maar is zeker wel ondersteund.

Er is natuurlijk heel veel wat we niet behandeld hebben, zoals triggers, templates en meer, laat staan alle leuke dingen die je kunt doen met de Azure DevOps CLI, maar hopelijk is het genoeg voor je om een goede start ermee te maken.