Terraform: Versnel innovatie – Deel 2

Blog Terraform
Blog Terraform en Azure

Introductie blogserie Terraform: Versnel innovatie

Welkom bij deel twee van het blogserie Terraform: Versnel innovatie. Waar we in het eerste deel zijn begonnen met Terraform lokaal vanaf je machine uit te voeren, gaan we in dit blog via een Azure DevOps project code “automatisch” laten doorvoeren. hierbij maken we gebruik van een Git Repository op Azure Repos.

Git is een versiebeheersysteem voor de code die je schrijft. De code wordt centraal opgeslagen in een zogenaamde Repository. Je bouwt tijdens het werken met Git een historie op van alle wijzigingen die je maakt. Door kleine stappen te maken, kun je gemakkelijk terug naar vorige versies en wijzigingen bekijken. Werk je in een team aan de code, dan is Git een veelgebruikte en gemakkelijk manier om samen te werken en elkaars wijzigingen in de code te zien.

Een Git repository maakt gebruik van zogenaamde branches. In deze branches staan bepaalde versies van de code opgeslagen. veelal zie je de branches master terugkomen met daarin de “productie” code en een develop branch met daarin de code waaraan actief ontwikkeld wordt. (door een of meerdere mensen). Tot slot kun je gebruik maken van losse “feature branches” waarin één specifieke feature wordt ontwikkeld. Elke wijziging die je aan een branch toevoegd wordt een commit genoemd. Deze bevat zowel de nieuwe code als een korte omschrijving wat de wijziging precies inhoudt. Het is vaak slim om kleine stappen te doen bij het ontwikkelen en daardoor veel kleine commits te maken. zo kun je gemakkelijk je vorige stappen terugleiden mocht er een fout zijn ingeslopen.

Wanneer je klaar bent met een branch (develop- of een featurebranch) dan kun je door middel van een merge, twee branches samenvoegen. de target branch krijgt dan alle aangepaste code van de source branch erbij.

In dit blog houden we het wat kleiner door alleen te werken met een master en develop branch. Daarnaast maken we in Azure Pipelines gebruik van zowel de pipeline als release om onze code uit te brengen naar “Productie”. De Azure pipeline is in dit verhaal de technische oplossing voor ons “continuous integration/continuous deployment” (CI/CD) proces.

De pipelines gaan we zo instellen dat de develop pipeline bij elke commit van code gaat draaien en zo onze resources uitrolt. Zo krijg je direct een tastbaar resultaat van de code die je schrijft en daardoor continue feedback. Zodra we tevreden zijn met de code in de develop branch, gaan we deze samenvoegen (merge) met de master branch. Die gaat op zijn beurt een release pipeline activeren die de productie omgeving uitrolt.

Genoeg uitleg, laten we beginnen!

Git

We beginnen met dit tweede deel van het blog met het downloaden en installeren van Git. We openen we website https://git-scm.com/ en klikken op de Download knop.

Klik op Uitvoeren om de download direct te starten zodra deze klaar is met downloaden.

Zodra de installatie start, accepteren we de standaard instellingen. Klik op Next om de waarde te accepteren en klik uiteindelijk op install.

Git is nu geïnstalleerd en we sluiten de installatie af.

Azure DevOps Project aanmaken

We gaan nu een Azure Project aanmaken. In dit project komen de pipelines en onze GIT repository te draaien. Een Azure Project draait altijd binnen een DevOps Organization. beide gaan we in de volgende stappen aanmaken.

We gaan naar https://dev.azure.com toe en klikken op Sign in to Azure DevOps. Log in met je Azure account welke we in het vorige blog hebben gebruikt.

Als je voor de eerste keer inlogt, wordt de DevOps Organisatie aangemaakt. Deze moet worden gekoppeld aan een Azure Tenant. Klik op Switch Directory om te controleren aan welke organisatie deze wordt gekoppeld.

Selecteer de juiste organisatie in de drop-down lijst en klik op Continue.

We selecteren een unieke naam voor de organisatie en kiezen de locatie waar deze komt te draaien. Voltooi de Captcha challenge en klik op Continue.

