Les conteneurs sont un moyen simple de packager, déployer et gérer une application dans le cloud. C’est en grande partie pour cela que ce format est largement privilégié par les développeurs.

Sur Azure, il existe de nombreux moyens de travailler avec des conteneurs/applications conteneurisées.

Aujourd’hui, nous allons en faire le tour et essayer de les comparer. C’est parti !

Attention, l’ensemble des options suivantes permettent le déploiement d’applications .NET Core et .NET 5+. Concernant les applications .NET Framework, elles nécessitent des containers Windows et ne peuvent pas fonctionner sous Linux.

Table des matières

Azure App Service

Azure App Service est un service PaaS (Platform as a Service) HTTP pour l’hébergement d’applications web ou d’API. Il s’agit d’un service assez ancien sur Azure (preview en 2012 et General Availability en 2013).

Il permet d’utiliser de nombreux langages (.NET, Java, Node.js, Python…) et peut exécuter les applications sur des environnements Windows et Linux.

Le service propose de nombreuses fonctionnalités “clé en main” :

  • environnement complètement managé (maintenance de l’infrastructure, mise à jour automatique…)
  • intégration avec les outils DevOps (CI/CD)
  • auto-scaling et haute-disponibilité (SLA de 99,95%)
  • conformité (ISO, SOC et PCI)
  • intégration optimale avec les autres services Azure (supervision, sécurité, identité…)

En plus de l’hébergement “standard”, la brique App Service permet d’héberger des conteneurs. Voici la commande Azure CLI permettant de créer une WebApp et d’y déployer un conteneur :

az webapp create --resource-group <rg-name> --plan <plan-name> --name <app-name> --deployment-container-image-name <registry-name>.azurecr.io/my-custom-image:latest

Dans l’exemple, j’utilise une image provenant du registre Azure (ACR - Azure Container Registry). Mais vous pouvez aussi le faire à partir de Docker Hub ou d’un autre registre privé (auquel cas il faudra probablement vous authentifier).

Il est aussi possible de passer par du déploiement continu via Azure DevOps ou GitHub Actions.

Une dernière option est le déploiement de conteneurs multiples (attention, cette fonctionnalité est encore en preview à la date d’écriture de l’article). Autrement dit, il s’agit de déployer un docker-compose. Si vous souhaitez plus de détails sur cette dernière possibilité, je vous redirige vers le quickstart de Microsoft.

Attention, le pricing est basé sur le plan sous-jacent (aka. les ressources de calcul réservées) et non sur l’usage. Azure App Service est donc plus adapté à des charges continues pour optimiser au mieux la tarification.

Azure Functions

Azure Function est la brique serverless d’Azure (aka. compute-on-demand). Elle permet aux développeurs de se concentrer sur le code et la logique du système tout en offrant des capacités de scaling très importantes quand c’est nécessaire. Au même titre que les App Services, il est possible d’utiliser de nombreux langages : C#, Java, JavaScript, PowerShell, Python…

Cette brique répond à plusieurs problématiques : web API, workflow, tâches planifiées, réaction à des évènements, traitement de données…

Azure Functions permet aussi d’exécuter des conteneurs. Microsoft propose des images de base pour chaque langage supporté.

