La configuration en Drupal 8 : plusieurs besoins et solutions

Remarques générales sur la configuration en Drupal 8

Drupal 8 possède une API dans son noyau permettant l'export et l'import de configuration, aussi appelée CMI pour Configuration Management Initiative. Ce que ne permettaient pas nativement les versions précédentes.

Dans les versions précédentes

En Drupal 6 et 7, la solution la plus largement répandue pour palier à ce manque est l'utilisation du module Features permettant d'exporter la configuration dans des fichiers.

Features a pour but de permettre de grouper la configuration en brique fonctionnelle et permettre la réutilisation de fonctionnalités d'un site à l'autre (cela est toujours le cas en Drupal 8).

Drupal 6 et Drupal 7 ne possédant pas de système de déploiement de la configuration, Features est également utilisé pour cet usage, usage non prévu à la base. Ce qui fait qu'il peut y avoir parfois certains problèmes facilement résolus une fois qu'ils sont identifiés.

Le cas standard est la suppression d'un champ en environnement de développement, le retrait de son code dans la feature et l'oubli de faire un hook_update_N pour supprimer le champ lors d'un déploiement. En effet, Features peut créer des champs lors d'un import de configuration car ils sont dans le code des features exportés, mais ne peut supprimer des champs qui ne sont plus dans son code. Cela supposerait de devoir supprimer tous les champs non exportés dans des features !

En Drupal 7, Features permet donc de gérer l'export et l'import de configuration et fait globalement l'unanimité dans la communauté Drupal. De plus d'autres solutions existent comme :

  • gérer entièrement la conf avec des hook_install et hook_update_N

  • l'utilisation de modules comme Config in Code (je n'ai personnellement jamais eu l'occasion de tester)

  • scripting via des commandes Drush ?

  • autre ?

Avantages avec Drupal 8

Avec Drupal 8, il y a eu plusieurs avancées sur le sujet de la gestion et du déploiement de la configuration.

  1. L'uniformisation du stockage

Là où en Drupal 7, il y avait une table « variables » stockant la plupart des variables et chaque modules ajoutaient ses tables custom pour stocker sa configuration plus complexe, comme les modules Views, Panels, etc., désormais Drupal 8 possède une table « config » dans laquelle toute la configuration, que ce soit de la configuration simple (l'équivalent des variables de Drupal 7) ou que ce soient des entités de configuration (views, styles d'image, types de contenu, etc.), est sérialisée.

Ce n'est donc plus à chaque module de fournir son stockage de configuration et s'intégrer à Features pour être exportable/importable.

  1. L'introduction des entités de configuration

Abordé au point précédent, lorsqu'un module a désormais de la configuration pouvant être instanciée plusieurs fois (styles d'image, index de recherche, formulaires de contact, etc.), il est désormais possible de créer des entités de configuration avec une classe de base simplifiant les développements.

De plus, merci à la Drupal console de permettre la génération de type d'entité (contenu ou configuration) simplement.

  1. L'introduction des States

En Drupal 8, il y a également séparation entre les données à exporter d'un environnement à l'autre (configuration), des données propres à un site sur un environnement données (état / state). Ces dernières n'étant pas exportables.

Cela permet de stocker des données, par exemple le timestamp de la dernière exécution du CRON Drupal ou si le site est en mode maintenance ou non, sans risquer de les exporter dans des features comme en Drupal 7. Car en Drupal 7, ces données étaient généralement stockées dans des variables faute de mieux.

  1. La surcharge de la configuration dans les settings

Avec Drupal 7, il est possible de forcer la valeur de variables en écrivant la valeur dans le fichier settings.php. À chaque exécution, Drupal va lire le fichier et utiliser la valeur à l'intérieur, il va de plus mettre cette valeur en base de données.

