Your web browser is out of date. Update your browser for more security, speed and the best experience on this site.

Microsoft .NET-applicaties op AWS cloud laten draaien

Wie vertrouwd is met Microsoft .NET-applicaties, dweept ongetwijfeld bij Azure wanneer het op cloudcomputing aankomen. Als er iemand weet hoe je een .NET-applicatie moet runnen, dan zal het Microsoft toch wel zijn? Rob van Pamel, .NET developer sinds 2007, was ook zo’n Azure-fanboy. Toch kwam daar in 2015 verandering in, vertelde Rob in een keynote aan zijn collega’s.

Deel dit artikel
.NET

‘Ons team ging een nieuw ticketing project opstarten. Doordat het een greenfield project was konden we alles kiezen, zolang het maar kostenefficiënt was. Een van de consultants stelde AWS voor, waarna we ons zijn gaan verdiepen om een goede afweging te kunnen maken.'

Rob Van Pamel, .NET solution architect

De keuze om .NET en AWS te combineren mag dan misschien niet voor de hand liggen, er zijn wel een aantal belangrijke factoren in het voordeel van de Amazon Web Services. Een grote waaier topklanten, van Netflix tot de NASA, zoeken steeds de grenzen van de technologie op, waardoor ze steeds verbetert. Daar profiteren alle gebruikers van AWS van: meer dan 90% van de nieuwe features ontstaat uit directe feedback van hun klanten.

Die features en producten zijn zeer uitgebreid en focussen onder andere op berekeningen, opslag en databases. Ze zijn ook bruikbaar voor mobiele of IoT-toepassingen en zijn, zo ontdekte Rob, beter dan die van Microsoft. ‘Amazon is een van de belangrijkste Corporate Sponsors van de .NET Foundation. AWS heeft een betrokken community, met developer advocates en actieve user groups.’

Schermafbeelding 2022 07 27 om 10 10 40

Hoe begin je eraan?

Een account op AWS aanmaken is gratis, je betaalt vervolgens afhankelijk van de services die je wil gebruiken. Eenmaal je die eerste stap doorlopen hebt, kom je in de AWS Management Console terecht. Dit is je thuisbasis waar je alle services terugvindt.

In zijn keynote gaf Rob ook een demonstratie waarin hij van een lokale .NET-applicatie een cloud-native applicatie maakte. Dat deed hij aan de hand van vijf verschillende pistes die je als ontwikkelaar kan volgen wanneer je gebruik wil maken van AWS. De ene manier is al wat eenvoudiger dan de andere, afhankelijk van hoe ver je met je applicatie staat. Daarvoor zoomde hij in op een aantal tools die bij zo’n migratie van pas komen, zoals de API Gateway, Serverless Lambda-functies en de NoSQL DynamoDB.

Doordat veel developers Visual Studio gebruiken ontwikkelde Amazon de AWS Toolkit. Deze plugin maakt de migratie makkelijker en biedt verschillende services, producten en project templates aan. De AWS Toolkit is beschikbaar voor Visual Studio, Visual Studio Code en Rider.


Stap 1: Data van een lokale machine migreren naar een RDS-database in de cloud

In zijn eerste demonstratie toonde Rob hoe je de applicatie aanpast om gebruik te laten maken van een database op een RDS Server in plaats van een on-premise database server. ‘Ik had al vermeld dat AWS open-minded is: voor elke grote database vendor kan je ook in RDS een database variant laten draaien’, zei hij. ‘Het runnen van een RDS databank in plaats van een on-premise database is vooral interessant voor bedrijven die de operationele workload willen verminderen. Zo hoef je bij RDS niet wakker te liggen van operationele taken zoals patchen of het nemen van backups. AWS regelt dit voortaan voor jou!’