Nu is de organisatie aangemaakt en worden we direct gevraagd om een Azure DevOps project aan te maken. We geven ons project een naam en selecteren bij visibility voor Private. Tot slot klikken we op Create Project.

Het Azure DevOps project is nu aangemakt!

DevOps Service Connector aanmaken

Voordat we vanuit Azure DevOps daadwerkelijke resources op onze Azure omgeving kunnen aanmaken, moeten we een verbinding maken naar Azure toe. Dit doen we door middel van een Service Connector. Deze maakt een service principal aan in de Azure Tenant.

We beginnen door links onder op Project Settings te klikken. Vervolgens klikken we op Service Connections.

In het nieuwe scherm klikken we rechts boven op New service connection.

Vervolgens selecteren we Azure Resource Manager en klikken we op Next

Bij de keuze voor Authentication Method controleren we dat Service Principal (Automatic) geselecteerd staat en klikken we op Next.

In de laatste stap selecteren we onze subscription en geven we de service connector een naam. Deze naam hebben we later nodig bij het aanmaken van de Azure Pipeline. In het voorbeeld gebruik ik azure development. we klikken op Save om de connectie op te slaan.

Nu is er een Service Principal voor ons aangemaakt in de Azure AD tenant met een standaard naam. om deze te verduidelijken gaan we hem hernoemen. We klikken op de nieuw aangemaakt service connector.

Vervolgens klikken we op Manage Service Principal om naar de Azure portal te gaan. deze opent in een nieuw tabblad en gaat direct naar de service principal.

Hier klikken we op de Display Name waar we de naam kunnen aanpassen.

De naam passen we aan naar iets herkenbaars. bijvoorbeeld; Azure DevOps Service Principal. Klik op Save om de naam op te slaan.

Azure Repo aanmaken

Onze code gaan we opslaan in een GIT repository. Hier gaan we gebruik maken van een Azure Repo. Keer terug naar het tabblad van Azure DevOps. We klikken aan de linkerkant op Files onder het kopje Repos. De eerste keer krijgen we de vraag om een Repo te initializeren. Onderaan de pagina kiezen we in de dropdownlijst bij Add a .gitignore voor Terraform. tot slot klikken we op Initialize.

Een .gitignore is simpelweg een tekst bestand welke aan Git “vertelt” welke bestanden en mappen genegeerd mogen worden. Dit zijn vaak bestanden die enkel lokaal gebruikt worden, maar geen nut hebben om in het project op te slaan of wanneer je met een team werkt aan een project.

Nu we de Azure Repo hebben geinitialiseerd, gaan we een extra branch aanmaken. Onder het kopje Repos klikken we op Branches. Rechts boven klikken we op New Branch.

Er komt een scherm naar voren waar we de naam kunnen opgeven, Hier tikken we develop in en klikken op create.

De develop branch is nu aangemaakt. We gaan de develop branch de standaard branch maken waar we in werken. Dit doen we door achter de develop branch op de 3 punten te klikken en vervolgens te klikken op Set as default branch.

Nu dat klaar is, gaan we de repository klonen naar onze machine. Hierdoor kunnen wij lokaal onze bestanden aanmaken en aanpassen, om deze vervolgens te pushen naar de Repo. We klikken links op Files en vervolgens op de Clone knop.

In het scherm Clone Repository dat naar voren komt, klikken we op Clone in VS Code. Dit is het programma dat we in het eerste blog ook hebben gebruikt.

Als Windows de vraag stelt om over te schakelen naar een andere app, klikken we op Ja.

Ook in VS Code krijgen we de vraag of we een externe URL willen openen. Hier klikken we ook op Open.

Nu mogen we een locatie kiezen waar de kloon van de Git repository komt te draaien. In dit voorbeeld heb ik de map C:\GIT\Terraform aangemaakt en geselecteed. Browse naar de map en klik op Select Repository Location.

Aangezien dit de eerste keer is dat VS Code naar de DevOps Organisatie verbinding maakt, zal ik eenmalig moeten inloggen. VS Code maakt na het inloggen een Personal Access Token aan en gebruikt die om voortaan verbinding te maken.

Zodra je bent ingelogd en de GIT repository is gekloond, stelt VS Code de vraag of je deze repository direct wilt openen. Hier klikken we op Open.

