HOE KAN IK TEMPLATES INZETTEN IN AZURE DEVOPS?
Templates kun je verdelen in verschillende onderdelen. Zo is het mogelijk om een stage template, job template of step template te bouwen waarbij je tot in de kleinste stap een template kunt gebruiken. Mocht je gebruik maken van veelvoorkomende variabelen is het ook mogelijk om een variabele template te gebruiken die je vervolgens ophaalt bij het runnen van de pipeline. Zo hoef je enkel maar één variabele file te gebruiken.
4 stappen voor het opzetten van Azure DevOps templates
Om goed gebruik te kunnen gaan maken van Azure DevOps templates is het van belang om een aantal stappen uit te voeren. Deze stappen zijn als volgt:
- Identificeren van veel voorkomende stappen, door vooraf veelvoorkomende stappen te identificeren in een CI/CD straat is helder welke bouwblokken ontwikkeld kunnen worden.
- Creeren van de pipeline, de volgende stap is het ontwikkelen van deze bouwblokken. Deze bouwblokken zijn feitelijk gewoon pipelines en deze pipelines dienen dus ontwikkeld te worden in Azure DevOps.
- Beschikbaar stellen van de template, als er bouwblokken ontwikkeld zijn maar niemand weet waar deze staan en hoe deze gebruikt kunnen worden is het verloren moeite. Zorg er dus voor dat de bouwblokken beschikbaar worden gesteld op een centrale plek, zodat de herbruikbaarheid gewaarborgd wordt.
- Version management, als laatste stap dienen de pipelines up-to-date gehouden te worden. Waarbij ontwikkelteams geen hinder ondervinden van wijzigingen aan de bouwblokken.
Deze verschillende stappen worden hieronder verder toegelicht.
Identificeren van veel voorkomende stappen tijdens build en deployment
Gedurende de build en deployment zijn er een aantal stappen die veel voorkomend zijn. Het is van belang om deze stappen in kaart te brengen zodat je weet welke templates van toepassing zullen zijn. Zo zijn veelvoorkomende stappen bijvoorbeeld build gerelateerde stappen zoals: ‘build image’, ‘security check’, ‘check code coverage’ etc.. Maar ook deployment gerelateerde stappen zoals: ‘download docker image van container registry’ of ‘deploy image naar Azure Kubernetes Service’.
Creëren van pipelines voor de veelvoorkomende stappen
Een logische vervolgstap na het identificeren van de veelvoorkomende stappen in de CI/CD straat is het ontwikkelen van deze template pipelines.
Kijk bijvoorbeeld eens naar de volgende code snippet. Hierin is een voorbeeld te vinden van een stage zoals deze is opgenomen in azure-pipelines.yaml, het gaat hierbij enkel om de de build stage uit de azure-pipelines.yaml.
#azure-pipelines.yaml
stages:
- stage: build
displayName: Build and push container image
jobs:
- job: build
steps:
- task: Docker@2
displayName: Login to Azure Container Registry
inputs:
command: login
containerRegistry: $
- task: Docker@2
displayName: Build and push container image
inputs:
repository: $
command: buildAndPush
Dockerfile: '$(Build.SourcesDirectory)/wp-content/Dockerfile'
buildContext: app
tags: $(Build.BuildId)
- task: CmdLine@2
displayName: Replace tokens in manifest
inputs:
script: |
sed -i "s|%IMAGE_TAG%|${IMAGE_TAG}|g" kubernetes/*.yaml
env:
IMAGE_TAG: $(Build.BuildId)
- task: PublishPipelineArtifact@1
displayName: Store kubernetes template as pipeline artifact
inputs:
path: $(System.DefaultWorkingDirectory)/kubernetes
artifact: $-kubernetes
Deze volledige build stap is een herbruikbare stap en kan gebruikt worden als bouwblok. We gaan deze build stage verplaatsen naar een nieuwe repository genaamd ‘Global’. Vervolgens roepen we het template aan in onze #azure-pipelines.yaml.
#azure-pipelines.yaml
resources:
repositories:
- repository: Global
type: git
name: Global/Global
ref: 'refs/heads/master'
stages:
- template: 'build.yml@Global'
parameters:
AcrHost: $
AcrImage: $
ServiceName: $
#build.yml@Global
parameters:
- name: AcrHost
type: string
- name: AcrImage
type: string
- name: ServiceName
type: string
stages:
- stage: build
displayName: Build and push container image
jobs:
- job: build
steps:
- task: Docker@2
displayName: Login to Azure Container Registry
inputs:
command: login
containerRegistry: $
- task: Docker@2
displayName: Build and push container image
inputs:
repository: $
command: buildAndPush
Dockerfile: '$(Build.SourcesDirectory)/wp-content/Dockerfile'
buildContext: app
tags: $(Build.BuildId)
- task: CmdLine@2
displayName: Replace tokens in manifest
inputs:
script: |
sed -i "s|%IMAGE_TAG%|${IMAGE_TAG}|g" kubernetes/*.yaml
env:
IMAGE_TAG: $(Build.BuildId)
- task: PublishPipelineArtifact@1
displayName: Store kubernetes template as pipeline artifact
inputs:
path: $(System.DefaultWorkingDirectory)/kubernetes
artifact: $-kubernetes
Bij het runnen van de pipeline zul je zien dat de stappen die voorheen nog in azure-pipelines.yaml uitgevoerd werden, nu worden aangeroepen door middel van een template uit de Global. Dit zie je dan ook terug onder de pipeline run.
.png?width=752&height=216&name=image%20(1).png)
Eerder getoonde templates is een voorbeeld van het vervangen van een volledige stage. Dit kan ook gedaan worden door een enkele job te vervangen voor een template. Als laagste niveau is het ook mogelijk om een task te vervangen door een template. Dit heeft eenzelfde werking als voorgaande stappen.
Met de templates is het vrij eenvoudig om bepaalde bouwblokken te ontwikkelen binnen de organisatie die vervolgens toegepast kunnen worden door de teams die deze benodigd hebben. Maar hoe stel ik deze templates beschikbaar?
Beschikbaar stellen van de templates
Templates kunnen op vele manieren toegepast worden, zo kun je de templates verwerken in de eigen repository van het team. Echter, vind ik dat de er een betere manier is om ‘standaard’ templates centraal beschikbaar te stellen binnen de organisatie, namelijk via een platform. Hierbij is het platform team verantwoordelijk is voor het onderhoud aan de templates. Andere teams zijn daardoor in staat om meer de focus te leggen op het ontwikkelen, verbeteren en onderhouden van de applicaties. Zij kunnen eenvoudig gebruikmaken van de templates om de applicaties te builden en deployen.
Op deze manier kunnen er bouwblokken ontwikkeld worden maar ook complete build en deploy pipelines waarbij de ontwikkelteams enkel bepaalde parameters hoeven mee te geven. Dit zorgt binnen de repositories van de teams voor een overzichtelijke pipeline.
Version management
De laatste stap is het bijhouden van deze pipelines. Ik ben zelf bekend met het gebruik maken van tagging op je centrale pipelines. Zo kunnen de teams referen naar een tag van de pipeline, bijvoorbeeld versie 2, 2.0, 2.0.0 waarbij deze tag weer refereert naar een commit ID. Zo kunnen er pull requests gemerged worden op master zonder dat de teams die gebruik maken van deze pipelines hinder ondervinden. Daarnaast dien je bij kleine wijzigingen zoveel mogelijk rekening te houden met de backwards compatibility zodat de ontwikkelteams niet steeds de pipelines moeten aanpassen om up to date te blijven.
Nadat er tags zijn aangemaakt op basis van de juiste commits kan er gerefereerd worden naar een tag in de resources van de pipeline.
resources:
resources:
repositories:
- repository: Global
type: git
name: Global/Global
ref: 'refs/tags/1'
Tijdens een pipeline run zie je vervolgens ook dat de desbetreffende tag versie gebruikt wordt:
Conclusie
Het toevoegen van templates binnen Azure maakt de workflow een stuk overzichtelijker. Ook helpt het beschikbaar stellen van templates via bijvoorbeeld een platform, andere collega’s. Doordat zij gebruik kunnen maken van een template hoeft niet iedereen nieuwe code te schrijven en voorkom je rommel en duplicates.
Door simpelweg te kijken welke stappen veel terugkomen, kun je de hele basis voor een template opzetten. Zo kun je het aanroepen in de basiscode, maar neemt het niet onnodig veel ruimte in beslag.