In de AWS Explorer kan je eenvoudig een nieuwe Instance van een RDS Database server lanceren. Je hebt er keuze uit verschillende database engines, van MySQL tot Oracle. Amazon heeft ook zelf een eigen engine, Amazon Aurora, waar zelfs een serverless versie,van bestaat. Nadat je een Instance type hebt gekozen, geef je de database een identifier en credentials. Die maak je vervolgens publiek beschikbaar en je wijst de correcte security groep toe. Op dit moment draait je database in de cloud en is deze klaar voor gebruik!

Voordat onze applicatie onze database kan gebruiken, moet de juiste structuur aangemaakt worden. Via de Azure Data Studio maken we onze database op de nieuwe RDS server aan. Aangezien onze applicatie gebruik maakt van Entity Framework, is het voldoende om de Entity Framework database migraties uit te voeren. Hiervoor hoeven we enkel de connection string aan te passen en het EF commando Database Update uit te voeren.

Stap 2: De API naar de cloud migreren

Op dit punt steekt onze database in de cloud, de volgende stap is onze API te verplaatsen van on-premise naar de cloud. Het voordeel hiervan is dat je in cloud makkelijk kan opschalen door bestaande instanties te upgraden. Daarnaast kan je ook makkelijker uitschalen door nieuwe instanties toe te voegen. Zo kan je je servercapaciteit aanpassen aan je huidige workload, en niet op de workload die je binnen een aantal jaar verwacht te hebben. Dat geldt ook andersom: wanneer je minder workload hebt kan je perfect down- of inschalen. Probeer dit maar eens on-premise!

Naast de verschillende memory-, cpu- en netwerkmogelijkheden binnen EC2 heb je ook verschillende classificaties. Heb je een workload die veel memory vereist, dan kan je kiezen voor een EC2-type met een instance classificatie die daar op specialiseert, in dit geval de R versie. Heeft je applicatie veel CPU compute, kies dan voor de C-specifieke EC2 classificaties.

Bij die migratie van on-premise naar cloud komen verschillende termen kijken. De Amazon Simple Storage Service, kortweg S3, is een zeer kwalitatieve object storage service die je kan vergelijken met de Blob Storage in Azure. Je kan S3 gebruiken voor eender welke blob storage tot het hosten van je single page applications in combinatie met Cloudfront, maar ook voor het bouwen van data lakes.

Nog zo’n begrip is EC2, voluit Amazon Elastic Compute Cloud. Deze webservice laat toe om computing capaciteit op een eenvoudige manier te configureren in de cloud. Zo worden bij gebruik virtual machines opgestart die gebruik maken van Windows of Linux in de cloud.

Om onze applicatie naar EC2 te brengen, maken we gebruik van de orchestrator Elastic Beanstalk. Deze orchestrator zal in combinatie met S3 onze applicatie deployen op EC2.

Op dit ogenblik maakt onze applicatie nog gebruik van een secret file voor username en password. Omdat deze secret file niet beschikbaar is in de cloud, zullen we de user ID en het paswoord tijdelijk toevoegen aan de app-instellingen. Later zal dit rechtgezet worden met een andere service. Eenmaal je het juiste instance type hebt ingesteld, en alle gegevens zijn ingevoerd, kan je je applicatie deployen naar Elastic Beanstalk. Je .NET-applicatie zal nu gepubliceerd worden via.NET publish-commando. Als alles gezipt is, zal het deze data verplaatsen naar S3. Van daaruit zal ze data gebruiken om je applicatie op te starten in een virtual machine.

In de console, zo’n beetje de thuishaven van alles wat je in AWS doet, vind je ook Elastic Beanstalk terug. Daar vind je je applicatie en alle bijbehorende gegevens. Telkens je iets uploadt, wordt er een nieuwe versie aangemaakt. Om onze user-id en paswoord veilig te bewaren, gebruiken we de Parameter store. Deze laat toe om gegevens op een veilige locatie te bewaren.

