Blog

Efficiëntie in App configuratie: Een diepgaande kijk op Cloud Native Software Development met Azure

Ontdek hoe je applicatie configuratie soepeler en efficiënter kunt maken met Azure. Scheid configuratie en code voor Cloud Native applicaties en leer handige trucs voor een naadloze uitrol met GitHub Actions. Optimaliseer je applicaties en haal meer uit Azure's krachtige services.

Gepubliceerd: 21 augustus 2023

Allereerst is bij het bouwen van Cloud Native applicaties één van de principes het scheiden van de configuratie en de code. (https://12factor.net/config). Idealiter wil je deze configuratie het liefst, net als de infrastructuur, vastgelegd zien in de code. Immers wanneer de configuratie vastgelegd is biedt dat voordelen als versionering, traceerbaarheid en een verbeterde beheersbaarheid.  

Intercept bouwt zelf Cloud Native applicaties en helpt de klanten om hun applicaties Cloud Native te maken. (Lees hier meer over hoe we dat doen) Al deze applicaties maken gebruik van een configuratie, die vaak verschilt tussen omgevingen (test, acceptatie en productie). Hierbij wordt altijd onderscheid gemaakt tussen gevoelige en niet-gevoelige configuratie. In dit artikel wordt gebruik gemaakt van een applicatie gebouwd in .NET 7. Deze applicatie wordt uitgerold via GitHub Actions naar Azure.  

 

Het opslaan van de configuratie

Voor het opslaan van onze configuratie maken we een nieuwe map in onze repository (bijvoorbeeld /config). Voor elke omgeving maken we een appsettings.[omgevingsnaam].json aan. In deze bestanden kunnen we onze configuratie opgeven als key-value pairs. Indien gewenst is het nesten van waarden mogelijk.   

{ 
  "Supplier": { 
    "RedirectUri": "https://cloudadventures.com", 
    "Scope": "all", 
    "State":  "active" 
  } 
}

Voor alle gevoelige configuraties maken we secretreferences.[omgevingsnaam].json aan. In die bestanden slaan we de referenties op verwijzend naar de secrets in Azure Key Vault. We slaan dus niet de daadwerkelijke gevoelige informatie op in de configuratiebestanden zelf. Als we de configuratie laden in onze applicatie, zal deze de Key Vault benaderen voor het ophalen van de daadwerkelijke configuratiewaarden. 

{ 
  "Supplier" : { 
    "ClientId": "{\"uri\":\"https://cloudadventures-dev.vault.azure.net/secrets/Supplier--ClientId\"}", 
    "ClientSecret": "{\"uri\":\"https://cloudadventures-dev.vault.azure.net/secrets/Supplier--ClientSecret\"}", 
  } 
} 

De uitrol

Voor het uitrollen van onze configuratie maken we gebruik van GitHub Actions. Er is een GitHub Action (Azure/AppConfiguration-Sync: GitHub action for importing configuration files to Azure App Configuration) beschikbaar binnen Microsoft voor het synchroniseren van de configuratie in onze repository met die van de Azure App Configuration.  

Voor het communiceren met de App Configuration zullen we de connectie string moeten toevoegen aan onze GitHub ‘Actions secrets and variables’ (Encrypted secrets - GitHub Docs). In onze Action verwijzen we naar dit secret.  

Stappen:  

- uses: actions/checkout@v1  
- uses: azure/appconfiguration-sync@v1  
  with:  
    configurationFile: 'config/appsettings.dev.json' 
    format: 'json' 
    connectionString: ${{}} 
    separator: ':'  
    prefix: '' 
 - uses: azure/appconfiguration-sync@v1 
   with: 
     configurationFile: 'config/secretreferences.dev.json' 
     format: 'json' 
     connectionString: $<<secrets.app_configuration_connection>>
     separator: ':' 
     prefix: '' 
     contentType: 'application/vnd.microsoft.appconfig.keyvaultref+json;charset=utf-8' 

Door onze pipeline tegelijkertijd met de uitrol van onze applicatie te draaien, zorgen we ervoor dat iedere nieuwe versie van onze applicatie bij de laatste configuratie kan.

 

Configuratie gebruiken in de applicatie   

We hebben er nu voor gezorgd dat de configuratie in de Azure App Configuration wordt aangepast wanneer de GitHub Action gedraaid heeft. Deze configuratie gaan we inlezen en gebruiken in de applicatie.  

Om in onze code verbinding te maken met de App Configuration gebruiken we de ‘Connection string’. Die kan verkregen worden door in het Azure Portal te navigeren naar de App Configuration resource en vervolgens te kiezen voor ‘Access keys’.  

Deze connection string slaan we vervolgens op in de settings van onze applicatie (lokaal in de user secrets Safe storage of app secrets in development in ASP.NET Core | Microsoft Learn), in Azure kan gebruik gemaakt worden van bijvoorbeeld de ‘application settings’ of ‘environment variabelen’.  

In onze applicatie dienen we te refereren naar de NuGet-package ‘Microsoft.Azure.AppConfiguration.AspNetCore’. In de program.cs kunnen de configuratiewaarden worden uitgelezen aan de hand van de volgende code:

var connectionString = builder.Configuration.GetValue<string>("AppConfigurationConnectionString"); 
builder.Configuration.AddAzureAppConfiguration(options => 
{ 
   options.Connect(connectionString).ConfigureKeyVault(kv => 
   { 
      var credentials = new DefaultAzureCredential(new DefaultAzureCredentialOptions 
      { 
          SharedTokenCacheTenantId = tenantId 
      }); 
       
      kv.SetCredential(credentials); 
    }) 
    .Select("*"); 
}); 

Aan de hand van bijvoorbeeld het option pattern (https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/options?view=aspnetcore-7.0) kunnen de configuratie waardes worden gebruikt.

 

Het gebruik van een User Assigned Managed Identity  

Wanneer we in Azure draaien is het handig om onze Azure App Configuration en Azure Key Vault toegang te verlenen via Managed Identities. Als onderdeel van de uitrol van onze infrastructuur zal onze applicatie dan ook toegang moeten geven aan deze resource.   

Om via een User Assigned Managed Identity toegang te krijgen, zal het Program.cs moeten worden aangepast. Het ‘Client ID’ van onze Managed Identity dienen we dan ook toe te voegen aan onze configuratie.  

var connectionString = builder.Configuration.GetValue<string>("AppConfigurationConnectionString"); 
var userAssignedManagedIdentityClientId = builder.Configuration.GetValue<string>(“UserAssignedManagedIdentityClientId”); 
builder.Configuration.AddAzureAppConfiguration(options => 
{ 
  options.Connect(connectionString).ConfigureKeyVault(kv => 
  { 
     DefaultAzureCredential credentials = new DefaultAzureCredential(new DefaultAzureCredentialOptions 
     { 
        ManagedIdentityClientId = userAssignedManagedIdentityClientId 
     }); 
        
     kv.SetCredential(credentials); 
   }) 
   .Select("*"); 
});

Tenslotte

In dit artikel toonden we jou hoe aan de hand van de Azure App Configuration en de Azure Key Vault configuratie as-code kan worden gerealiseerd. Doormiddel van GitHub Actions zijn we in staat om deze configuratie automatisch uit te rollen. Ben je benieuwd naar hoe wij jou kunnen helpen met de configuratie van Cloud Native applicaties? Neem dan contact met ons op.

Ontdek onze CNSD aanpak

Neem contact met ons op

Handige links: 

https://learn.microsoft.com/en-us/azure/azure-app-configuration/  

https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/options?view=aspnetcore-7.0   

https://github.com/Azure/AppConfiguration-Sync