Attention, le déploiement de conteneurs sur une Azure Function requiert un plan Premium ou Dédié. Il n’est donc pas possible de profiter du plan de consommation :(

Si vous souhaitez en savoir plus à ce sujet, voici le tutoriel de Microsoft.

Azure Container Instance (aka. ACI)

Azure Container Instance est la façon la plus simple et rapide de déployer un conteneur sur Azure (à privilégier dans le cas de conteneur isolé, autrement dit, sans orchestration).

Il est possible d’exécuter des conteneurs Windows et Linux, et pour chaque conteneur, de personnaliser le nombre de coeurs de calcul et la mémoire disponible (facturation instantanée et en fonction de la consommation et des capacités de calcul). C’est la solution la moins chère pour les scénarios de charges de travail courte et sporadique (tâches planifiées, applications simples, batch…).

Techniquement, il s’agit d’un pod Hyper-V isolé qui permet de faire du “container-on-demand”. Attention par contre, il n’y a aucune gestion du scaling, du load-balancing ou des certificats. L’ACI se contente de fournir une adresse IP publique et un nom de domaine (.azurecontainer.io).

az container create --resource-group <rg-name> --name <container-name> --image <registry-name>.azurecr.io/my-custom-image:latest --dns-name-label <dns-name> --ports 80

Au même titre que la brique App Service, il est possible de déployer plusieurs conteneurs au sein d’un même hôte, via les groupes de conteneurs. Cela fonctionne toujours via un fichier YAML, mais celui-ci n’est plus au format “docker-compose”.

apiVersion: 2019-12-01
location: westeurope
name: myContainerGroup
properties:
  containers:
  - name: aci-app-1
    properties:
      image: <registry-name>.azurecr.io/my-app1-image:latest
      resources:
        requests:
          cpu: 1
          memoryInGb: 1.0
      ports:
      - port: 80
      - port: 8080
  - name: aci-app-2
    properties:
      image: <registry-name>.azurecr.io/my-app2-image:latest
      resources:
        requests:
          cpu: 2
          memoryInGb: 1.5
  osType: Linux
  ipAddress:
    type: Public
    ports:
    - protocol: tcp
      port: 80
    - protocol: tcp
      port: 8080
type: Microsoft.ContainerInstance/containerGroups

Azure Kubernetes Service (aka. AKS)

Azure Kubernetes Service est un service managé permettant de déployer simplement un cluster Kubernetes dans Azure. Il offre un accès et un contrôle complet à l’ensemble de l’API Kubernetes.

Azure Kubernetes Service architecture Azure Kubernetes Service architecture

L’infrastructure est découpée en 2 parties :

  • le plan de contrôle (aka. control plane), qui fournit les services Kubernetes de base (kube-apiserver, etcd, kube-scheduler, kube-controller-manager) et l’orchestration, et qui est géré par Azure
  • les noeuds, qui exécutent les charges de travail, représentés sous la forme de machine virtuelle (il en faut au moins un) sur laquelle sont installés les composants (kubelet, kube-proxy et containerd)

Le pricing est donc basé sur les noeuds, et donc le nombre et la tailles des VMs, ainsi que le stockage et le réseau associés. Je vous invite à jeter un oeil à la calculatrice Azure pour faire vos propres estimations.

Si vous avez un besoin d’orchestration ou que votre application possède une charge de travail difficilement prédictible, AKS est l’évolution logique des ACI. Vous disposerez en plus d’une excellente intégration avec l’écosystème Azure (Azure Monitor, Azure AD et RBAC…).

L’idée de l’article n’est pas de rentrer dans le détail de la brique AKS, donc je vous redirige vers la documentation de Microsoft à ce sujet :

A noter, il est possible de combiner AKS et ACI pour étendre vos charges de travail sans provisionner de nouveaux noeuds. Pour cela, AKS va déployer des pods à la demande en utilisant des ACI via Virtual Kubelet.

Plus d’informations sur ce lien.

Azure Red Hat OpenShift (aka. ARO)

Azure Red Hat OpenShift est un service managé permettant de déployer simplement un cluster OpenShift. Ce service a été conçu conjointement avec Red Hat et Microsoft.

OpenShift est basé sur Kubernetes, et est un produit commercial nécessitant une licence (aka. c’est payant !).

Kubernetes is the kernel.

OpenShift is the distribution, focused on the experience of developers

OpenShift vient ajouter à Kubernetes des fonctionnalités, comme un registre d’images (Image Streams), une CI/CD (Jenkins), une UI d’administration plus simple, des politiques de sécurité plus strictes, du support…

Encore une fois, l’idée de l’article n’est pas de rentrer dans le détail de la brique Azure Red Hat OpenShift, mais de donner une vue globale des possibilités d’Azure pour l’hébergement de conteneurs. Si vous souhaitez aller plus loin, je vous redirige vers la documentation de Microsoft.

Azure Container Apps (aka. ACA)

Et enfin, la dernière possibilité (et aussi la plus récente), les Azure Container Apps (ACA) ! Le service était en preview depuis plusieurs mois (la 1ère annonce date de la conférence Ignite 2021), et il est désormais en General Availability depuis Mai 2022.

L’idée est de fournir une plateforme pour héberger et orchestrer des conteneurs sans avoir à gérer la complexité d’un cluster Kubernetes (car oui, c’est quand même complexe, même avec AKS…). Attention, sous le capot, c’est tout de même basé sur AKS, mais vous n’avez pas accès à l’API de Kubernetes.

ACA répond à plusieurs cas d’utilisation :

  • déploiement d’endpoints d’API (mise à l’échelle en fonction du trafic HTTP)
  • applications de traitement en arrière-plan (mise à l’échelle en fonction de l’utilisation des ressources CPU et mémoire)
  • traitement event-driven (mise à l’échelle en fonction du nombre de messages dans la file)
  • microservices (mise à l’échelle en fonction des scalers KEDA)

Les ACAs peuvent être exposées sur le web (aka. Ingress), en HTTPS, via un FQDN généré par Azure (*.azurecontainerapps.io).

Environnement

Azure Container Apps - Environnements Azure Container Apps - Environnements

La 1ère notion importante est la notion d’environnement. Il s’agit d’un réseau virtuel sécurisé dans lequel on va pouvoir déployer plusieurs applications/conteneurs. Il est possible de fournir un VNET personnalisé (au moment de la création de l’environnement), sinon, il est créé automatiquement.

Cela permet de partager des composants (configuration Dapr et Log Analytics Workspace) ainsi que de permettre la communication entre les applications.

ACA Environment ~= Kubernetes Namespace

Révision

On va ensuite trouver la notion de révision. Il s’agit d’un instantané immuable d’une version d’un conteneur.

ACA Revision ~= Kubernetes Deployment

La 1ère révision est créée automatiquement lors du déploiement de l’application. Les révisions sont ensuite créées automatiquement, notamment lors de la mise à jour de l’image du conteneur (et toutes modifications de scope révision).

Lors d’une mise à jour, vous pouvez choisir de désactiver automatiquement les anciennes révisions (mode de révision unique) ou de les autoriser à rester disponibles (mode de révisions multiples). Dans ce 2nd cas, vous pouvez choisir le mode de répartition du trafic (pour faire du déploiement blue/green ou de l’A/B testing par exemple).

Azure Container Apps - Répartition du trafic entre plusieurs révisions Azure Container Apps - Répartition du trafic entre plusieurs révisions

Cycle de vie des applications :

Déploiement -> Mise à jour -> Désactivation -> Arrêt

Observabilité

L’observabilité est ce qui permet d’affirmer qu’un système est actif ou non, et s’il l’est, de déterminer s’il fonctionne correctement ou fait preuve d’une défaillance. C’est donc un outil indispensable pour diagnostiquer et améliorer la fiabilité et les performances de votre application (en particulier dans un contexte distribué).

Nativement, les ACA intègrent plusieurs fonctionnalités d’observabilité permettant d’obtenir une vue globale de l’intégrité de votre application.

On peut citer la journalisation (aka. les logs), aussi bien au niveau de votre conteneur que sur l’ensemble du service ACA. Il est possible de les visualiser en temps réel, via le portail Azure ou la CLI, mais aussi de consulter l’historique, via l’intégration d’Azure Monitor Log Analytics (et donc de profiter du système de requêtage via Kusto).

Grâce à Azure Monitor, vous allez aussi pouvoir surveiller les métriques de vos applications (CPU, mémoire, trafic I/O, nombre de réplicas…), en temps réel et dans le passé via la construction de graphiques.

Une fonctionnalité très pratique est Application Map, qui permet de dresser une cartographie de votre application en y intégrant des métriques.

Azure Application Map Azure Application Map

Bien sûr, cela inclut aussi la possibilité de configurer des alertes, aussi bien au niveau des métriques que des journaux.

La documentation de Microsoft détaille tout cela, je vous invite à la consulter si vous souhaitez creuser le sujet.

Authentification

De la même façon que pour l’observabilité, Azure Container Apps intègre nativement des fonctionnalités d’authentification et d’autorisation.

Cela permet, simplement et rapidement, de fournir une solution prête à l’emploi via des fournisseurs d’identité fédérée : Azure AD, Facebook, Google, Twitter et tout fournisseur OpenID Connect.

Ce mécanisme s’appuie sur un middleware qui est déployé au côté de votre conteneur (lorsque la fonctionnalité est activée). Chaque requête HTTP entrante va donc traverser cette couche avant d’atteindre votre application.

Azure Container Apps - Authentication middleware Azure Container Apps - Authentication middleware

Encore une fois, je vous redirige vers la documentation si vous voulez aller plus loin ;)