Die vind je in de Systems Manager van je console. Hier kan je verschillende parameters aanmaken, zoals de User ID of paswoord. Wanneer dat gebeurd is, kan je ze gebruiken in je applicatie door in je program file de configuratie te wijzigen zodat deze de Parameter Store uitleest. Vervolgens kan je opnieuw deployen richting Elastic Beanstalk. De Systems Manager koppelen is een kwestie van een paar muisklikken: de juiste prefix en configuratie toevoegen aan je applicatie.


Stap 3: Containerize je API

Een andere optie is gebruik maken van containers voor onze applicatie. ‘Door je API te containerizen heeft je applicatie een snellere spin up-tijd en zullen resources beter gebruikt worden’, zei Rob. ‘Een ander voordeel is dat onze applicatie minder afhankelijk is van bepaalde operating systems en hun configuratie. Hoe vaak valt het wel niet voor dat een applicatie zich op de productieomgeving anders gedraagt dan in de testomgeving, omdat die ene parameter bij de test anders ingesteld is dan in de productie? Door gebruik te maken van containers kunnen we dit soort risico’s tot het minimum beperken.’

Om onze applicatie om te bouwen hebben we minimaal 2 functies nodig: Containerregistratie en container orchestratie. Die eerste heet AWS ECR, of languit Elastic Container Registry. Je kan ze vergelijken met bijvoorbeeld Docker Hub, maar dan voor private docker images.

De tweede functie heet AWS ECS, wat voor Elastic Container Service staat. Hiermee orchestreer je je containers: je laat ze starten, herstarten en opschalen. AWS ECS heeft drie belangrijke onderdelen: Tasks, Services en Clusters.

Met een Task kan je een docker container opstarten op basis van een Task-definitie, een Service is een geautomatiseerde manier om dat te doen en ze vervolgens te schalen. Clusters ten slotte zijn bundels services en tasks. De meeste applicaties draaien prima op ECS, maar in de iets duurdere Kubernetes Service AWS EKS heb je nog meer configuratie mogelijkheden waardoor het nog net iets krachtiger is.

Bij het migreren van onze applicatie naar container instances voeg je voor je applicatie een load balancer toe. Deze zal voor de applicatie staan, zodat het uitschalen naar meerdere instanties ook onmiddellijk ondersteunt wordt. Een docker container aanmaken is standaard beschikbaar in Visual Studio. In de gegenereerde Dockerfile staat beschreven hoe de applicatie gebouwd moet worden. Eenmaal de dockerfile toegevoegd is, kan je de container op AWS publiceren. In de bijhorende wizard geef je aan of het om een Service of een Scheduled Task gaat.

Ook de Load Balancer creëren gebeurt in de wizard waar je de de juiste instellingen en permissies invoert. Bij het publiceren van je applicatie zal de toolkit deze zippen en je container creëren. Er wordt een image voor je container aangemaakt en naar AWS ECR geüpload, waarna de ECS-cluster geconfigureerd wordt. De Services en Tasks die je invoerde zullen ook aangemaakt worden. Hierna ben je klaar!

Op je AWS Management Console zul je zien dat dingen veranderd zijn. In je Elastic Container Service zie je bijvoorbeeld dat een nieuwe Service gedefinieerd is. In de Log Configuration zal je een aantal defaults zien die werden toegepast. Die Log Configuration is verbonden met CloudWatch, de log provider voor je applicatie. Iedere output die je applicatie maakt wordt doorgestuurd naar je logs op CloudWatch. Het is een zeer eenvoudige manier om te kijken wat je applicatie doet.


Stap 4: Migreren naar serverless in de cloud

Op dit moment draait een container, verbonden met een relational database, in de cloud. De volgende stap is serverless computing. Dankzij AWS Lambda heb je een snellere boot time en hoef je niet langer wakker te liggen van containers of het updaten van security patches voor .NET Core. In dit scenario trigger elk event je applicatie. Daarom heb je nood aan bijvoorbeeld een API gateway die de AWS Lambda kan triggeren.

