In mijn vorige blog ben ik ingegaan op het realiseren van een bestandsoverdracht integratie middels Azure Logic Apps. Een andere methode om dit te realiseren is middels Azure Functions. In dit laatste deel van mijn Azure-reeks licht ik dan ook het stappenplan toe om een bestandoverdracht in de cloud te realiseren met Azure Functions. Verder sta ik nog kort stil bij mijn persoonlijke voorkeur voor Azure Logic Apps of Azure Functions.
Zoals ik in deel twee van deze Azure blogreeks beschreef, is het functioneel ontwerp van de Azure Functions oplossing bijna identiek aan die van Azure Logic Apps. Het grote verschil is dat Azure Logic Apps workflow-gebaseerd is en Azure Functions op code-gebaseerd. Voor alle voor- en nadelen van beide opties verwijs ik je dan ook graag terug naar deze vorige blog.
Azure Logic Apps Solution
Azure Functions Solution
Wat zijn Azure Functions?
Azure Functions is een serverloze oplossing waarmee je minder code hoeft te schrijven, minder infrastructuur hoeft te onderhouden en kunt besparen op kosten. In plaats van dat je je zorgen moet maken over het implementeren en onderhouden van servers, biedt de cloudinfrastructuur alle bijgewerkte resources die nodig zijn om toepassingen uit te voeren. Dit betekent dat jij je alleen hoeft te richten op het schrijven van de code; Azure Functions doet de rest.
Een functie is het primaire concept in Azure Functions en bevat twee belangrijke onderdelen. Allereerst de code die in verschillende talen kan worden geschreven en daarnaast een configuratiebestand (function.json). Dit bestand definieert de trigger, bindingen en andere configuratie-instellingen van de functie. Elke functie kan slechts één trigger hebben. De runtime maakt gebruik van dit configuratiebestand om te bepalen welke gebeurtenissen bewaakt moeten worden, hoe gegevens doorgegeven dienen te worden en hoe deze na de uitvoering van een functie retourneren.
Een functie-app biedt een uitvoeringscontext in Azure, waarin de functies worden uitgevoerd. Dit is dus de eenheid van implementatie en beheer voor de functies. Een functie-app bestaat uit één of meerdere afzonderlijke functies die samen worden beheerd, geïmplementeerd en geschaald. Een paar voordelen aan Azure Functions is dat alle functies in een functie-app hetzelfde prijsplan (App Service plan), dezelfde implementatiemethode en dezelfde runtime versie delen. In principe kan je een functie-app zien als een manier om je functies te organiseren en gezamenlijk te beheren.
Naast Azure Functions is er ook de mogelijkheid om stateful functies te schrijven. Dit is mogelijk met behulp van Azure Durable Functions. In deze blog zal ik daar niet verder op in gaan.
Azure Functions implementatie
Zoals te zien is in de afbeeldingen van beide solutions is het merendeel van de bouwblokken identiek aan elkaar en verschilt alleen de applicatielogica (Logic Apps vs. Functions). Je zult echter zien dat het aantal stappen om tot een identieke oplossing te komen aanzienlijk groter is in Azure Functions dan met de Logic Apps-oplossing. Hieronder schets ik het stappenplan in Azure Functions.
- Storage account aanmaken
Deze stap is vergelijkbaar met stap 1 binnen Azure Logic Apps en is bedoeld als opslag voor de inkomende bestanden in Azure Blob Storage. Verder dient het ook als opslag voor de Azure Functions die we gaan implementeren. Voor deze case maak ik gebruik van één storage account, maar in een productie-omgeving is het raadzaam om hiervoor verschillende storage accounts te gebruiken. Dit omdat het andere doelen dient en waarschijnlijk ook andere schaalbaarheidseisen stelt.
Vul de gegevens van het Storage Account in, zoals weergegeven in onderstaande afbeelding. Voor deze demo gebruik ik de goedkoopste instellingen, dus de dichtstbijzijnde regio met de laagste latency, lokale redundantie en standaardprestaties.
Vervolgens navigeer je naar ‘Containers’ binnen het zojuist aangemaakte storage account en geef je de container een ‘Name’ en een ‘Public access level’.
2. Creëren van een functie-app
Zoals hierboven uitgelegd, hebben we een functie-app nodig waar de functie in kan draaien en wat de uitvoeringscontext is van de functie in Azure. Om dit te realiseren, vul je de gegevens van de functie-app in zoals weergegeven in onderstaande afbeelding. We kiezen hier voor .NET 3.1 als runtime stack.
Vervolgens vul je bij het kopje ‘Hosting’ de naam van het Storage account in die je hierboven hebt aangemaakt. Als plan type kiezen we voor ‘Consumption (Serverless)’. De Application Insights monitoring zetten we ook aan om de applicatie logging van onze Functions te kunnen inzien.
Als je nu naar je ‘Resource Group’ navigeert, zie je het Storage account en de Function App verschijnen. Dit is namelijk de plek waarin je de verschillende onderdelen hebt aangemaakt. Overigens is de Application Insight optioneel, maar in deze casus heb ik deze wel aangevinkt. Wat je minimaal nodig hebt is een Storage account en een App Service plan.
In de volgende stappen ga ik de Azure Functions code implementeren in Visual Studio Code. Het is echter ook mogelijk om hiervoor ‘Visual Studio 2019’ te gebruiken.
3. Azure Functions project aanmaken in Visual Studio Code
Alvorens je Azure Functions kan gebruiken, dienen er enkele tools geïnstalleerd te worden naast Visual Studio Code. Dit zijn:
3a. Initialiseren Azure Function project
In deze stap maken we het basis Visual Studio project aan voor de Azure Function die we gaan ontwikkelen. Daarvoor open of maak je een folder vanuit Visual Studio (bijvoorbeeld C:\azure\azure-functions). Vervolgens open je een PowerShell terminal venster in Visual Studio via ‘View -> Terminal’ en voer je het onderstaande commando uit. Kies hierbij voor ‘dotnet’ waarna het project zal worden geïnitialiseerd.
3b. Configureren toegang tot Storage account vanuit de Azure Function
Om vanuit de Azure Function de inputbestanden te kunnen benaderen, is er toegang nodig vanuit de Azure Function richting het storage account. Eén van de opties om dit te realiseren is middels het opnemen van de ‘connection string’ van het storage account in het local.settings.json bestand van de Azure Function.
Open de Access Keys vanuit het aangemaakte storage account en kopieer de connection string.
Open het local.settings.json bestand en wijzig de waarde van de AzureWebJobsStorage setting naar de waarde van de connection string.
3c. Aanmaken van een EventGrid Triggered Function
Open de Visual Studio terminal en creëer een nieuwe functie met het ‘func new’ commando en kies voor het EventGridTrigger template.
Na het kiezen van een functienaam (e.g. FileTransfer) zal de code worden gegenereerd welke een EventGrid event kan ontvangen en loggen.
Vervolgens deploy je de functie naar de functie-app middels het uitvoeren van het onderstaande commando in de terminal.
Hierna kan je de functie zien in de Azure portal in je functie-app.
4. Aanmaken van een Event Subscription
Navigeer naar de Azure portal en kies de functie-app die je hebt aangemaakt en selecteer ‘FileTransfer’.
Selecteer ‘Integration’ en kies vervolgens de EventGrid Trigger en klik op ‘Create Event Grid subscription’.
In deze stap wordt de EventGrid Trigger geconfigureerd voor de gemaakte ‘FileTransfer’ functie.
Gebruik de onderstaande instellingen voor het maken van de Event Subscription. Als onderdeel van de Event Subscription creatie moet ook een Topic worden aangemaakt.
Ga naar het tabblad ‘Filters’, activeer subject filtering en specificeer de input-share folder van het Storage account.
In het kort zeggen we hiermee dat we op een specifieke container (input-share) binnen het Storage account luisteren naar BlobCreated events. Als dat gebeurt wordt de functie gestart. Klik vervolgens op ‘Create’ om de Event Subscription af te ronden.
5. Azure Function code uitbreiden om bestand in te lezen en te versturen naar SharePoint
File ophalen uit Azure Blob Storage
We gebruiken voor het ophalen van het bestand uit Azure Blob Storage de Azure Storage Blobs client library for .NET. We kiezen er hier voor om het bestand in het geheugen te bewaren.
File versturen naar SharePoint folder
Voor het versturen van files richting SharePoint zijn verschillende opties mogelijk om dit te realiseren, zoals CSOM (SharePoint Client Object Modal) of PnP Core SDK. Beide libraries hebben dan weer andere packages nodig en vereisen een andere .NET framework SDK. In deze case kiezen we voor de CSOM-oplossing. Voor het versturen van het bestand richting SharePoint maak ik specifiek gebruik van de FileCreationInformation Class.
Vervang de standaard gegenereerde Event Triggered functie (FileTransfer) code door de onderstaande code. Deze code haalt dus het bestand op uit de ‘input-share’ van Azure Blob Storage en verstuurt deze naar de gewenste SharePoint-locatie.
6. Controleren en testen van de Azure Function-integratie
Nu kunnen we een bestand plaatsen op de ‘input-share’ container in het Storage account. Hoe berichten te plaatsen op het Storage account is reeds beschreven in mijn vorige blog t.a.v. Logic Apps. Na het plaatsen van het bericht op de ‘input-share’ zal de ‘FileTransfer’ functie worden gestart en uitgevoerd met als resultaat dat het bestand in de gewenste SharePoint folder verschijnt.
Met behulp van de ‘Monitor’-optie binnen de Azure-portal kun je de status van de aanroepen bekijken alsmede de gedetailleerde functie logging uit je code.
Voorkeur Azure Logic Apps of Azure Functions
Zoals je misschien zelf al hebt geconcludeerd, als je ook mijn vorige blog hebt gelezen over de uitwerking van de case met Azure Logic Apps, is het implementeren van een basisintegratie sneller en gemakkelijker uitgevoerd met Azure Logic Apps. Dit komt met name doordat de meest voor de hand liggende connectoren al aanwezig zijn binnen Logic Apps en je deze alleen maar hoeft te configureren. Bij Azure Functions daarentegen dien je zelf uit te zoeken hoe je met een bepaalde service of back-end wilt communiceren. Dit kan behoorlijk veel tijd kosten in sommige gevallen.
Een voorbeeld van wat er bij deze use-case speelde, was dat het bestand naar een SharePoint folder moest worden verstuurd. Via Logic Apps is dit in een paar minuten gerealiseerd door enkele dropdown boxen in te vullen in de workflow designer. Bovendien worden deze automatisch ingevuld op basis van je eigen Azure AD-accountgegevens. Bij het uitzoeken hoe je dit met een Azure Function moet realiseren, kom je al snel verschillende opties tegen. Ga je de CSOM library gebruiken of toch liever de PnP Core SDK? Kortom, met Azure Functions begeef je je al snel in ontwikkelaarsland wat voor de meeste integraties ongewenst en onnodig is. In het geval van complexe cases waarvoor geen standaard connectoren beschikbaar zijn, is Azure Functions een prima alternatief. Je hebt dan veel meer vrijheden hebt om de meest uiteenlopende libraries te gebruiken.
Dan zijn we nu aan het einde gekomen van mijn vierdelige Azure-blog. Ik hoop dat ik jullie inzicht heb kunnen bieden in wat Azure in hoofdlijnen is, waarom het juist nu interessant is, welke integratie opties er zijn en hoe deze in de basis werken.
Wil je meer weten over de mogelijkheden die Microsoft Azure jou kan bieden? Neem dan gerust contact op!