Bestanden plaatsen

Als eerste stap controleren we of we de eerder aangemaakt develop branch geselecteerd is. Dit moet standaard zo zijn, omdat we de develop branch als standaard hebben ingesteld. Is het toch niet het geval, dan wisselen we door links onder op master te klikken en vervolgens in de drop down op develop te klikken. Deze knop geeft je direct de mogelijk andere branches te maken (bijvoorbeeld een feature branch) en te wisselen tussen verschillende branches.

Nu we op de develop branch zitten, maken we een map aan voor onze ARM-templates. Klik op New Folder en type vervolgens source\arm-templates\storageaccount in.

13

In deze map gaan we twee bestanden aanmaken. azuredeploy.json en azuredeploy.parameters.json. Hierin plakken we onderstaande code voorbeelden. Deze gaan we later aanroepen om een storage account aan te maken binnen Azure.

Klik rechts op de storageaccount map en kies voor New File. De eerste code is voor azuredeploy.json en plak daar onderstaande code in. Druk op de toetsencombinatie ctrl + s om het bestand op te slaan.

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "storageAccount_Name": {
            "type": "String"
        },
        "location": {
            "defaultValue": "westeurope",
            "type": "string"
        },
        "tags": {
            "defaultValue": {
                "Environment": "dev",
                "Purpose": "blog"
            },
            "type": "object"
        }
    },
    "variables": {},
    "resources": [
        {
            "type": "Microsoft.Storage/storageAccounts",
            "apiVersion": "2019-06-01",
            "name": "[parameters('storageAccount_Name')]",
            "location": "[parameters('location')]",
            "tags": "[parameters('tags')]",
            "sku": {
                "name": "Standard_LRS",
                "tier": "Standard"
            },
            "kind": "StorageV2",
            "properties": {
                "networkAcls": {
                    "bypass": "AzureServices",
                    "virtualNetworkRules": [],
                    "ipRules": [],
                    "defaultAction": "Allow"
                },
                "supportsHttpsTrafficOnly": true,
                "encryption": {
                    "services": {
                        "file": {
                            "keyType": "Account",
                            "enabled": true
                        },
                        "blob": {
                            "keyType": "Account",
                            "enabled": true
                        }
                    },
                    "keySource": "Microsoft.Storage"
                },
                "accessTier": "Hot"
            }
        }
    ]
}

Het volgende bestand is azuredeploy.parameters.json. Hier vervangen in we regel 6 (“value”: “storacc1200213”) de waarde tussen haakjes voor iets unieks.

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "storageAccount_Name": {
            "value": "storacc1200213"
        },
        "location": {
            "value": "westeurope"
        }
    }
}

Nu de bestanden zijn aangemaakt gaan we deze comitten naar de Azure Repo. Om te beginnen klikken we links op Source Control. bij elke commit dient een opmerking te worden gegeven. Zo krijg je een overzicht van de wijzigingen die gedaan zijn. Klik vervolgens achter beide bestanden op het + teken om ze klaar te zetten (te stagen).

Nu de bestanden klaar staan, voltooien we de commit door op ✓ te klikken.

De commit is nu geregistreerd voor de lokale versie van de Git repository. Deze gaan we nu pushen naar de Azure Repo door links onder op de Sync Changes knop te klikken. Hier staat 0↓ 1↑ zijn, (0 wijzigingen die online staan, maar niet lokaal en één wijziging die lokaal staat, maar niet online). Klik op OK om het synchroniseren te beginnen.

We wachten totdat de synchronisatie klaar is. Visual Studio Code zal de vraag stellen of er periodiek een Azure Fetch uitgevoerd moet worden. Druk op Yes. Hierdoor zal Visual Studio Code regelmatig controleren of er nog code wijzigingen zijn geweest op de online repository.

We keren terug naar het overzicht met de bestanden. Nu gaan we nog een bestand aanmaken en pushen naar Azure Repo. Dit keer maken we het bestand azure-pipelines.yml aan in de hoofdmap. Klik rechts op het lege vlak onder .gitignore, klik op New File en type de naam in. kopieer onderstaande code en plak deze in het nieuwe bestand.