Je betaalt enkel voor iedere milliseconde dat de applicatie draait en je kan ongelimiteerd schalen. Het nadeel aan deze oplossing is dan weer dat het moeilijker is om te testen, doordat je veel meer bewegende delen in de architectuur van je applicatie hebt. ‘Je applicatie wordt ook schaalbaarder doordat je enkel de functies deployt. Als er fouten optreden op je container, zijn die dus beter geïsoleerd van de rest van je applicatie.’

Om je applicatie te migreren zul je er een API gateway voor moeten plaatsen, zodat de Lambda functie beschikbaar is voor de front end applicatie. De makkelijkste manier om de applicatie om te bouwen is door een nieuw Serverless project te beginnen. De toolkit heeft heel wat templates die je hiervoor kan gebruiken. Rob gebruikte in zijn voorbeeld de .NET API. Die zal een Lambda Entry Point en een serverless template toevoegen, die je kan kopiëren naar je applicatie.

Door het Lambda Entry Point dezelfde configuratie te geven als je programma, kan het alle API calls van je API gateway opvangen en doorsturen naar je applicatie. Dat doe je door in de Serverless Template de handler te wijzigen, zodat die voortaan weet waar hij naar je applicatie moet zoeken. Geeft vervolgens de juiste policies in en past het projecttype aan. Zo kan het als een Lambda functie gepubliceerd worden. Wanneer dit gebeurd is kan je publiceren naar AWS Lambda en heb je een serverless applicatie!


Stap 5: Gebruik cloud native storage.

Als je met een heel schaalbare applicatie zit, moeten we ook proberen om alle bottlenecks te vermijden. Als we veel load hebben kan de database snel zo’n bottleneck worden, en dat probleem is moeilijk op te lossen. Een volgende stap die we kunnen nemen om een schaalbare applicatie te maken is gebruik maken van DynamoDB, de NoSQL database @ scale van AWS. Deze functie is hypersnel, heeft key-value en document data models. Het is compatibel met PartiQL, er is transaction support en het werkt prima met micro-services, mobile back-ends en serverless applicaties. Door op die manier te werken zal je data altijd beschikbaar zijn, ook bij een hoge workload.

DynamoDB is verdeeld in tabellen. Die bestaan telkens uit een Primary Key die bepaalt in welke partitie je data bewaard wordt. Dit is de beslissende factor die ervoor zorgt dat DynamoDB zo snel kan werken. Als je niet aan de data kan die je met je Primary Key wil bereiken, dan kan je nog altijd Secondary Indexes gebruiken die de data kopiëren binnen een andere partitie.

Queries worden gebruikt om data op te halen op basis van de partition key. Een andere optie is gebruik maken van de scan operatie, maar die is veel trager en duurder. Hier worden alle partities een voor een gescand tot de relevante data gevonden is.

DynamoDB biedt daarnaast steams aan. Die zou je kunnen vergelijken met triggers in een relationele database. In dit geval zullen Lambda functions bijhorende logica uitvoeren indien data toegevoegd, aangepast of verwijderd werd.

De laatste stap die je moet nemen is het verplaatsen van je applicatie van een relationele database naar een NoSQL DynamoDB database. Dat doe je door de database in de console te creëren. Binnen Visual Studio kan je via de AWS toolkit aan de data en je tabellen. Via de bijhorende NuGet Packages pas je de applicatie aan om de data uit dynamoDB te lezen.


Een match made in heaven

Hoewel Microsoft .NET en AWS op het eerste gezicht dus een atypisch koppel lijkt, zijn ze in werkelijkheid een match made in heaven. Vooral de snelheid waarmee Amazon innoveert is doorslaggevend: dagelijks komen er meer dan 3 nieuwe features bij. Rob, jarenlange Azure-fanboy, is na zijn ervaringen in de praktijk alvast volledig overtuigd!

Blijf je graag op de hoogte van de laatste Insights?

Rob Van Pamel

Rob Van Pamel

.NET Solution Architect

Benieuwd naar meer software development Insights?

Check hier de Insights van Kenny Laevaert, .NET consultant Axxes.

.NET Insight
Axxes