Composants tiers

Azure Container Apps fournit de manière native une compatibilité et une intégration avec des composants permettant de vous simplifier certaines tâches : Dapr, KEDA et envoy.

Dapr

Dapr, pour Distributed Application Runtime, est un projet open source en Go initié par Microsoft permettant de résoudre certaines problématiques complexes des applications distribuées (gestion d’état, communications inter-services, observabilité…).

Dapr Dapr

Dapr est composé de modules (aka. building blocks - les cases bleues sur le schéma ci-dessus) accessibles via des API HTTP/gRPC. Ces blocs peuvent donc être utilisés via n’importe quel langage ou framework (même s’il existe des SDK apportant une meilleure expérience et intégration).

Ces modules vont masquer l’implémentation de la fonctionnalité à vos services. Cela a pour effet de réduire les dépendances à des SDK ou bibliothèques externes et de laisser Dapr gérer la tuyauterie. Et surtout, on va pouvoir changer l’implémentation concrète à la demande sans avoir besoin de modifier le code de notre service (par exemple, pour la gestion d’état, passer de Azure Storage à Redis).

Dapr va agir comme un sidecar, autrement dit, un processus ou un container qui va tourner à côté de votre application principale.

Je vous invite à regarder ce lien pour plus d’informations sur comment Dapr est intégré avec les Azure Container Apps. Microsoft publie aussi un livre, gratuitement, sur l’utilisation de Dapr en tant que développeur .Net.

