Migrer des applications Tomcat vers Tomcat sur Azure App Service

Ce guide décrit ce que vous devez savoir quand vous voulez migrer une application Tomcat existante pour pouvoir l’exécuter sur Azure App Service en utilisant Tomcat 9.0.

Prémigration

Pour garantir la réussite de la migration, avant de commencer, effectuez les étapes d’évaluation et d’inventaire décrites dans les sections suivantes.

Si vous ne parvenez pas à respecter ces conditions de prémigration, consultez les guides de migration suivants :

Basculer vers une plateforme prise en charge

App Service offre des versions spécifiques de Tomcat sur des versions spécifiques de Java. Pour garantir sa compatibilité, migrez votre application vers l’une des versions prises en charge de Tomcat et Java dans son environnement actuel avant de passer à l’une des étapes restantes. Veillez à tester entièrement la configuration obtenue. Utilisez la dernière version stable de votre distribution Linux dans ces tests.

Remarque

Cette validation s’avère particulièrement importante si votre serveur actuel s’exécute sur un JDK non pris en charge (comme Oracle JDK ou IBM OpenJ9).

Pour obtenir votre version actuelle de Java, connectez-vous à votre serveur de production et exécutez la commande suivante :

java -version

Sur Azure App Service, les fichiers binaires pour Java 8 sont fournis à partir d’Eclipse Temurin. Pour Java 11, 17 et toutes les futures versions LTS de Java, App Service fournit la Build Microsoft d’OpenJDK. Ces fichiers binaires sont disponibles gratuitement sur les sites suivants :

Pour obtenir votre version actuelle de Tomcat, connectez-vous à votre serveur de production et exécutez la commande suivante :

${CATALINA_HOME}/bin/version.sh

Pour obtenir la version actuelle utilisée par Azure App Service, téléchargez Tomcat 9, en fonction de la version que vous prévoyez d’utiliser dans Azure App Service.

Inventorier les ressources externes

Les ressources externes, comme les sources de données, les répartiteurs de messages JMS, etc., sont injectées par le biais de l’interface JNDI (Java Naming and Directory Interface). Certaines de ces ressources peuvent nécessiter une migration ou une reconfiguration.

Au sein de votre application

Examinez le fichier META-INF/context.xml. Recherchez les éléments <Resource> à l’intérieur de l’élément <Context>.

Sur le ou les serveurs d’applications

Examinez les fichiers $CATALINA_BASE/conf/context.xml et $CATALINA_BASE/conf/server.xml, ainsi que les fichiers .xml trouvés dans les répertoires $CATALINA_BASE/conf/[engine-name]/[host-name].

Dans les fichiers context.xml, les ressources JNDI sont décrites par les éléments <Resource> à l’intérieur de l’élément <Context> de niveau supérieur.

Dans les fichiers server.xml, les ressources JNDI sont décrites par les éléments <Resource> à l’intérieur de l’élément <GlobalNamingResources>.

Sources de données

Les sources de données sont des ressources JNDI dont l’attribut type a la valeur javax.sql.DataSource. Pour chaque source de données, réunissez les informations suivantes :

  • Quel est le nom de la source de données ?
  • Quelle est la configuration du pool de connexions ?
  • Où trouver le fichier JAR du pilote JDBC ?

Pour plus d’informations, consultez JNDI Datasource HOW-TO (Guide pratique sur les sources de données JNDI) dans la documentation Tomcat.

Toutes les autres ressources externes

Il n’est pas possible de décrire toutes les dépendances externes possibles dans ce guide. Il incombe à votre équipe de vérifier que vous pouvez satisfaire à toutes les dépendances externes de votre application après la migration.

Inventorier les secrets

Mots de passe et chaînes sécurisées

Recherchez dans l’ensemble des propriétés et fichiers de configuration présents sur les serveurs de production d’éventuels chaînes secrètes et mots de passe. Pensez à vérifier server.xml et context.xml dans $CATALINA_BASE/conf. Vous pouvez également trouver des fichiers de configuration contenant des mots de passe ou des informations d’identification à l’intérieur de votre application. Il peut s’agir du fichier META-INF/context.xml et, pour les applications Spring Boot, des fichiers application.properties ou application.yml.

Inventorier les certificats

Documentez tous les certificats utilisés pour les points de terminaison SSL publics ou la communication avec les bases de données back-end et autres systèmes. Vous pouvez voir tous les certificats présents sur les serveurs de production en exécutant la commande suivante :