En Drupal 8, il est toujours possible de faire cela, à 2 différences près :

  1. La valeur surchargée dans le settings est bien utilisée à l'exécution mais n'est pas enregistrée en base de données. Ce qui a pour conséquences :

    1. Que la valeur surchargée dans le settings n'apparaît pas dans les formulaires de configuration, ce qui est assez perturbant la première fois que l'on teste la surcharge de configuration (l'issue à ce sujet).

    2. Que la valeur en base de données peut à nouveau être utilisée en retirant la surcharge du settings. Pas de risque d'écrasée la valeur originale avec la surcharge.

  2. Avec l'uniformisation du stockage, il est donc possible de surcharger des valeurs d'entités de configuration par environnement. Très pratique pour changer le nom de domaine d'un serveur Solr, Redis, Varnish, etc. d'un environnement à l'autre.

  1. Export des traductions de configuration

Avec le nouveau découpage des traductions entre traductions :

  • d'interface,

  • de configuration,

  • de contenu,

il est possible d'exporter et d'importer les traductions des configurations qui sont donc versionnées.

Inconvénients avec Drupal 8

Avec toutes ces améliorations, la gestion de la configuration en Drupal 8 c'est réglé une bonne fois pour toutes via le noyau… Et bien non ! Cela ne pouvait pas être aussi simple.

CMI a pas mal d'avantages, mais aussi des inconvénients :

  • Elle exporte TOUTE la configuration du site : pas possible d'avoir de la configuration par environnement et du coup on se retrouve par exemple à exporter la configuration fournie par des modules de développement et à devoir les avoir en production… Le but recherché est de s'assurer de l'intégrité et de la cohérence de la configuration fournie, ce qui n'est pas rien non plus.

  • Elle exporte la configuration dans UN seul dossier (+ des sous-dossiers pour chaque langue du site) : peu pratique pour le découpage fonctionnel.

  • Elle utilise les UUIDs pour vérifier que la configuration fournie ne provient pas d'un autre site et empêche donc son import si le site possède déjà un élément de configuration avec le même nom machine mais un UUID différent : dans le workflow pensé, il faudrait donc partir d'une base de données de production. Impossible pour un développeur de travailler sur un projet en recréant un site à partir de la configuration, obligation de repartir d'une sauvegarde de production.

  • Il est possible pour les modules, thèmes et profils d'installation de fournir de la configuration à l'installation (dossiers config/install et config/optional), mais la modification de ces fichiers n'est pas prise en compte une fois le module/thème/profil installé.

Pour palier à cela, en plus du port du module Features en Drupal 8, il y a eu une grosse quantité de modules en config_XXX pour trouver des alternatives pour avoir des workflows de développement évitant les problèmes évoqués.

En voici une liste non exhaustive, les modules sont groupés entre eux lorsqu'ils sont pensés pour fonctionner ensemble :

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

<troll>Heureusement que Drupal 8 était l'occasion d'éviter la divergence des efforts afin de fournir moins de modules mais de meilleurs qualité...</troll>

De cette masse de modules, ceux autour de « Configuration Split » commencent à avoir un bon nombre de sites les utilisant et font pas mal parler d'eux dans les articles de blog concernant Drupal. Mais est-ce LA solution ?

J'ai voulu m'y intéresser car il faut aussi le dire Features en Drupal 8 a des inconvénients :

  • Plus complexe qu'en Drupal 7, ce qui est compliqué pour les débutants (facile d'oublier d'exporter de la configuration),

  • Ne gère pas les traductions de configuration (l'issue à ce sujet),

  • Importe les features par ordre alphabétique au lieu de reconstruire les dépendances entre configuration, ce qui provoque des erreurs lorsque par exemple on importe un nouveau champ mutualisé entre plusieurs features.

  • Les thèmes ne peuvent être gérés par Features (l'issue à ce sujet), hors il serait logique que ce soit le thème qui apporte la configuration du placement des blocs qu'il comporte.

  • Ne compare pas la configuration active (en base de données) avec le bon fichier. Par exemple, pour la configuration des langues, Features va détecter la langue française dans un sous-module de test de Webform ou pour de la configuration simple comme le Cron, va comparer avec une valeur située dans un module du noyau au lieu de la configuration exportée dans une feature custom.

Le principal problème étant qu'avec CMI, les mainteneurs de Features ont exprimé que le périmètre fonctionnel du module en Drupal 8 est le packaging de configuration. Les problèmes d'import/export de configuration ne concernent plus le module.

Quelle solution pour quel besoin ?

Parce que les projets Drupal sont variés, voyons quelle solution correspond à quel besoin car la lecture des articles concernant la gestion de la configuration en Drupal 8 donne l'impression qu'il n'y a qu'une seule solution, j'en doute.

En effet, il peut y avoir plusieurs types de projet :

  • Usine à sites : fonctionnant via des profils d'installation

  • Site unique :

    • Configuration prédéfinie et non modifiable en production

    • Configuration prédéfinie et modifiable en production :

      • toute la configuration

      • uniquement certains points

  • etc.

Installer un site à partir de configuration existantes

Pour cela, on peut utiliser le profil d'installation Configuration installer, ce qui permet de d'utiliser CMI, sans nécessité de passer par une sauvegarde de base de données.

Attention : Configuration installer requiert d'avoir modules et thèmes en dehors du profil d'installation. En effet si le site fournissant la configuration initiale est parti d'un profil d'installation, cela peut être problématique :

  • Ce n'est pas idéal pour le découpage, il est courant qu'un profil fournisse ses modules et son ou ses thèmes dans son dossier.

  • Cela empêche l'utilisation des profils d'installation communautaires qui ont leurs modules et thèmes dans le dossier du profil.

Configuration installer s'utilisera donc plutôt pour un projet de site unique où l'on pourra :

  1. partir du profil d'installation standard,

  2. modifier la configuration

  3. exporter la configuration

  4. utiliser le profil d'installation Configuration installer

Faire un profil d'installation

Avec le besoin souvent lié d'usine à sites afin de créer des sites identiques sur le plan fonctionnel et identique ou proche au niveau design.

Passer par un profil d'installation permet d'ajouter des étapes de configuration lors de l'installation et permet donc plus de flexibilité qu'importer toute la configuration d'un site sans pouvoir la modifier.

Pour ce besoin, on peut utiliser Features afin de packager la configuration dans les modules.

La question à se poser ensuite est : une fois un site créé, faut-il le gérer avec Features ou CMI pour les mises à jour de configuration ?

Si l'on sait que l'usine à sites est prévue pour 600 sites, il sera lourd de versionner la configuration de 600 sites via CMI une fois qu'ils auront été créés. Dans ce cas, passer par Features avec des hook_update pour palier les problèmes cités précédemment de Features, est une solution.

Si l'usine est prévue pour une dizaine de site, il est possible ensuite de se baser sur CMI.

Ignorer certaines configuration par environnement

Le besoin standard est d'empêcher la présence de configuration et de modules de développement sur les environnements autres que ceux de développement.

Avec l'utilisation de Features, il est possible d'exporter cette configuration dans des modules activés uniquement sur les environnements de développement.

Avec CMI, cela n'est pas possible, mais avec l'ajout du module Config split dans le process, là il est désormais possible d'avoir de la configuration par environnement.

De plus avec le module Config ignore, il est possible d'éviter d'exporter/importer complètement certaines configurations.

Pouvoir ajouter/modifier de la configuration en production

Donner la possibilité d'ajouter ou modifier de la configuration en production est une demande assez courante. Par exemple donner la possibilité d'activer des langues, de modifier des panels, placer de nouveaux blocs, etc.

Avec Features, il faudra exclure les configurations concernées des features, quitte à les initialiser via des hook_install ou un module n'étant pas géré par Features.

Avec CMI, l'utilisation de Config ignore permet ici de répondre au besoin. Avec ce module il est possible de ne pas gérer certaines configuration en les précisant ou en utilisant des jokers (wildcards).

Plusieurs points d'attention :

  1. Il n'est pas possible d'initialiser de cette façon de la configuration lors d'un déploiement puis de permettre de la modifier en production. Il faudra alors l'initialiser via des hook_install ou hook_update_N.

    La fonctionnalité « graylist » de Config split permet d'avoir des configurations présentes sur chaque environnement mais avec des valeurs différentes. Mais ne permet quand même pas d'avoir une configuration initialisée lors d'un déploiement puis pouvant être modifiée en production.

  2. Attention avec les wildcards, j'ai lors de mes tests mis la configuration suivante dans Config ignore :

  • views.view.*

  • ~views.view.commerce_stores

Lors d'une installation avec Config installer, je n'avais plus que la vue whitelistée.

    Conclusion

    Il n'y a pas en Drupal 8 LA solution pour gérer sa configuration, même si de grands progrès ont été faits de ce côté là, il faut adapter le process en fonction du type de projet.

    Si vous voyez d'autres cas à gérer, n'hésitez pas à laisser un commentaire :), je testerai les solutions possibles.

    PS 1 : Pour l'utilisation de Config installer, il vaut mieux créer un profil d'installation custoim quasiment vide afin d'éviter que des modules comme Shortcuts ne soient activés et que le hook_install du profil d'installation standard ne soit exécuté.

    PS 2 : Après avoir pu échanger avec Fabien Bircher au sujet de Config Split, il est en effet possible avec Config Split de fournir de la configuration initale modifiable en production. Il faut pour cela définir un split de production qui servira à stocker les surcharges faîtes en production.

    Tags: 

    Commentaires

    > Plusieurs points d'attention :
    >
    > Il n'est pas possible d'initialiser de cette façon de la configuration lors d'un déploiement puis de permettre de la modifier en production. Il faudra alors l'initialiser via des hook_install ou hook_update_N.
    >
    > La fonctionnalité « graylist » de Config split permet d'avoir des configurations présentes sur chaque environnement mais avec des valeurs différentes. Mais ne permet quand même pas d'avoir une configuration initialisée lors d'un déploiement puis pouvant être modifiée en production.

    Je ne suis pas de comprendre ce point.

    En effet, il est toujours possible d'initier les configurations via l'installations d'un module et après de l'ignorer soit via config_ignore soit via config_split.

    Par contre, pour la modification cela dépendra du cas vis à vis des différentes possibilitées.

    Oui tu peux toujours initialiser la conf via config/install ou config/optional, mais ce que je voulais dire c'est que tu ne peux pas passer par CMI pour cela. Avec CMI, tu ne peux pas laisser la config être modifiée en production sans resynchroniser ce qui est versionné sinon au prochain déploiement tu vas écraser les modifs de prod.

    L'idée de passer par CMI est d'éviter d'utiliser config/install, config/optional, sinon ça revient "un peu" à passer par features.

    Est-ce plus clair désormais ?

    Ajouter un commentaire