Bien sûr, vous pouvez utiliser les ACA sans Dapr ;)

KEDA

KEDA, pour Kubernetes Event-driven Autoscaling, est un composant permettant la mise à l’échelle automatique des applications en fonction d’évènements. C’est l’une des façons de mettre à l’échelle une ACA.

Les évènements peuvent provenir de nombreux services via des scalers : Azure Blob Storage, Azure Event Hubs, métrique CPU/mémoire, SQL Server…

Vous trouverez plus d’informations dans la documentation de Microsoft.

envoy

Envoy est un proxy HTTP. Il est utilisé dans les Azure Container Apps pour router les requêtes vers la bonne application en fonction des règles qui ont été définies (en particulier le niveau d’accessibilité, interne ou externe, et les règles de fractionnement du trafic).

Comme pour KEDA, je vous invite à jeter un oeil à la documentation.

Pricing

Comme les Azure Functions, on est sur un mode de facturation basé sur la consommation. Cela comprend les ressources (vCPU et mémoire) ainsi que le nombre de requêtes HTTP. Dans sa grande bonté, Microsoft offre du crédit gratuit chaque mois :

  • 180k vCPU/sec
  • 360k Gio/sec
  • 2M de requêtes

Jusque là, ça ressemble quand même beaucoup au pricing d’une Azure Function. MAIS, il y 2 points intéressants :

  • la possibilité qu’une révision possède 0 réplica, et donc l’absence de frais
  • la notion de conteneur inactif, avec des frais réduits

Un conteneur est marqué comme inactif lorsqu’il ne traite aucune requête HTTP et qu’il utilise moins de 0.01 vCPU et moins de 1000 octets/s de trafic réseau. Dans ce cas, votre conteneur sera facturé beaucoup moins cher, malgré le fait qu’il soit toujours provisionné. Et c’est très intéressant car on s’évite les soucis de cold-start que l’on pourrait rencontrer si l’on retire tous les replicas d’un conteneur. Autrement dit, on peut donc garder des instances “prêtes” pour un coût raisonnable.

Attention, la réduction est uniquement valable sur le prix du temps de vCPU, le prix de la mémoire ne change pas.

  • vCPU conteneur actif : 0,0000227 €/seconde
  • vCPU conteneur inactif : 0,0000029 €/seconde Soit tout de même 8 fois moins cher !

Si vos ACA ont pas mal d’IDLE time, ce mode de facturation peut donc être très intéressant pour vous ;)

Avec un exemple, c’est toujours plus clair !

Pour illustrer l’article, je vous propose un exemple utilisant les Azure Container Apps. Le projet est (très) simple, je souhaite surtout montrer le fonctionnement global, le déploiement et les interactions entre les différentes briques ;)

Schéma d'architecture du sample Schéma d'architecture du sample

Prenons un peu de temps pour parcourir ce schéma (en mode vue d’avion).