Let op! Op regels 33 en 42 staan de velden azureSubscription met de naam ‘Azure Development’. Dit is de naam van de service connector die eerder hebben aangemaakt. vervang deze voor de naam die je hebt gebruikt.

druk op ctrl + s om het bestand op te slaan.

name: $(TeamProject)_$(Date:ddMMyyyy)_$(Rev:rr)

trigger:
 branches:
   include:
     - master
     - develop

variables:
  - name: resourcegroupName
    value: rg-dev-storageaccount
  - name: location
    value: westeurope
  - name: BuildVersion
    value: 'Build-$(Build.BuildNumber)'
  - name: storageAccountname
    value: 'storblog1200213'

stages:
  - stage: Develop
    displayName: Develop
    jobs:
      - job:
        condition: and(succeeded(), in(variables['Build.Reason'], 'IndividualCI', 'BatchedCI'))
        displayName: 'deploy develop'
        pool:
            vmImage: windows-2019
        continueOnError: false
        steps:
          - task: AzurePowerShell@5
            displayName: 'Azure Resource Group'
            inputs:
              azureSubscription: 'Azure Development'
              ScriptType: 'InlineScript'
              Inline: 'New-AzResourceGroup -Name $(resourcegroupName) -Location $(location) -tags @{Environment="development"; Purpose="blog"; Version="$(BuildVersion)"} -force'
              azurePowerShellVersion: 'LatestVersion'
              pwsh: true
          - task: AzureResourceManagerTemplateDeployment@3
            displayName: 'Deploy Storage Account'
            inputs:
              deploymentScope: 'Resource Group'
              azureResourceManagerConnection: 'Azure Development'
              subscriptionId: 'df2d437a-4249-4e47-9ec2-9440d8149525'
              action: 'Create Or Update Resource Group'
              resourceGroupName: '$(resourcegroupName)'
              location: '$(location)'
              templateLocation: 'Linked artifact'
              csmFile: '$(System.DefaultWorkingDirectory)/source/arm-templates/storageAccount/azuredeploy.json'
              csmParametersFile: '$(System.DefaultWorkingDirectory)/source/arm-templates/storageAccount/azuredeploy.parameters.json'
              overrideParameters: '-storageAccounts_Name "$(storageAccountname)" -location "$(location)" -tags {"Environment":"dev","Purpose":"blog","Version":"$(BuildVersion)"}'
              deploymentMode: 'Incremental'

Nu het besand is opgslagen, gaan we deze weer stagen, comitten en pushen naar Azure Repos net als dat we bij de twee ARM bestanden hebben gedaan. Klik op Source control, Voer een opmerking in voor de commit, klik op + achter azure-pipelines.yml. Druk daarna op ✓ om de bestanden te comitten en klik onderin op Sync Changes om het bestand door te zetten naar Github.

DevOps Pipeline aanmaken

Nu we een Azure DevOps project hebben, een gevulde Git Repository en de verbinding met Azure is opgezet, beginnen we met het aanmaken van onze eerste pipeline. We keren terug naar Azure DevOps en klikken op Pipelines en vervolgens op Create Pipeline.

In de eerste stap wordt de vraag gesteld waar onze code staat. Hier kiezen we voor Azure Repos.

Hier selecteren we onze repository. In mijn geval heet deze de naam Blog.

Azure pakt standaard het azure-pipelines.yml bestand waardoor de eerder aangemaakte pipeline direct wordt gevonden. We klikken op het pijltje achter run en klikken op Save. Heb je het bestand een andere naam gegeven, gebruik dan het pop-up venster dat naar voren komt om het betand te selecteren.

We slaan hem op zonder hem uit te voeren door op het pijltje achter Run te klikken, en te kiezen voor Save. In het volgende scherm klikken we rechts op de 3 puntjes en kiezen we Rename/Move.

Hier geven we de pipeline een andere naam, bijvoorbeeld Develop pipeline en klikken we op Save.

De eerste pipeline is nu een feit! Laten we kort de onderdelen doornemen.

