Les Azure Logic Apps Standard sont des services d’intégration et d’automatisation de flux de travail proposés par Microsoft Azure. Elles permettent d’orchestrer et de piloter des processus métier en s’appuyant sur des connecteurs prédéfinis (SharePoint, Azure Service Bus, Outlook, Salesforce, etc.).
L’un des principaux atouts des Logic Apps Standard réside dans leur simplicité de mise en œuvre : on peut, sans écrire une seule ligne de code, automatiser des scénarios complexes d’intégration et d’échange de données. Elles sont donc très appréciées pour leur rapidité de mise en production et leur flexibilité.
Docker est une plateforme de conteneurisation qui permet d’empaqueter et d’exécuter des applications dans des environnements isolés, reproductibles et portables. Les avantages de cette approche sont multiples :
Dans ce contexte, exécuter une Logic App Standard dans un conteneur Docker permet d’optimiser sa portabilité et son déploiement, que ce soit pour des environnements de développement, de test ou de production.
Avant de commencer, assurez-vous de disposer des outils suivants :
Votre projet doit inclure :
Pour la suite, il est important d’ajouter ceci dans le fichier local.settings.json afin de définir le port d’écoute de la Logic App Standard sur 80, au lieu du port 7071 par défaut :
"Host": { "LocalHttpPort" : 80 }
Par la même occasion, vérifiez que dans vos app settings que FUNCTIONS_WORKER_RUNTIME soit bien défini à dotnet et non pas nodejs.
"FUNCTIONS_WORKER_RUNTIME": "dotnet"
Pour exécuter une Logic App Standard en local, vous devez utiliser le runtime de la Logic App Standard (basé sur Azure Functions Runtime). Vous pouvez soit :
Assurez-vous que votre fichier host.json comporte les informations nécessaires au runtime, notamment la version du runtime (v2 par exemple).
A savoir : au 25 janvier 2025, la migration des Logic Apps Standard vers dotnet 8 n’a toujours pas été finalisée par Microsoft. Il faut donc utiliser dotnet 6 !
Les Logic App Standard démarrent leur exécution via un trigger. Celui-ci peut être programmé (timer trigger), événementiel (webhook, message queue, etc.) ou encore manuel.
Dans notre exemple, nous utiliserons un trigger http.
Dans VS Code, vous pouvez lancer la Logic App Standard en local :
func host start
Ceci démarrera votre Logic App Standard localement. Une fois en cours d’exécution, vous pouvez envoyer une requête HTTP à l’URL exposée et vérifier son bon fonctionnement.
Pour récupérer l’URL à appeler, avec l’extension Logic Apps Standard de VS Code, faites un clic droit sur le fichier json du workflow, puis overview. L’URL à appeler s’affichera.
La première étape consiste à créer un fichier Dockerfile à la racine de votre projet. Attention, si vous êtes sur une architecture ARM, il faut garder à l’esprit que Azure Container Instance ne propose pas l’hébergement de containers en ARM pour le moment. Il faudra donc build son image en amd. Voici un exemple minimaliste basé sur l’image mcr.microsoft.com/dotnet/sdk:6.0:
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS installer-env COPY . /src/dotnet-function-app RUN cd /src/dotnet-function-app && \ dotnet build RUN apt-get update RUN apt-get -y install curl gnupg RUN curl - fssl https://deb.nodesource.com/setup_18.x | bash - RUN apt-get -y install nodejs RUN npm i -g azure-functions-core-tools@4 --unsafe-perm true RUN apt-get install -y unzip RUN curl -sSL https://aka.ms/getvsdbgsh | /bin/sh /dev/stdin -v latest -1 ~/vsdbg RUN apt-get update && apt-get install -y coreutils WORKDIR /src/dotnet-function-app ENV AzureFunctionsJobHost__Logging_Console_IsEnabled=true EXPOSE 80 ENTRYPOINT [ "func", "host", "start" ]
Dans cet exemple :
À la racine de votre projet (là où se situe le Dockerfile), exécutez :
docker build -t <nom-image>:latest
Cette commande va :
Une fois l’image construite, lancez un conteneur localement :
docker run -p 80:80 <nom-image>:latest
L’option -p 80:80 mappe le port 80 du conteneur sur le port 80 de votre machine locale.
Vérifiez les logs affichés dans la console pour confirmer le bon démarrage de la Logic App.
Afin de pouvoir appeler la Logic App, il faut se rendre sur le portail Azure, dans le storage account lié à la Logic App, puis dans le container azure-webjobs-secrets, dans le dossier du même nom que la Logic App, se trouve le fichier host.json. Récuperez la master key, et faites un POST à l’url suivante (avec postman par exemple) :
http://localhost/runtime/webhooks/workflow/api/management/workflows/{nom du workflow}/triggers/{nom du trigger}/listCallbackUrl?api-version=2022-05-01-preview&code={masterKey}
Cet appel vous permet de récupérer le paramètre sp, sv et sig à envoyer à la Logic App. Notez les, puis appelez la Logic App à cette URL :
http://localhost/api/{nom du workflow}/triggers/{nom du trigger}/invoke?api-version=2022-05-01-preview&sp={sp}&sv={sv}&sig={sig}
Si tout fonctionne, on peut passer à l’étape suivante : déployer tout ça dans azure.
Pour déployer un conteneur sur ACI, l’image doit être disponible dans un registre accessible. Étant sur Azure, Azure Container Registry (ACR) est un choix naturel.
1. Connectez-vous à azure :
az login
2. Créez un registre ACR depuis le portail Azure ou via Azure CLI :
az acr create --resource-group <votre-resource-group> --name <nom-acr> --sku Basic
Pour récupérer le registery-username & password, il faut se rendre sur l’ACR, puis dans Settings > Access Keys et cocher « Admin user ». Il vous sera alors donné un username et mot de passe.
3. Connectez-vous à votre registre :
az acr login --name <nom-acr>
4. Tagguez votre image pour la pousser vers ACR :
docker tag my-logic-app:latest <nom-acr>.acr.io/my-logic-app:latest
5. Poussez l’image vers ACR :
docker push <nom-acr>.azurecr.io/my-logic-app:latest
Une fois l’image disponible dans ACR, vous pouvez déployer un conteneur sur ACI. Par exemple :
az container create \ --resource-group <nom-resource-group> \ --name <nom-container> \ --image <nom-acr>.azurecr.io/<nom-image>:latest \ --registry-login-server <nom-acr>.azurecr.io \ --registry-username <utilisateur-acr> \ --registry-password <mot-de-passe-acr> \ --ports 80 --os-type Linux --cpu 1 --memory 1.5 --dns-name-label <label-dns> --ip-address Public
az container show --resource-group <nom-resource-group> --name <nom-container> --query ipAddress.fqdn --output tsv
Avant de commencer, il est nécessaire, si ce n’est pas déjà fait, de créer les services connections requises sur Azure Devops. Vous aurez besoin d’une service connection de type Azure Resource Manager ainsi qu’une autre de type Docker Registry.
Voici un exemple minimaliste d’un fichier yaml qui build une image docker et la pousse sur ACR.
# Fichier : azure-pipelines.yml trigger: - main stages: - stage: Build_and_Push displayName: "Build and Push Docker Image" jobs: - job: Build displayName: "Build and Push to ACR" pool: vmImage: 'ubuntu-latest' steps: # 1. Vérifier que Docker est installé (généralement déjà présent sur l'agent Microsoft-hosted) - task: DockerInstaller@0 displayName: "Installer Docker (si nécessaire)" # 2. Se connecter à Azure à l'aide du service connection - task: AzureCLI@2 displayName: "Connexion à Azure" inputs: azureSubscription: "<Service connection ID>" scriptType: bash scriptLocation: inlineScript inlineScript: | echo "Connecté à Azure, subscription : $AZURE_SUBSCRIPTION_ID" # 3. Se connecter à ACR via Docker login - task: Docker@2 displayName: "Login to ACR" inputs: command: login containerRegistry: "<Service connection registry ID>" azureSubscription: "<Service connection ID>" # 4. Construire et pousser l'image Docker vers ACR - task: Docker@2 displayName: "Build and Push Docker Image" inputs: command: buildAndPush repository: "<nom acr>azurecr.io/<nom image>" dockerfile: "**/Dockerfile" # Chemin vers votre Dockerfile (peut être à la racine) tags: | latest containerRegistry: "<Service connection registry ID>" azureSubscription: "<Service connection registry ID>" - stage: Deploy_to_ACI displayName: "Deploy to Azure Container Instances" dependsOn: Build_and_Push jobs: - job: Deploy displayName: "Déploiement ACI" pool: vmImage: 'ubuntu-latest' steps: # 1. Se reconnecter à Azure si nécessaire - task: AzureCLI@2 displayName: "Connexion à Azure" inputs: azureSubscription: "<Service connection ID>" scriptType: bash scriptLocation: inlineScript inlineScript: | echo "Connecté à Azure, subscription : $AZURE_SUBSCRIPTION_ID" # 2. Créer ou mettre à jour le conteneur sur ACI - task: AzureCLI@2 displayName: "Déployer la Logic App standard conteneurisée sur ACI" inputs: azureSubscription: "<Service connection ID>" scriptType: bash scriptLocation: inlineScript inlineScript: | # Variables ACR_NAME="<nom acr>" RESOURCE_GROUP="<nom ressource group>" CONTAINER_NAME="<nom container>" IMAGE_NAME="<nom image>" # Déployer le conteneur az container create \ --resource-group $RESOURCE_GROUP \ --name $CONTAINER_NAME \ --image $ACR_NAME.azurecr.io/$IMAGE_NAME:latest \ --registry-login-server $ACR_NAME.azurecr.io \ --registry-username <user acr> \ --registry-password '<mot de passe acr>' \ --ports 80 \ --os-type Linux \ --cpu 1 \ --memory 1.5 \ --dns-name-label <nom label dns> \ --ip-address Public