Au centre, on retrouve notre environnement Azure Container Apps. Celui-ci contient 3 Container App :

  • FrontEnd, qui est un site web ASP.NET Core chargé d’afficher du contenu en provenance des briques BackEnd (avec une UI donc). Cette brique dispose d’un point d’entrée HTTP (aka. ingress).
  • BackEnd1 et BackEnd2, qui sont des Web API ASP.NET Core chargés d’exposer la météo (il s’agit du template par défaut de Microsoft lorsque l’on créé une Web API en .NET) et des informations sur des produits (générés aléatoirement via Bogus). Pour ces 2 briques, l’ingress est désactivé, elles n’ont pas vocation a être exposées.

Autour de notre environnement, on va retrouver plusieurs autres composants nécessaires au bon fonctionnement de l’ensemble : Azure Container Registry, Log Analytics Workspace et Azure Monitor.

A noter aussi la présence du sidecar Dapr à côté de chaque Container App. Celui-ci est utilisé pour la communication entre les services (aka. service mesh).

Et Dapr du coup, comment on fait concrètement ?

J’ai déjà parlé de ce qu’était Dapr un peu avant, mais regardons maintenant comment ça se passe concrètement pour l’utiliser dans notre application. Vous allez voir, c’est très simple ;)

Let’s code !

La 1ère étape est d’installer le package NuGet : https://www.nuget.org/packages/Dapr.AspNetCore/1.9.0.

Ensuite, on ajoute Dapr à l’injecteur de dépendances de .NET : builder.Services.AddDaprClient();

Et… voilà ! En l’état, c’est tout ce qu’il y a faire pour intégrer Dapr dans notre FrontEnd.

Il ne reste plus qu’à voir comment, à partir de notre FrontEnd, faire des appels vers les APIs de nos BackEnd (aka. service invocation). Cette fois-ci, allons voir directement le code-behind de la page Index :

public class IndexModel : PageModel
  {
      private readonly DaprClient _daprClient;

      public IndexModel(DaprClient daprClient)
      {
          _daprClient = daprClient;
      }

      public async Task OnGetAsync()
      {
          var forecasts = await _daprClient.InvokeMethodAsync<IEnumerable<WeatherForecast>>(
              HttpMethod.Get,
              "backend1",
              "weatherforecast"
          );

          var products = await _daprClient.InvokeMethodAsync<IEnumerable<Product>>(
              HttpMethod.Get,
              "backend2",
              "product"
          );
      }
  }

Vous noterez qu’à aucun moment, on ne précise l’url du service distant, mais uniquement son appId ;) En coulisse, le side-car Dapr utilise un composant de résolution de noms pour résoudre l’adresse du service distant. En mode auto-hébergé, il s’agit de mDNS. Avec Kubernetes, ce sera le service DNS de Kubernetes.

Il est aussi possible d’utiliser la classe HttpClient via :

var httpClient = DaprClient.CreateInvokeHttpClient("appId");
await httpClient.GetAsync("requestUri");

Côté BackEnd, en dehors d’activer le side-car Dapr, il n’y a pas de code spécifique à écrire.

Le SDK Dapr pour .NET permet bien sûr de gérer la gestion d’état, le pub/sub, l’observabilité, la gestion des secrets… Mais on sort un peu du cadre de l’article, j’en reparlerais donc prochainement… ;)

Et si je veux tester en local ?

Avant de déployer tout ça sur Azure, on peut (légitimement :D) avoir envie de tester en local !

On va donc créer un fichier docker-compose.yml. Et pour cela, on va se faire aider par l’assistant de Visual Studio. Vous trouverez l’option en faisant Clic-droit sur votre projet -> Add -> Container Orchestrator Support. Choisissez Docker Compose (vous avez aussi le choix avec Service Fabric) puis l’OS cible (Linux ou Windows) et vous aurez l’immense joie d’obtenir un docker-compose et le DockerFile permettant de builder et exécuter votre application.

Il faudra tout de même y ajouter le side-car Dapr pour chacune de vos briques. Voici l’exemple de la brique FrontEnd :

myfrontend:
    image: ${DOCKER_REGISTRY-}myfrontend
    build:
      context: .
      dockerfile: MyFrontEnd/Dockerfile
    ports:
        - "52000:50002"
myfrontend-dapr:
    image: "daprio/daprd:latest"
    command: [ "./daprd", "-app-id", "my-front-end", "-app-port", "80" ]
    depends_on:
        - myfrontend
    network_mode: "service:myfrontend"