Deze code bestaat uit diverse onderdelen

  • Trigger: Deze geeft aan wanneer de pipeline moet draaien. Door hier – develop en master bij te zetten draait deze alleen wanneer er nieuwe bestanden worden toegevoegd (commit) aan een van deze branches.
  • Variables: Dit zijn variabelen die we eenmalig defineren en verderop in de code kunnen hergebruiken. Zo kun je de code generiek maken en tijdens het uitvoeren van een specifieke pipeline aanpassen.
  • stages: met stages kun je de pipeline splitsen in verschillende logische stappen. bijvoorbeeld “Bouw deze applicatie”, “Draai tests op de applicatie”, “Publiceer naar pre-productie” enzovoort. Hier houden we het iets kleiner en hebben we twee stages.
  • condition: Bij de tweede stage hebben we een conditie toegevoegd. Hiermee kun je aangeven wanneer een bepaalde stage juist wel, of juist niet moet draaien.
  • Tasks: De taken zijn daadwerkelijk de acties die uitgevoerd gaan worden. In de step develop heb ik twee soorten taken toegevoegd.
    • inline script: Deze voert Powershell code uit die je in de pipeline invoert. In dit voorbeeld het aanmaken van een Azure Resourcegroup.
    • ARM template: Deze voert ons eerder aangemaakt ARM template uit (welke een storageaccount gaat aanmaken)

Op de Microsoft Docs site kun je een totaal overzicht vinden van de mogelijkheden voor een Azure Pipelines YAML bestand.

Nu gaan we de pipeline handmatig laten draaien, Hiervoor klikken we op Run Pipeline.

Vervolgens selecteren we de develop branch en klikken we op Run.

De pipeline gaat nu lopen. Door op Job te klikken kunnen we de details zien terwijl de pipeline draait.

En zodra de pipeline klaar is kunnen we per taak controleren wat er uitgevoerd is. Als overal groene vinkjes bij staat, is de job successvol verlopen. Mislukt er een taak, dan kun je hier details terugvinden waarom het niet lukt.

We openen nu de Azure website om te kijken of de resources ook daadwerkelijk zijn aangemaakt.

We hebben nu de pipeline handmatig gestart. En dat werkt, maar we hebben door middel van de trigger in te stellen de pipeline zo ingesteld dat hij automatisch gaat draaien zodra er bestanden aan de develop branch worden toegevoegd. Dat gaan we proberen!

We gaan een container toevoegen aan het storage account en een extra tag met een versienummer op de resource group. We keren terug naar Visual Studio Code en openen azuredeploy.json. Op regel 56 voegen we achter het } teken, de volgende code toe;

        ,{
            "type": "Microsoft.Storage/storageAccounts/blobServices/containers",
            "apiVersion": "2019-06-01",
            "name": "[concat(parameters('storageAccount_Name'), '/default/terraform')]",
            "dependsOn": [
                "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccount_Name'))]"
            ],
            "properties": {
                "publicAccess": "None"
            }
        }

Alternatief is het volledig vervangen van de bestaande code voor de onderstaande code. Hierbij heb ik de code voor de container reeds toegevoegd.

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "storageAccount_Name": {
            "type": "String"
        },
        "location": {
            "defaultValue": "westeurope",
            "type": "string"
        },
        "tags": {
            "defaultValue": {
                "Environment": "dev",
                "Purpose": "blog"
            },
            "type": "object"
        }
    },
    "variables": {},
    "resources": [
        {
            "type": "Microsoft.Storage/storageAccounts",
            "apiVersion": "2019-06-01",
            "name": "[parameters('storageAccount_Name')]",
            "location": "[parameters('location')]",
            "tags": "[parameters('tags')]",
            "sku": {
                "name": "Standard_LRS",
                "tier": "Standard"
            },
            "kind": "StorageV2",
            "properties": {
                "networkAcls": {
                    "bypass": "AzureServices",
                    "virtualNetworkRules": [],
                    "ipRules": [],
                    "defaultAction": "Allow"
                },
                "supportsHttpsTrafficOnly": true,
                "encryption": {
                    "services": {
                        "file": {
                            "keyType": "Account",
                            "enabled": true
                        },
                        "blob": {
                            "keyType": "Account",
                            "enabled": true
                        }
                    },
                    "keySource": "Microsoft.Storage"
                },
                "accessTier": "Hot"
            }
        },
        {
            "type": "Microsoft.Storage/storageAccounts/blobServices/containers",
            "apiVersion": "2019-06-01",
            "name": "[concat(parameters('storageAccount_Name'), '/default/terraform')]",
            "dependsOn": [
                "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccount_Name'))]"
            ],
            "properties": {
                "publicAccess": "None"
            }
        }
    ]
}