keytool -list -v -keystore <path to keystore>

Déterminer si le système de fichiers est utilisé et de quelle manière

Toute utilisation du système de fichiers sur le serveur d’applications nécessite une reconfiguration ou, dans de rares cas, des modifications architecturales. Vous pouvez identifier une partie ou l’ensemble des scénarios suivants.

Contenu statique en lecture seule

Si votre application sert actuellement du contenu statique, vous aurez besoin d’un autre emplacement pour lui. Vous pouvez envisager de déplacer le contenu statique vers Azure Blob Storage et d'ajouter Azure CDN pour des téléchargements rapides à l'échelle mondiale. Pour plus d’informations, consultez Hébergement de sites web statiques dans le service Stockage Azure et Démarrage rapide : Intégrer un compte de stockage Azure à Azure CDN.

Contenu statique publié dynamiquement

Si votre application autorise le contenu statique chargé/produit par votre application mais immuable après sa création, vous pouvez utiliser le Stockage Blob Azure et Azure CDN comme décrit ci-dessus, avec une fonction Azure pour gérer les chargements et l’actualisation du réseau CDN. Nous avons mis à votre disposition un exemple d’implémentation dans Chargement et préchargement CDN de contenu statique avec Azure Functions.

Contenu dynamique ou interne

Pour les fichiers fréquemment écrits et lus par votre application (comme les fichiers de données temporaires) ou les fichiers statiques uniquement visibles pour votre application, vous pouvez monter le Stockage Azure dans le système de fichiers App Service. Pour en savoir plus, consultez Monter Azure Storage en tant que partage local dans App Service.

Identifier le mécanisme de persistance de session

Pour identifier le gestionnaire de persistance de session en cours d’utilisation, examinez les fichiers context.xml dans votre application et votre configuration Tomcat. Recherchez l’élément <Manager>, puis notez la valeur de l’attribut className.

Les implémentations PersistentManager intégrées de Tomcat, comme StandardManager ou FileStore ne sont pas conçues pour être utilisées avec une plateforme adaptée distribuée comme App Service. Étant donné qu’App Service peut équilibrer la charge entre plusieurs instances et redémarrer de manière transparente toute instance à tout moment, il n’est pas recommandé de rendre persistant l’état mutable dans un système de fichiers.

Si la persistance de session est nécessaire, vous devez utiliser une autre implémentation PersistentManager qui écrit dans un magasin de données externe, comme VMware Tanzu Session Manager avec le cache Redis. Pour plus d’informations, consultez Utiliser Redis comme cache de session avec Tomcat.

Identifier tous les processus et démons extérieurs exécutés sur les serveurs de production

Si vous avez des processus qui s’exécutent en dehors du serveur d’applications, comme les démons de supervision, vous devez les éliminer ou les migrer ailleurs.

Cas particuliers

Certains scénarios de production peuvent nécessiter d’autres changements ou imposer d’autres limites. Même si de tels scénarios peuvent être rares, il est important de s’assurer qu’ils ne sont pas applicables à votre application ou qu’ils sont correctement résolus.

Déterminer si l’application s’appuie sur des tâches planifiées

Les tâches planifiées, comme les tâches Quartz Scheduler ou les travaux Cron, ne peuvent pas être utilisées avec App Service. App Service ne vous empêchera pas de déployer une application contenant des tâches planifiées en interne. Toutefois, si votre application a fait l’objet d’un scale-out, la même tâche planifiée peut s’exécuter plusieurs fois par période planifiée. Cette situation peut entraîner des conséquences inattendues.

Inventoriez toutes les tâches planifiées à l’intérieur ou à l’extérieur du serveur d’applications.

Déterminer si votre application contient du code propre au système d’exploitation

Si votre application contient du code avec des dépendances vis-à-vis du système d’exploitation hôte, vous devez la refactoriser pour supprimer ces dépendances. Par exemple, vous devrez peut-être remplacer toute utilisation de / ou \ dans les chemins d'accès au système de fichiers par File.Separator ou Paths.get si votre application fonctionne sous Windows.

Déterminer si le clustering Tomcat est utilisé

Le clustering Tomcat n’est pas pris en charge sur Azure App Service. Vous pouvez alors configurer et gérer la mise à l’échelle et l’équilibrage de charge par le biais d’Azure App Service sans fonctionnalités propres à Tomcat. Vous pouvez rendre persistant l’état de session à un autre emplacement pour le rendre disponible dans tous les réplicas. Pour plus d’informations, consultez Identifier le mécanisme de persistance de session.

