Agnostic environment
Créer des logiciels indépendant de l'environnement d'exécution.
Si vous êtes un développeur junior, vous n'avez peut-être pas encore entendu parler du manifeste des Twelve-Factor App. Si c'est le cas, je vous conseille vivement de vous y intéresser : https://12factor.net/fr/.
Il y a, je crois, deux grands principes dans le développement logiciel. Ils devraient être les lignes directrices de tout développeur : les principes SOLID et le manifeste des Twelve-Factor Apps.
La configuration
Je voulais donc m'attarder sur l'un des éléments du manifeste Twelve-Factor, à savoir la configuration, qui devrait toujours être la plus agnostique possible : https://12factor.net/fr/config.
En fonction du type de logiciel et de son environnement d'exécution, deux approches sont à privilégier :
- Soit la configuration par variables d'environnement
- Soit la configuration par fichier
Cas concret
Pourquoi parler de cela ? Tout simplement parce que je suis retombé sur ce problème de configuration par environnement il y a peu de temps.
J'ai du, il y a peu travailler sur un projet où il fallait suffixer un fichier de configuration d'un magnifique _dev avant de le déployer sur les périphériques cibles (de dev). Car l'application, suivant qu'elle ait été buildé en dev ou prod, ne va chercher ledit fichier sous le même nom, et n'utilise pas la même clé de chiffrement pour le déchiffrer.
Cela implique donc d'ajouter du code pour gérer un nom de fichier de destination différent selon le type de build que l'on souhaite déployer ou tester...
Mais quel est le problème ?
En fait, ce choix d'implémentation oblige le logiciel à faire des tests conditionnels pour savoir dans quel environnement d’exécution nous sommes. Et ce type de tests peut potentiellement se retrouver un peu partout dans votre codebase.
En plus du risque d'oublier une condition quelque part, cela oblige surtout les développeurs à écrire du code uniquement pour eux-mêmes, et non pas pour répondre aux besoins du logiciel et de ses utilisateurs.
Il devient également compliqué voir impossible de gérer différents environnements supplémentaires.
On ajoute donc du risque pour notre "confort" ?! Non !!
Solution
La solution est présentée dans le manifeste Twelve-Factor, dans la rubrique "Configuration". Vous y verrez qu'il est préférable de passer par des variables d'environnement, et, si cela n'est pas possible, par un fichier de configuration externe à l'application (non buildé/compilé/embarqué dedans).
D'ailleurs, si vous y regarder de plus près, lorsque vous voulez héberger une BDD, une instance ElasticSearch, un Nextcloud, Matrix Synapse, Keycloak, ou que sais-je encore... Vous noterez qu'elles sont généralement configurables via des variables d'environnement. Et ce n'est sans doute pas un hasard 😇.
Comment faire concrètement ?
Évidemment, cela dépendra de votre langage de programmation. Je ne connais pas de langage de programmation n'offrant pas la possibilité de lire les variables d'environnement de l'OS à l'exécution. Vous trouverez facilement des librairies pour gérer vos configurations.
En Go par exemple, j'utilise Viper : https://github.com/spf13/viper. Cette librairie gère mes configurations (via des variables d'environnement ou des fichiers) de manière totalement transparente.
Si votre application doit se connecter à une BDD, en mettant la chaîne de connexion dans une variable d'environnement que vous lisez avant d'initialiser votre connexion, il suffit de la changer pour changer de BDD cible (dev, staging, prod, test, ...) sans toucher à quoi que ce soit dans l'application.
Cela vous garantit également l'iso-morphisme de votre application entre les différents environnements dev, local, tests et la production.
Et les applications web front ?
C'est un peu plus compliqué pour le front (l'environnement d'exécution étant le navigateur web du client). C'est néanmoins possible avec une bonne chaîne de build.
Là aussi, en dockerisant votre application, il suffit d'écrire un entrypoint
qui écrit un fichier de configuration, que JavaScript peut lire, correspondant à l'environnement dans lequel le container est exécuté. J'ai ainsi des applications front totalement agnostiques. Attention néanmoins a ne pas passer de credentials sensibles à votre front.
Lorsque les variables d'environnement ne sont pas disponibles
Et il y a le reste... Les applications Android, windows, mac ou linux standalone où l'utilisation de variables d'environnement est pas du tout pratique au vu du mode de diffusion de l'application.
Pour Android par exemple, vous pourrez utiliser des product flavors permettant de préparer une app en lui injectant votre configuration au moment du build.
Enfin pour les applications standalone (tout os) il sera préférable de passer par un fichier de configuration, yaml ou toml (voir json) dans le dossier de l'utilisateur.
Conclusion
Il y a dans cet article deux points essentiels :
- Nous ne devons pas ajouter de code uniquement pour notre confort. Vous vous en mordrez les doigts à coup sûr.
- Vos applications doivent être configurables soit via des variables d'environnement, soit via un fichier externe.