Na het aanpassen van de code, drukken we op ctrl + s om deze op te slaan. Vervolgens gaan we deze “committen”. Net als de vorige keren klikken we op Source Control, vullen we een opmerking in voor de nieuwe commit en drukken we op +.

Als laatste stap drukken we op V om de wijzigingen te comitten.

We sluiten azuredeploy.json af en openen vervolgens azure-pipelines.yml. Hier passen we de volgende regels aan om bij zowel de resource group als de storageacount een extra tag met de naam versionnumber toe te voegen.

Inline: 'New-AzResourceGroup -Name $(resourcegroupName) -Location $(location) -tags @{Environment="development"; Purpose="blog"; Version="$(BuildVersion)"} -force'
    overrideParameters: '-storageAccount_Name "$(storageAccountname)" -location "$(location)" -tags {"Environment":"dev","Purpose":"blog", "Version":"$(BuildVersion)"}'

Let op dat de regels nog op dezelfde identie staan en niet teveel naar voren of achter. Gebruik backspace of TAB om ze te verspringen als dat nodig is.

We drukken op ctrl + s om het bestand op te slaan. Vervolgens gaan we net als bij het azure-deploy.json bestand, de wijzigingen opslaan naar Git. Wederom klikken we op Source Control, vullen we een opmerking in voor de nieuwe commit en drukken we op + achter azure-pipelines.yml. vervolgens klikken we op V om de wijzigingen in de commit toe te voegen.

We hebben nu twee commits gedaan. Deze gaan we synchroniseren door links onder op de Synchroniseer knop te drukken. Hier staat nu 0 ↓ 2 ↑. Ondanks dat we twee commits gaan Pushen naar Azure Repo, zal de pipeline maar één keer starten en pakt hierbij de laatste commit.

We klikken op OK om de bestanden te pushen naar Github.

Vervolgens gaan we terug naar Azure DevOps en klikken we links op Pipelines. Uiteindelijk gaat de pipeline automatisch draaien zodra de bestanden zijn gepushed naar de repository.

Als we er op klikken zien we een overzicht van alle keren dat de pipeline heft gedraaid. De laatste versie is nog bezig of zal al voltooid zijn. Klik op het icoon in de kolom Stages.

Dat ziet er goed uit! Wederom controleren we de Azure Portal of de wijzigingen daar ook zichtbaar zijn. De Azure portal update niet altijd direct en moeten we misschien een paar keer verversen voordat de wijzigingen zichtbaar zijn.

Als we op de storage account klikken en vervolgens op containers, Kun je zien dat de nieuwe Terraform container is aangemaakt.

De pipeline is nu zo ingesteld dat we aanpassingen kunnen blijven doen aan de azuredeploy.json. Wanneer we deze pushen naar Azure Repo, zal de pipeline gaan draaien en deze uitvoeren naar Azure toe.

Wanneer we extra arm-templates willen toevoegen aan de pipeline, zullen we deze als extra Task moeten defineren in de azure-pipelines.yml.

Extra stage toevoegen aan pipeline

Nu we een development pipeline hebben aangemaakt waarmee we onze test omgeving automatisch uitrollen, gaan we er een maken voor onze “productie”. Dit doen we door gebruik te maken van een release pipeline. Om die te laten werken, moeten we zogenaamde “artifacts” maken welke we kunnen uitrollen. Bouw je bijvoorbeeld apps, dan kun je deze laten compileren en als artifact klaarzetten voor de release pipeline. In dit voorbeeld worden de artifacts simpelweg een kopie van de ARM-templates.

