- Dans des environnements où le nombre de cibles de configuration augmente, comme Kubernetes, multiplier les fichiers YAML écrits à la main atteint vite ses limites, et une approche qui génère les données de configuration devient plus adaptée que les templates YAML
- Les charts Helm injectent des valeurs via
values.yaml et des templates Go, mais dès qu’entrent en jeu des champs optionnels, des tableaux ou des maps, le poids des conditions et de l’indentation augmente fortement
- YAML impose des règles strictes sur les espaces, mais le parseur de templates Helm ne comprend pas la structure YAML, si bien que la combinaison de
toYaml et indent conduit facilement à une génération de configuration fragile
- YAML étant un sur-ensemble de JSON, les conversions entre les deux sont simples, et Jsonnet traite la génération d’objets de configuration comme du code grâce aux variables externes, aux champs conditionnels, à la composition de maps et à la fusion d’objets
- kr8 adopte un flux basé sur Jsonnet pour créer et manipuler les configurations de plusieurs clusters Kubernetes, en préférant générer et transformer directement des objets plutôt que d’assembler des chaînes YAML complexes
La complexité de la configuration commence quand le nombre de fichiers YAML augmente
- Dès que les applications et l’infrastructure dépassent une certaine taille, la complexité de configuration augmente rapidement
- Quand il n’y a qu’une ou deux cibles de déploiement, écrire directement les fichiers de configuration YAML peut suffire, mais au-delà, il faut gérer la configuration de manière structurée
- Si plusieurs fichiers de configuration sont nécessaires, c’est généralement parce que certaines valeurs diffèrent pour une même cible
- des déploiements par environnement comme
dev, stg, prod
- des déploiements par région comme Europe, Amérique du Nord
- Toutes les configurations ne sont pas différentes, mais si les écarts sont suffisamment importants, il faut séparer et gérer d’un côté les parties communes et de l’autre les différences
- Le domaine de la gestion de configuration traite ce problème depuis longtemps, et divers outils ont utilisé YAML chacun à leur manière
- hiera, inclus dans Puppet, permet de rechercher des variables de façon hiérarchique, ce qui est puissant et flexible, et réduit fortement le besoin de templatiser le YAML lui-même
Les problèmes des templates YAML mis en évidence par les charts Helm
- Avec le cloud computing et Kubernetes, les cibles de configuration se sont étendues au-dessus de la couche système d’exploitation, et des outils comme CloudFormation et Helm sont apparus
- Un chart Helm peut être rendu à partir de paramètres externes définis dans
values.yaml
- Les valeurs de chaîne simples sont relativement faciles à gérer
image: "{{ .Values.image }}"
- Si une valeur
image est définie dans values.yaml, elle est injectée dans le template
- Les choses se compliquent dès qu’on commence à gérer des configurations plus complexes, comme les champs optionnels
{{- with .resourceGroup }}
resourceGroup: {{ . }}
{{- end }}
- Comme une valeur optionnelle ne peut pas simplement être laissée vide, il faut des conditions et des boucles, et le template devient vite désordonné
- Pour insérer un tableau ou une map, il faut combiner
toYaml et indent
{{- with .Values.podAnnotations }}
annotations:
{{ toYaml . | indent 8 }}
{{- end }}
- L’appel d’une fonction qui reconvertit du YAML en YAML avec
toYaml paraît déjà maladroit, mais le vrai problème est la gestion des espaces
Le conflit entre les règles d’espacement de YAML et le moteur de templates
- YAML impose des règles strictes d’indentation et d’espacement
- L’exemple suivant n’est ni un YAML valide ni un YAML complet
something: nothing
hello: goodbye
- Si un humain l’écrit directement, quelques pressions sur Retour arrière suffisent à corriger le problème, mais générer du YAML avec un système de templates n’a rien de simple
- Dès qu’on dépasse 5 à 10 fichiers de configuration, il devient nécessaire de générer la configuration plutôt que de l’écrire directement
- Pour insérer la valeur de
.Values.podAnnotations sous annotations, déjà indenté, il faut que cette valeur soit elle-même indentée exactement au bon niveau
- Comme le parseur de templates Go ne comprend pas YAML, essayer d’indenter joliment la syntaxe de template pose lui aussi problème
{{- with .Values.podAnnotations }}
annotations:
{{ toYaml . | indent 6 }}
{{- end }}
- Quand un système de templates manipule à la fois les espaces et les conditions sans connaître la structure YAML, la génération de configurations complexes devient de plus en plus difficile
- Écrire directement du JSON n’est pas non plus adapté, à cause de l’absence de commentaires et des problèmes de virgules oubliées ; c’est d’ailleurs ce genre d’inconfort qui a favorisé l’usage de YAML
Jsonnet est un langage de templates de données pour générer des configurations JSON
- YAML est un sur-ensemble de JSON, donc les conversions entre JSON et YAML sont simples
- De nombreuses applications et de nombreux langages savent parser ou convertir JSON et YAML nativement
- En Python aussi, on peut lire du YAML et produire du JSON
python -c 'import json, sys, yaml ; y=yaml.safe_load(sys.stdin.read()) ; print(json.dumps(y))'
- Jsonnet se présente comme un langage de templates de données, dont l’objectif principal est de générer des configurations JSON
- Le contexte de conception de Jsonnet est expliqué dans sa design rationale
Variables externes et gestion des champs optionnels
- Jsonnet permet d’injecter des valeurs de configuration via des variables externes
{
image: std.extVar('image'),
}
- En passant une variable externe en ligne de commande, on obtient un résultat JSON
jsonnet image.jsonnet -V image="my-image"
{
"image": "my-image"
}
- Les champs optionnels peuvent être exprimés comme des conditions dans le code, sans insérer de logique conditionnelle au milieu d’une chaîne de template
// define a variable - yes, jsonnet also has comments
local rg = null;
{
image: std.extVar('image'),
// if the variable is null, this will be blank
[if rg != null then 'resourceGroup']: rg,
}
- Si
rg vaut null, le champ resourceGroup n’est pas inclus dans le résultat
- Si une valeur est fournie, le champ est produit
Manipuler des maps et des objets est plus simple que gérer l’indentation YAML
- Quand il faut placer une map dans une configuration, comme pour des annotations de pod Kubernetes, Jsonnet permet de définir la valeur comme variable puis de la placer dans l’objet
local annotations = {
'nginx.ingress.kubernetes.io/app-root': '/',
'nginx.ingress.kubernetes.io/enable-cors': true,
};
{
metadata: { // annotations are nested under the metadata of a pod
annotations: annotations,
},
}
- Cette approche est bien plus simple que d’ajuster l’indentation dans un template YAML
- Le résultat généré est un objet JSON contenant la map d’annotations sous
metadata.annotations
{
"metadata": {
"annotations": {
"nginx.ingress.kubernetes.io/app-root": "/",
"nginx.ingress.kubernetes.io/enable-cors": true
}
}
}
- Ajouter une annotation à un objet existant peut aussi se faire dans Jsonnet avec l’opérateur
+
local annotations = {
'nginx.ingress.kubernetes.io/app-root': '/',
'nginx.ingress.kubernetes.io/enable-cors': true,
};
{
metadata: {
annotations: annotations,
},
} + { // this adds another JSON object
metadata+: { // I'm using the + operator, so we'll append to the existing metadata
annotations+: { // same as above
something: 'nothing',
},
},
}
- L’objet résultant contient l’annotation existante ainsi que
something: "nothing"
{
"metadata": {
"annotations": {
"nginx.ingress.kubernetes.io/app-root": "/",
"nginx.ingress.kubernetes.io/enable-cors": true,
"something": "nothing"
}
}
}
- Dans un exemple simple, le code peut sembler plus long, mais plus la configuration devient complexe, plus cette façon de manipuler les objets devient utile
kr8 gère les configurations Kubernetes avec l’approche Jsonnet
- kr8 utilise cette méthode pour créer et manipuler simplement les configurations de plusieurs clusters Kubernetes
- Le principe central consiste à générer des objets de configuration JSON et à les transformer selon les besoins, plutôt qu’à assembler des templates YAML à coups d’espaces et de conditions
1 commentaires
Avis sur Hacker News
J’en ai désormais complètement assez des configurations écrites en YAML. C’est ce que je déteste le plus dans GitHub Actions, pire encore que sa fiabilité
Quand je vois un excellent outil exiger un fichier YAML pour sa configuration, je m’inquiète immédiatement. Il en va de même pour les langages de configuration propriétaires comme le HCL de Terraform ou l’ASL d’AWS Step Functions
Vouloir une API déclarative, c’est très bien, mais j’aimerais qu’on puisse générer cette déclaration par programme. Déclarer et générer la configuration avec du code a été une bien meilleure expérience, et AWS CDK le fait vraiment bien
On peut écrire des définitions d’infrastructure cloud avec un langage typé et une bonne prise en charge par l’IDE, sans dépendre d’un plug-in qui n’a pas été mis à jour depuis deux ans
deno fmta un formateur JSON, mais pas de formateur YAMLLe formateur JSON est un binaire unique qui s’exécute en quelques millisecondes, alors que pour formater automatiquement du YAML, il faut en pratique utiliser Prettier, qui dépend de la moitié de NPM et met environ 2 secondes à démarrer et à s’exécuter
J’ai donc déplacé vers JSON tous les fichiers YAML qui pouvaient l’être dans le dépôt de l’entreprise, et au moins moi, j’en suis beaucoup plus satisfait. Personne ne s’en est plaint
Plusieurs éditeurs prennent aussi en charge la balise
$schemade JSON. Nous avons ajouté cette fonctionnalité au produit, et c’est vraiment agréable de pouvoir créer un fichier de configuration en appuyant simplement sur Tab, sans lire la documentationC’est aussi possible avec YAML via YAML language server, mais comme la touche Tab sert aussi à l’indentation, l’ergonomie est médiocre. JSON n’est pas parfait non plus, mais au moins le texte
"no"n’est pas vraiNe suffirait-il pas d’ajouter un filtre qui supprime les commentaires avant de lire la configuration ? Cela ne peut pas être plus difficile que de passer à YAML
Je ne comprends pas non plus vraiment l’idée selon laquelle YAML serait plus lisible. La douleur liée à la gestion de la configuration ne vient pas du fait qu’on passe quelques secondes de moins à analyser des accolades et des crochets, mais du fait qu’il est difficile de comprendre ce qui ne va pas, au milieu de centaines de lignes de configuration, à cause d’un espace manquant ou d’une tabulation
Ansible commet la même erreur, tout comme une multitude d’outils
Je ne sais pas vraiment si CDK fonctionne de cette façon. Quand je l’ai un peu essayé, l’expérience était assez différente de celle de ma « génération CloudFormation », et je n’ai pas vraiment saisi les avantages de CDK
J’avais l’impression qu’on remplaçait le problème YAML/templates par un problème d’héritage et de magie. J’aimerais entendre davantage de retours de personnes ayant utilisé AWS CDK, Terraform CDK et Pulumi
https://github.com/actions/runner/issues/1182
Je suis d’accord pour dire que les templates YAML sont assez délirants, mais je n’ai jamais compris pourquoi on n’arrête pas d’utiliser de faux langages pour passer à un vrai langage de programmation
Si l’on a besoin d’une logique complexe, il suffit de générer du YAML/JSON/ce qu’on veut avec un langage de programmation. Ruby, Python ou n’importe quel autre langage fournit ce qu’il faut, sans pseudo-langages bizarres comme Jsonnet ou les templates Go
Il suffit d’écrire du code : on se fait beaucoup moins piéger par les problèmes opaques et étranges des moteurs de templates. N’importe quel vrai langage sera largement préférable
J’avais utilisé Chef pour des tâches similaires, et comme c’était du Ruby, j’appréciais de pouvoir définir facilement la logique voulue, utiliser des boucles et de vraies variables
Je comprends qu’Ansible ait été conçu pour des non-programmeurs, mais pour quelqu’un à l’aise avec les bases de la programmation, rien n’est plus infernal que d’enfermer des playbooks Ansible riches en tâches conditionnelles et en itérations dans la syntaxe verbeuse des templates Jinja
Aujourd’hui, la norme consiste plutôt à prendre un parseur JSON/TOML/YAML et à écrire une fonction
readConfig, même dans des cas où un interpréteur embarqué serait plus adaptéDu point de vue des développeurs, il est plus facile d’ajouter de la complexité à un format de configuration que de fournir un véritable embedding de langage avec des bindings vers l’application. On dirait donc qu’ils ont oublié la méthode elle-même, ou qu’ils n’imaginent même pas que ce soit possible
À l’époque de Chef/Puppet, beaucoup d’organisations ont commencé à mettre de la logique dans leur IaC et se sont retrouvées avec d’immenses bazars impossibles à mettre à niveau ou à maintenir. L’approche Chef/Pulumi est possible, mais elle exige des personnes très strictes sur le style et la maintenance
Pour les grandes équipes et la maintenance à long terme, je pense que le modèle Terraform/Puppet est meilleur. Même si HCL est pénible et que Python/TypeScript, etc. donnent une impression de libération, le code purement déclaratif évite beaucoup de spaghetti
Ils veulent y mettre les éléments de conception à la mode, veulent l’auto-hébergement, et finissent aussi par vouloir permettre d’écrire un serveur web multithread rapide, ce qui rend le tout conceptuellement complexe
Il faudrait un langage jouet simple, à la Logo, pour les ingénieurs système/DevOps. À l’origine, il devrait pouvoir être expliqué dans un livre de la taille du K&R C
Il faudrait un typage dynamique, des structures de contrôle apprenables en un week-end, pas de threading ni de concurrence, pas d’orienté objet ni d’héritage, une conception fonctionnelle/modulaire, et un modèle de FFI permettant d’appeler facilement d’autres langages et frameworks, et d’être appelé par eux
Le problème, c’est que les passionnés de langages ne savent pas se retenir : ils ajoutent sans cesse des fonctionnalités, qui finissent dans les bibliothèques de base et les guides de style, si bien que même les débutants doivent tout apprendre
Moi aussi, je serais tenté d’ajouter des fonctions du genre
each/mapaux tableaux/hashmaps, puis des fonctions de première classe et des closures, mais ce serait peut-être une erreur. Il existe déjà des langages fonctionnels immuables pour la configuration, mais plus de 95 % des gens qui utilisent du YAML templatisé ne veulent pas apprendre à programmer de cette manière, ce qui rend leur adoption difficileLa configuration devient plus simple, plus facile à consommer et plus facile à documenter. Mais lorsqu’on écrit les fichiers de configuration, il faut utiliser un langage de programmation, de préférence un langage statiquement typé offrant vérification des erreurs, autocomplétion et documentation inline
AWS CDK en est un bon exemple. Écrire du CloudFormation pur est pénible, mais CDK n’ajoute pas des fonctionnalités de programmation à CloudFormation : il génère du CloudFormation. L’entrée consommée par AWS reste du CloudFormation relativement simple et stable
Rien qu’en voyant le titre, je me suis dit que ça parlerait de Kubernetes
L’API Kubernetes est assez intuitive et dispose d’un schéma JSON bien défini. La majeure partie du temps passé à apprendre k8s devrait servir à comprendre comment utiliser l’API, mais en pratique elle sert à comprendre comment utiliser les charts Helm
Je n’ai pas l’impression que Jsonnet, Ksonnet, Nu ou CUE aient connu un si grand succès. La plupart des gens semblent utiliser Kustomize, parce que c’est relativement intuitif et intégré à
kubectlL’outil que je voudrais devrait fournir aux auteurs de définitions une vérification de types, une validation et des avertissements de dépréciation de versions pour le schéma k8s, produire un artefact unique que les utilisateurs puissent facilement inspecter, échouer atomiquement si le cluster ne prend pas en charge certains objets/versions, et être intégré à la chaîne d’outils de base
Un script TypeScript Bun ou Deno qui exporterait une fonction prenant des arguments et renvoyant une liste de définitions irait probablement bien avec
deno compileet autres, mais cela enfreindrait la condition d’intégration à la chaîne d’outils de baseOn est protégé des détails de bas niveau, mais quand un problème survient, on doit affronter une énorme pile d’abstractions qui rend le diagnostic et le débogage difficiles
Il devient beaucoup plus difficile de comprendre ce qui se passe réellement, et on dépend des couches d’abstraction, avec les mises à jour publiées par les fournisseurs et les autres problèmes dans le graphe des dépendances
Il fait à peu près ce dont nous avons besoin sans problème, il est multiplateforme et utilisable dans plusieurs langages. Je l’ai intégré dans des exécutables C++, .NET et JVM
La configuration JSON produite peut être utilisée avec un vaste écosystème d’outils qu’on trouve difficilement avec les alternatives toml/yaml/hocon/ini, etc. J’ai essayé d’utiliser HOCON dans des langages non JVM, mais il y avait toujours un cas limite qui coinçait
Mais lorsqu’on gère réellement de gros systèmes, on ne peut finalement pas éviter les avantages des templates
C’est amusant de voir à quel point les développeurs réfléchissent peu à la bonne façon de gérer la configuration
On dirait simplement un ensemble de clés et de valeurs stockées dans un fichier ou générées par du code, mais en réalité c’est tout. C’est la programmation elle-même
Tout est configuration, et tous les arguments de fonction sont aussi une forme de configuration. Toute configuration dans un fichier externe finit d’une manière ou d’une autre par devenir un argument de fonction
Le problème, c’est la représentation en texte brut du code. Les fichiers de configuration déclaratifs semblent pratiques parce qu’on peut tout voir au même endroit, mais quand on fait de la configuration un programme, il devient difficile de trouver quoi modifier
Si le code s’exécutait en temps réel pour montrer la représentation de la configuration finale, et permettait de retracer comment chaque valeur finale a été générée, ce ne serait pas un problème. Pourtant, même si cette fonctionnalité est assez simple, aucun système n’est conçu de cette façon. La configuration est toujours une réflexion après coup
Si l’on étend ce concept à toute la programmation, on devrait pouvoir voir tout le code qui dépend d’une valeur de configuration donnée, ainsi que ses transformations
De plus, la plupart des configurations sont relationnelles ou orientées graphe, si bien qu’il vaudrait peut-être mieux les placer dans une base de données centrale. Les différentes valeurs de configuration sont liées entre elles. Il faudrait donc consulter la configuration dans une base de données ou un éditeur de graphe
Dès qu’on sort du texte brut, les choses commencent à devenir beaucoup plus simples, mais les fonctionnalités de langage évoquées plus haut restent nécessaires
Les configurations essaient d’utiliser des conventions de nommage pour regrouper les variables liées
J’aimerais passer à de vraies structures de données imbriquées, probablement en JSON, mais les ingénieurs refusent absolument d’écrire du code, donc la configuration en tant que code est impossible. Il y a aussi les inconvénients mentionnés plus haut
L’idée suivante est qu’il faudrait un meilleur moyen d’afficher et de modifier la configuration. J’ai pensé à une interface visuelle permettant d’explorer la représentation du produit final, de sélectionner des pièces et de modifier les paramètres de cette manière
Je me demande si cette direction est la bonne. Sinon, j’aimerais qu’on m’explique un peu plus. Le cœur de cette application, c’est la configuration
Le pire, c’est que dans des endroits comme la CI/CD, YAML devient presque un langage de programmation. Un langage très verbeux, peu intuitif, mal spécifié et différent selon les fournisseurs
Même avec les DTD et la validation XML, on retrouvait ces caractéristiques familières : des erreurs qui n’apparaissaient que tardivement et dont les messages étaient difficiles à interpréter
À l’époque, beaucoup de frustrations visaient XML, mais quand on voit l’enfer YAML du milieu des années 2020, le problème n’était pas le langage de balisage lui-même
Je déteste vraiment enfouir de la logique quelque part dans des templates YAML
[0] https://tanzu.vmware.com/developer/guides/ytt-gs/
Je suis vraiment triste que Helm ait gagné. Au travail, je m’occupe de sujets open source liés à k8s, et 100 % des utilisateurs nous ont demandé de créer des charts Helm, donc on a fini par devoir le faire
C’est misérable à travailler. Les fichiers s’appellent
foo.yaml, mais en réalité ce n’est pas du YAML, donc l’éditeur ne peut pas aider. Il faut faire passer toutes les données parindent 4pour que l’alignement YAML soit correctLe plus déprimant, c’est qu’il faut réexposer toutes les fonctionnalités de Kubernetes à sa propre manière. Si quelqu’un veut ajouter
deployment.spec.template.spec.fooBars, il faut ajouterdeploymentFooBarsdansvalues.yamlet le relier. Ça se répète pour chaque fonctionnalitéC’est vraiment un cas où « worse is better » a mal tourné. Moi aussi, il m’est arrivé de faire des horreurs comme
sed -e s/$FOO/foo/gpour implémenter des templates, et Helm a probablement commencé comme ça aussi. Le résultat est un désordrePersonnellement, j’utilise Kustomize depuis avant son intégration à
kubectl, et j’en ai toujours été assez satisfait. Il a beaucoup de bizarreries, mais au moins il comprend la sémantique des objets qu’il génère, ce qui fait gagner du tempsJsonnet est bien meilleur. Dans le cadre de notre appli k8s, nous fournissons aussi un déploiement Envoy pour du routage de trafic complexe ; la configuration d’Envoy est verbeuse, mais facile à gérer avec Jsonnet : https://github.com/pachyderm/pachyderm/blob/master/etc/gener...
J’envisage sérieusement de transpiler jsonnet vers le langage de templates de Go et de tout implémenter en Jsonnet. Au moins, ce serait un peu maintenable, et comme
helm installfonctionnerait tout simplement, personne ne s’en rendrait compteMais j’ai l’impression que Helm finira par causer la perte de Kubernetes. Si un outil concurrent d’allocation de machines / d’exécution de conteneurs arrive avec un vrai langage de configuration, tout le monde basculera du jour au lendemain
sed -e s/$FOO/foo/g, il vaut mieux jeter un œil à envsubst, une solution un peu plus standard et meilleureSi le sujet est de templater ou modifier des charts Helm avec jsonnet, Tanka peut aussi aider : https://tanka.dev/helm
Cela dit, les endroits où j’ai travaillé ont encore peur du changement et continuent d’utiliser tf/hcl et helm tels quels. Au moins, dans mes projets personnels, je respire un peu mieux
Je pense qu’il y a un problème ici. Mais je ne sais pas trop si le genre de personne qui choisit YAML comme langage de configuration y verra un problème
Il y a un conflit direct entre la représentation des données centrée sur l’humain et celle centrée sur la machine. Les ordinateurs aiment quelque chose qui ressemble à Lisp, les humains aiment quelque chose qui ressemble à Python
Si l’on veut manipuler la configuration Kubernetes par programme, le fait que Kubernetes utilise YAML devient assez agaçant. Mais la communauté Kubernetes semble surtout composée de gens du camp YAML ; pourquoi se soucieraient-ils du fait que travailler sur des fichiers de configuration devient horrible dès qu’on y ajoute de la logique de programmation ?
C’est précisément l’un des défauts de YAML dans ce contexte, et je pense que les gens autour de k8s sont généralement assez intelligents pour l’avoir anticipé
Je ne pense pas que « YAML est un sur-ensemble de JSON » soit vrai en pratique, quoi que les auteurs de la spécification écrivent dans la documentation. Si l’on convertissait toute la configuration YAML en JSON, les équipes DevOps se mettraient en colère
Les deux formats de données peuvent représenter la même sémantique, mais c’est aussi le cas de tous les langages qui se compilent vers la même architecture CPU. JSON et YAML sont distincts en pratique, et les mélanger n’est pas une bonne idée
Bien sûr, les gens ont fini par les écrire à la main, puis quand c’est devenu insupportable, ils ont commencé à y ajouter des templates. Les choses semblent toujours évoluer comme ça
Le texte écrit à la main n’est pas remplacé par du texte sérialisé de configuration générée par machine ; il est généralement remplacé par du texte toujours écrit à la main, mais avec des templates par-dessus
Mon principe personnel est qu’il ne faut pas utiliser l’interpolation de chaînes pour générer du code destiné à être lu par des machines. Un langage de template n’est rien d’autre qu’une interpolation de chaînes sophistiquée
On a tous vu les conséquences de l’injection SQL et du cross-site scripting. Tant qu’on continuera à envoyer du texte arbitraire à un interpréteur, ce genre de choses continuera à arriver
C’est pourquoi je pense qu’il ne faut pas non plus utiliser de fichiers de template pour produire du HTML
Comme alternatives aux langages de template pour HTML, il y a Haml en Ruby et Pug en JavaScript. Ces langages fournissent une méthode définie pour spécifier l’arbre complet des balises, attributs et nœuds de texte
Si vous n’aimez pas l’indentation significative à la Python, il existe JSX en JavaScript. Les parties de JSX qui ressemblent à du HTML sont compilées en expressions
createElementqui construisent l’arbre du document web, lequel peut ensuite être sérialisé en HTML si nécessaireHaml, Pug et JSX peuvent produire du HTML, mais ce ne sont pas des langages de template. De la même façon,
JSON.stringify(myObj)n’est pas un langage de template pour JSONLe code lu par des machines devrait, quand c’est possible, être généré par des outils qui comprennent et exploitent la structure connue du langage cible
Haml est un système de templates destiné à éviter le code inline dans les documents web et à rendre le HTML plus propre, et Pug est un moteur de templates riche en fonctionnalités pour Node.js
Je peux admettre que JSX n’est pas, à proprement parler, un langage de template
Au final, ils se compilent tous en HTML. Simplement, ce n’est pas de l’interpolation de chaînes : ce sont des langages analysés en arbres syntaxiques puis rendus en HTML à partir d’une compréhension interne de la structure valide
Les templates YAML sont de l’interpolation de chaînes sophistiquée, et ne sont pas des langages de template, ou du moins ce sont des langages de template très mal implémentés
Ma règle personnelle est que chaque fois qu’une valeur est insérée dans une chaîne, elle doit impérativement être encodée correctement
J’ai écrit un billet à ce sujet il y a quelque temps : https://kevincox.ca/2022/02/08/escape-everything/
En résumé, toutes les chaînes ont un format à respecter, comme HTML, SQL ou une sortie de terminal destinée à des humains. Chaque fois qu’on insère une valeur dans une chaîne, il faut l’encoder correctement pour ce format, mais nous ne le faisons presque jamais
Nous sommes en train de migrer vers cuelang [1]. Personnellement, je trouve sa conception meilleure que celle de Jsonette
Kubernetes dispose déjà d’une réconciliation d’état ; la seule chose qui manquait dans cette configuration était la suppression, et c’est désormais possible avec la fonctionnalité prune [2]
[1] https://cuelang.org/docs/integrations/k8s/
[2] https://kubernetes.io/blog/2023/05/09/introducing-kubectl-ap...
Certains messages d’erreur sont un peu difficiles à interpréter, mais comme il détecte énormément d’erreurs en amont, c’est acceptable. Désormais, les rares moments où je dois écrire du YAML directement me semblent terriblement fastidieux en comparaison
Dans ce genre de situation, j’interviens généralement avec : « Avez-vous entendu parler de notre sauveur CUELang ? » : https://cuelang.org/
Il n’est pas encore Turing-complet, mais il est suffisamment expressif pour éliminer les doublons ; on peut définir schémas et données dans le même langage, dans le même fichier ou dans des fichiers séparés, et il prend aussi en charge les types union
Il peut générer du YAML ou du JSON, et valider ses propres fichiers ainsi que des fichiers YAML/JSON
Son principal inconvénient est que l’implémentation actuelle est uniquement en Go, ce qui peut imposer de passer par des sous-processus ou du FFI
Ensuite, il produit des fichiers JSON pour chaque application, un outil génère des définitions XML, ces définitions sont appliquées à un fichier XLS détenu par les architectes, puis celui-ci recrache le YAML à appliquer aux charts Helm
Le chart déploie le client k8s, et ce client interagit avec le cluster principal via l’API, en JSON
Cela a pris un peu de temps, mais nous utilisons le meilleur outil pour chaque tâche