Il ne reste plus qu’à démarrer la stack, soit via un docker-compose up -d, soit via F5 dans Visual Studio (en ayant positionné le projet de démarrage sur le docker-compose)

Il est temps de montrer les Bicep !

Maintenant que tout fonctionne en local, on peut passer à l’étape suivante : provisionner notre environnement sur Azure et déployer nos applications. Et tout cela, via Bicep évidemment ;)

Avant d’exécuter le fichier Bicep suivant, vous aurez besoin de quelques prérequis :

  • un groupe de ressource
  • un registre de conteneurs.

Pour l’exemple, j’ai utilisé Azure Container Registry, mais vous pouvez très bien en utiliser un autre (Docker Hub par exemple).

Je suis aussi parti du principe que les images des 3 briques étaient déjà construites et déposées sur le registre. Pour l’exemple, je suis passé par le mécanisme de publication de Visual Studio. Dans l’idéal, cela sera fait par une pipeline dans votre usine logicielle ;)

J’ai découpé mon fichier Bicep en 2 parties :

  • main.bicep : se charge de la création du Log Analytics Workspace, de l’environnement Container Apps et d’appeler 3 fois le module containerApp (pour nos 3 briques : FrontEnd, BackEnd1 et BackEnd2)
  • containerApp.bicep : module chargé de la création d’un Container App, avec un ensemble de paramètres permettant de le rendre réutilisable dans différents contextes

Globalement, pas de difficultés, les fichiers Bicep sont toujours aussi fluides et naturels à écrire (quoi, comment ça je suis fan :D). Quelques points à noter tout de même sur la partie Container App :

  • Dapr peut se configurer directement via Bicep (appId, protocole…)
  • On peut définir un registre de conteneurs source (public ou privé)
  • On peut préciser une image d’un conteneur à déployer directement ;)
resource containerApp 'Microsoft.App/containerApps@2022-06-01-preview' = {
  name: name
  location: location
  properties: {
    managedEnvironmentId: containerAppEnvId
    configuration: {
      dapr: {
        appId: daprAppId
        appPort: 80
        appProtocol: 'http'
        enabled: true
      }
      ingress: {
        external: useExternalIngress
        targetPort: containerPort
      }
      secrets: [
        {
          name: 'container-registry-password'
          value: registryPassword
        }
      ]
      registries: [
        {
          server: registry
          username: registryUsername
          passwordSecretRef: 'container-registry-password'
        }
      ]      
    }
    template: {
      containers: [
        {
          image: containerImage
          name: name
        }
      ]
      scale: {
        minReplicas: 0
      }
    }
  }
}

On peut ensuite passer au déploiement. Avant d’exécuter la commande, on a besoin de se connecter : az login

puis de récupérer les informations d’authentification vers notre registre (l’ACR dans mon cas). On peut faire ça soit via le portail (dans Settings -> Access Keys), soit via la CLI : az acr credential show -n <acr-name>

Enfin, c’est parti pour le déploiement :

az deployment group create -n container-app -g <rg-name> --template-file .\main.bicep -p registry=<acr-name>.azurecr.io registryUsername=<username> registryPassword<password>

Vous trouverez l’ensemble du code source sur ce dépôt GitHub : https://github.com/AnceretMatthieu/sample-azure-container-apps

Conclusion

Nous avons pu voir qu’il existe de nombreuses façons d’exécuter du conteneur sur Azure. Le choix du bon service pour votre application peut avoir un impact important sur la maintenance, le coût et les performances. Il est donc important, voire même essentiel, de bien examiner vos besoins et de les confronter aux avantages et inconvénients de chaque service.

J’espère en tous cas vous avoir donné une vision claire, et je vous laisse avec quelques liens supplémentaires pour continuer à creuser le sujet :

  • L’organigramme décisionnel de Microsoft, et en particulier le noeud avec la question can it be containerized ?
  • Toujours chez Microsoft, la page de comparaison des services de conteneurs
  • Un billet de Jonathan George, qui dresse un tableau assez complet des possibilités et des contraintes (en particulier sur ACA vs Functions)
  • Un article de Stanislav Lebedenko, qui expose différents scénarios d’usage des ACA (solution existante à migrer, ajout de nouveaux services à un existant, projet from sratch…)
  • Et enfin, un article ultra complet de Taiseer Joudeh sur Bit of Technology, qui donne un exemple vraiment complet d’utilisation des ACA, avec notamment une intégration assez poussée de Dapr