We beginnen door terugte keren naar VS Code en aan de bestaande azure-pipelines.yml een extra stage toe te voegen. We openen dit bestand in Visual Studio Code en voegen onderstaande code toe vanaf regel 52

  - stage: production
    condition: and(ne(variables['Build.Reason'], 'PullRequest'), eq(variables['Build.SourceBranch'], 'refs/heads/master'))
    displayName: production
    jobs:
      - job:
        displayName: 'Prepare Production'
        pool:
            vmImage: windows-2019
        continueOnError: false
        steps:
        - task: CopyFiles@2
          inputs:
            SourceFolder: 'source'
            Contents: '**'
            TargetFolder: '$(Build.ArtifactStagingDirectory)'
        - task: PublishBuildArtifacts@1
          inputs:
            PathtoPublish: '$(Build.ArtifactStagingDirectory)'
            ArtifactName: 'drop'
            publishLocation: 'Container'

Let met plakken goed op de indentie van de code. Dit verspringt in sommige gevallen. Er moet twee spaties voor het woord ‘– stage‘ staan.

Net als de vorige keren, gaan we deze wijziging opslaan met Ctrl + S, Gaan we naar Source Control aan de linkerzijde, voegen we een opmerking toe en drukken we op de + achter het aangepaste bestand azure-pipelines.yml. Daarna klikken we op ✓ om de commit te voltooien.

Na de commit klikken we links onder op 0↓ 1↑ om te synchroniseren.

Onze pipeline gaat nu automatisch draaien.

Er is nu een tweede stage zichtbaar. Deze zal door de ingestelde condition niet draaien. We gaan nu een release pipeline aanmaken.

Aanmaken release pipeline

In één van de vorige stappen hebben we een pipeline opgezet met behulp van een yaml bestand. Deze hebben we ingericht voor de development van onze “develop omgeving”.

Nu gaan we een release-pipeline aanmaken voor onze “productie” omgeving. Binnen Azure DevOps klikken we op Releases en vervolgens op New Pipeline.

Hier klikken we op Empty Job om met een lege template te starten.

We vullen een stage naam in en klikken daarna bij Artifacts op + Add.

Bij Project selecteren we Blog en bij Source de eerder aangemaakt Pipeline. Achter Alias typen we Deployment (Of een andere alias). Klik vervolgens op Add.

Nu stellen we in dat de release pipeline automatisch gaat lopen. We klikken op de Continuous deployment trigger knop.

We zetten de optie achter Continuous Deployment trigger op Enabled, klikken op Add en selecteren de master branch achter Include. Daarna klikken we op het kruisje

Als dat is gedaan gaan we een aantal stappen toeveogen. We klikken onder Deployment op 1 job 0 task om een taak toe te voegen.

Achter Agent job klikken we op het + teken en zoeken als eerste op Powershell Azure en kiezen voor Add achter de taak Azure Powershell om de taak toe te voegen.

Vervolgens zoeken we op arm. Bij de zoekresultaten komt nu ARM template deployment naar voren. ook hier klikken we op Add en voegen we deze toe aan de taaklijst.

Als dat is gedaan klikken we onder Agent Job op de Azure Powershell script taak. Aan rechterkant kunnen we deze taak aanpassen. Hier voeren we een naam in, kiezen we de Azure Subscription waar we deze op gaan uitvoeren. Controleer of Inline Script aangevinkt staat. In het kader kunnen we ons Powershell script defineren. Vul onderstaande code in.

New-AzResourceGroup -Name "$(resourcegroup)" -Location "$(location)" -tags @{Environment="production"; Purpose="blog";Version="$(Release.ReleaseName)"} -force

We scrollen iets naar onder en selecteren Latest installed version onder Azure Powershell Version.

Nu die taak klaar is selecteren we de tweede taak: ARM Template deployment. Pas hier de naam aan van de taak en kies onder Deployment scope voor Resource Group. Onder Azure Resource Manager connection kiezen we de Service connector (Azure Deployment) en bij de dropdown Subscription kies je je subscription.

Onder Action kiezen we Create or update resource group. Bij het veld Resource group vullen we de variabele $(resourcegroup) in. bij locatie vullen we de volgende variabele $(location) in.

Achter Template en Template parameter moeten we de artifacts invoeren die uitgevoerd moeten worden. Dit zijn de twee ARM-templates. Aangezien de pipeline nog geen Artifacts heeft gemaakt, kunnen we deze niet selecteren door middel van de 3 punten. Vul de volgende gegevens in.