Pour déterminer si votre application utilise un clustering, recherchez l’élément <Cluster> à l’intérieur des éléments <Host> ou <Engine> dans le fichier server.xml.

Déterminer si des connecteurs non-HTTP sont utilisés

App Service prend en charge un seul connecteur HTTP. Si votre application nécessite d’autres connecteurs comme le connecteur AJP, n’utilisez pas App Service.

Pour identifier les connecteurs HTTP utilisés par votre application, recherchez les éléments <Connector> à l’intérieur du fichier server.xml dans votre configuration Tomcat.

Déterminer si MemoryRealm est utilisé

MemoryRealm nécessite un fichier XML persistant. Sur Azure AppService, vous devrez charger ce fichier dans le répertoire /home ou l’un de ses sous-répertoires, ou sur un stockage monté. Vous devrez ensuite modifier le paramètre pathName en conséquence.

Pour déterminer si MemoryRealm est actuellement utilisé, examinez vos fichiers server.xml et context.xml et recherchez les éléments <Realm> dont l’attribut className a la valeur org.apache.catalina.realm.MemoryRealm.

Déterminer si le suivi de session SSL est utilisé

App Service effectue un déplacement de session en dehors du runtime Tomcat ; vous ne pouvez donc pas utiliser le suivi de session SSL. Utilisez un autre mode de suivi de session à la place (COOKIE ou URL). Si vous avez besoin du suivi de session SSL, n’utilisez pas App Service.

Déterminer si AccessLogValve est utilisé

Si vous utilisez AccessLogValve, vous devez définir le paramètre directory sur /home/LogFiles ou l’un de ses sous-répertoires.

Migration

Paramétrer la configuration

Lors des étapes de prémigration, vous aurez probablement identifié des secrets et des dépendances externes, comme des sources de données, dans les fichiers server.xml et context.xml. Pour chaque élément identifié, remplacez le nom d’utilisateur, le mot de passe, la chaîne de connexion ou l’URL par une variable d’environnement.

Par exemple, supposons que le fichier context.xml contienne l’élément suivant :

<Resource
    name="jdbc/dbconnection"
    type="javax.sql.DataSource"
    url="jdbc:postgresql://postgresdb.contoso.com/wickedsecret?ssl=true"
    driverClassName="org.postgresql.Driver"
    username="postgres"
    password="t00secure2gue$$"
/>

Dans ce cas, vous pouvez le changer comme indiqué dans l’exemple suivant :

<Resource
    name="jdbc/dbconnection"
    type="javax.sql.DataSource"
    url="${postgresdb.connectionString}"
    driverClassName="org.postgresql.Driver"
    username="${postgresdb.username}"
    password="${postgresdb.password}"
/>

Pour vous assurer que la substitution de paramètre se produit pour n’importe quel fichier context.xml dans le dossier META-INF à l’intérieur d’un fichier .war déployé, veillez à définir la variable d’environnement CATALINA_OPTS comme indiqué dans l’exemple suivant :

export CATALINA_OPTS="-Dorg.apache.tomcat.util.digester.PROPERTY_SOURCE=org.apache.tomcat.util.digester.EnvironmentPropertySource"

Provisionner un plan App Service

Dans la liste des plans de service disponibles aux tarifs App Service, sélectionnez celui dont les spécifications respectent ou dépassent celles du matériel de production actuel.

Remarque

Si vous envisagez d’exécuter des déploiements de préproduction/contrôle de validité ou d’utiliser des emplacements de déploiement, le plan App Service doit inclure cette capacité supplémentaire. Nous vous recommandons d’utiliser des plans Premium ou plus élevés pour les applications Java. Pour plus d’informations, consultez Configurer des environnements de préproduction dans Azure App Service.

Ensuite, créez le plan App Service. Pour plus d’informations, consultez Gérer un plan App Service dans Azure.

Créer et déployer une ou plusieurs applications web

Vous avez besoin de créer une application web sur votre plan App Service (en choisissant une version de Tomcat comme pile d’exécution) pour chaque fichier WAR déployé sur votre serveur Tomcat.

Remarque

Même s’il est possible de déployer plusieurs fichiers WAR dans une seule application web, ce choix n’est vraiment pas souhaitable. Le déploiement de plusieurs fichiers WAR sur une seule application web empêche en effet chaque application de se mettre à l’échelle en fonction de ses propres besoins. Il complique également les pipelines de déploiement ultérieurs. Si plusieurs applications ont besoin d’être disponibles sur une seule URL, envisagez d’utiliser une solution de routage comme Azure Application Gateway.