$(System.DefaultWorkingDirectory)/Deployment/drop/arm-templates/storageaccount/azuredeploy.json
$(System.DefaultWorkingDirectory)/Deployment/drop/arm-templates/storageaccount/azuredeploy.parameters.json

Het laatste wat we hier gaan invullen is het kader override parameters. Hier vullen we het volgende in.

-storageAccount_Name "$(storageaccount)" -location "$(location)" -tags {"Environment":"prd","Purpose":"blog","Version":"$(Release.ReleaseName)"}

Zodra die is ingevuld, gaan we de parameters aanmaken welke we hebben gebruikt. We klikken bovenin op Variables.

We drukken 3 keer op + Add voor de variabelen en maken de volgende variabelen aan.

  • resourcegroup: rg-prd-storageaccount
  • storageaccount: *Unieke naam*
  • location: westeurope

Zodra deze zijn angemaakt kliken op op Save om de release pipeline op te slaan.

Geef een opmerking op en klik op Ok.

Om de naam van de pipeline we wijzigen klikken we boven op New Release Pipeline en vullen we een nieuwe naam in. Klik nogmaals op Save om de nieuwe naam op te slaan.

Geef wederom een naam op en klik op Ok.

Develop naar Master mergen

Nu ook de release pipeline is aangemaakt, gaan we deze laten draaien. Dit doen we door onze develop branch samen te voegen met de master branch. Wanneer dat is uitgevoerd, gaat de tweede stage uit de pipeline lopen waardoor een artifact wordt aangemaakt. Zodra de artifact is gemaakt gaat de release pipeline op zijn beurt draaien.

Om dit uit te voeren gaan we binnen Azure DevOps naar Repos en kiezen we Pull Requests.

In dit scherm klikken we op New Pull Request.

Zorg dat boven in aan de linkerzijde develop staat en rechts master. Hiermee geven we aan dat we develop gaan samenvoegen naar master.

We geven een titel van de Pull-Request op en klikken vervolgens op “Add commit messages”. Nu zien we alle eerder aangemaakte commit messages verschijnen in het “description” veld. Tot slot klikken we op Create.

Er wordt gecontroleerd of er geen Merge conflicten zijn. Zodra die controle is voltooid drukken we rechts boven op Complete.

In het nieuwe venster klikken we rechts onder op Complete Merge.

De twee branches zijn nu samengevoegd. Alle bestanden die we in de develop branch hebben staan, staan nu ook in de master branch.

Nu zal door de eerder gedefinieerde trigger de pipeline starten voor de master branch. Dit controleren we door links op Pipelines te klikken. vervolgens klikken we op de pipeline naam.

De tweede stage zal nog draaien of al klaar zijn. We klikken op het tweede icoon om naar de details van de stage te gaan.

Als alles goed is verlopen, zal je zien dat er een artifacts is aangemaakt. Door hier op te klikken kunnen we zien wat er precies in de artifact zit.

Als we alles uitklappen zien we onze bestanden weer terug.

Aangezien de artifact nu is aangemaakt, moet de release pipeline gestart zijn. dit controleren we door links op Releases te klikken.

Door op de naam van de Release te klikken kunnen we de details bekijken. In mijn voorbeeld draait deze nog.

Door op het icoon te klikken waar In Progress of Succeeded staat kunnen we de details zien van de release.

Alle taken die we gedefinieerd hebben kunnen we hier bekijken. ze zijn in dit voorbeeld goed verlopen.

De laatste controle die we doen is de Azure portal openen en kijken of de resources daadwerkelijk zijn aangemaakt.

Dat is gelukt! nu is de release pipeline zo ingesteld dat hij deze gaat draaien zodra bestanden van de develop naar master worden samengevoegd.

Nu hebben we Azure DevOps klaar staan en maken we door middel van resource groepen storage accounts aan. Deze gaan we in het volgende Blog gebruiken als plek voor de Terraform state files en gaan we Terraform integreren in de Azure Pipelines.

Auteur: Léon Boers

Léon Boers is Microsoft cloud consultant bij 3fifty.

× Stel jouw vraag direct via Whatsapp Available from 09:00 to 17:00