Applications Maven

Si votre application est générée à partir d’un fichier POM Maven, utilisez le plug-in Webapp pour Maven pour créer l’application web et déployer votre application.

Applications non-Maven

Si vous ne pouvez pas utiliser le plug-in Maven, vous devez provisionner l’application web par le biais d’autres mécanismes, comme :

Une fois l’application web créée, utilisez l’un des mécanismes de déploiement disponibles pour déployer votre application.

Migrer des options de runtime JVM

Si votre application exige des options de runtime spécifiques, utilisez le mécanisme le plus approprié pour les spécifier.

Renseigner les secrets

Utilisez des paramètres d’application pour stocker tous les secrets propres à votre application. Si vous envisagez d’utiliser les mêmes secrets dans plusieurs applications ou si vous avez besoin de stratégies d’accès et fonctionnalités d’audit affinées, utilisez plutôt Azure Key Vault.

Configurer un domaine personnalisé et SSL

Si votre application web est visible sur un domaine personnalisé, elle devra être mappée à ce domaine. Pour plus d’informations, consultez Tutoriel : Mapper un nom DNS personnalisé existant à Azure App Service.

Ensuite, vous devrez lier le certificat SSL de ce domaine à votre application web App Service. Pour plus d’informations, consultez Sécuriser un nom DNS personnalisé avec une liaison SSL dans Azure App Service.

Importer des certificats back-end

Tous les certificats de communication avec les systèmes back-end, comme les bases de données, doivent être mis à disposition dans App Service. Pour plus d’informations, consultez Ajouter un certificat SSL dans App Service.

Migrer des sources de données, des bibliothèques et des ressources JNDI

Pour connaître les étapes de configuration de la source de données, consultez la section Sources de données de Configurer une application Java Linux pour Azure App Service.

Pour obtenir des instructions supplémentaires sur les sources de données, consultez les sections suivantes de la page JNDI Datasource How-To (Guide pratique sur les sources de données JNDI) dans la documentation Tomcat :

Migrez toutes les autres dépendances classpath au niveau du serveur en suivant les mêmes étapes que pour les fichiers JAR de source de données.

Migrez toutes les autres ressources JDNI au niveau du serveur partagées.

Remarque

Si vous suivez l’architecture recommandée qui inclut un seul fichier WAR par application web, envisagez de migrer les bibliothèques classpath et les ressources JNDI au niveau du serveur dans votre application. La gouvernance des composants et la gestion des changements s’en retrouveront grandement simplifiées.

Migrer la configuration restante

À l’issue de la section précédente, vous devez avoir votre configuration de serveur personnalisable dans /home/tomcat/conf.

Effectuez la migration en copiant toutes les configurations supplémentaires (par exemple, domaines et JASPIC).

Migrer des tâches planifiées

Pour exécuter des tâches planifiées sur Azure, envisagez d’utiliser un déclencheur de minuteur pour Azure Functions. Vous n’avez pas besoin de migrer le code de la tâche lui-même dans une fonction. La fonction peut simplement appeler une URL dans votre application pour déclencher la tâche. Si de telles exécutions de tâches doivent être appelées dynamiquement et/ou suivies de manière centralisée, utilisez Spring Batch.

Vous pouvez également créer une application logique avec un déclencheur de périodicité pour appeler l’URL sans écrire de code en dehors de votre application. Pour plus d’informations, consultez Vue d’ensemble - Qu’est-ce qu’Azure Logic Apps ? et Créer, planifier et exécuter des tâches et des workflows récurrents avec le déclencheur Périodicité dans Azure Logic Apps.

Remarque

Pour empêcher toute utilisation malveillante, vous devrez probablement veiller à ce que le point de terminaison d’appel de tâche demande des informations d’identification. Ainsi, la fonction du déclencheur a besoin de fournir les informations d’identification.

Redémarrage et test de détection de fumée

Enfin, vous avez besoin de redémarrer votre application web pour appliquer tous les changements de configuration. Une fois le redémarrage terminé, vérifiez que votre application s’exécute correctement.

Post-migration

Maintenant que votre application a migré vers Azure App Service, vous devez vérifier qu’elle fonctionne comme prévu. Une fois que vous avez terminé, nous vous fournissons des recommandations pour rendre votre application plus native dans le cloud.

Recommandations