- En entornos donde crecen los destinos de configuración, como Kubernetes, aumentar manualmente la cantidad de archivos YAML pronto llega a un límite, y se vuelve más adecuado un enfoque que genere datos de configuración en vez de usar plantillas YAML
- Los Helm charts inyectan valores con
values.yaml y plantillas de Go, pero en cuanto aparecen campos opcionales, arrays o maps, aumenta la carga de manejar condicionales e indentación
- YAML tiene reglas estrictas de espacios, pero el parser de plantillas de Helm no entiende la estructura de YAML, por lo que la combinación de
toYaml e indent puede derivar fácilmente en una generación de configuración frágil
- YAML es un superconjunto de JSON, así que la conversión entre ambos es sencilla; Jsonnet trata la generación de objetos de configuración como código, con variables externas, campos condicionales, combinación de maps y merge de objetos
- kr8 usa un flujo basado en Jsonnet para crear y manipular configuraciones de varios clústeres de Kubernetes, y elige generar y transformar objetos directamente en lugar de ensamblar strings YAML complejos
La complejidad de la configuración empieza cuando aumenta la cantidad de archivos YAML
- Cuando las aplicaciones y la infraestructura superan cierta escala, la complejidad de la configuración crece rápidamente
- Si los destinos de despliegue son 1 o 2, escribir archivos de configuración YAML directamente puede ser suficiente, pero si aumentan más allá de eso, hay que gestionar la configuración de forma sistemática
- La razón por la que se necesitan varios archivos de configuración suele ser que, aun para el mismo destino, algunos valores difieren entre sí
- Despliegues por entorno como
dev, stg, prod
- Despliegues por región como Europe o North America
- No toda la configuración es distinta, pero si las diferencias son lo bastante grandes, hay que separar y gestionar las partes comunes y las partes diferentes
- El campo de la gestión de configuración lleva mucho tiempo tratando estos problemas, y varias herramientas han usado YAML a su manera
- hiera, incluido en Puppet, permite consultar variables de forma jerárquica, por lo que es potente y flexible, y reduce mucho la necesidad de usar plantillas sobre el propio YAML
Los problemas de las plantillas YAML que aparecen en Helm charts
- Con el cloud computing y Kubernetes, los destinos de configuración se expandieron hasta capas por encima del sistema operativo, y surgieron herramientas como CloudFormation y Helm
- Un Helm chart puede renderizarse recibiendo parámetros externos definidos en
values.yaml
- Los valores de string simples son relativamente sencillos
image: "{{ .Values.image }}"
- Si se especifica el valor
image en values.yaml, ese valor entra en la plantilla
- El problema crece cuando se empiezan a manejar configuraciones más complejas, como campos opcionales
{{- with .resourceGroup }}
resourceGroup: {{ . }}
{{- end }}
- Como los valores opcionales no pueden dejarse vacíos, se necesitan condicionales y loops, y la plantilla se ensucia fácilmente
- Al insertar arrays o maps, hay que combinar
toYaml e indent
{{- with .Values.podAnnotations }}
annotations:
{{ toYaml . | indent 8 }}
{{- end }}
- La llamada a una función que vuelve a convertir YAML en YAML con
toYaml ya resulta extraña, pero el problema mayor es el manejo de espacios
El choque entre las reglas de espacios de YAML y el motor de plantillas
- YAML tiene reglas estrictas de indentación y espacios
- El siguiente ejemplo no es YAML válido ni completo
something: nothing
hello: goodbye
- Si una persona lo escribiera directamente, podría corregirlo presionando Backspace algunas veces, pero al generar YAML con un sistema de plantillas no es tan simple
- Si se supera el nivel de 5 a 10 archivos de configuración, se vuelve necesaria la generación de configuración en vez de escribirlos directamente
- Para poner el valor de
.Values.podAnnotations debajo de annotations, que ya está indentado, el propio valor también debe indentarse al nivel exacto
- Como el parser de plantillas de Go no entiende YAML, surgen problemas incluso al intentar indentar la sintaxis de la plantilla para que sea legible
{{- with .Values.podAnnotations }}
annotations:
{{ toYaml . | indent 6 }}
{{- end }}
- Cuando un sistema de plantillas maneja espacios y condicionales sin conocer la estructura de YAML, generar configuraciones complejas se vuelve cada vez más difícil
- Escribir JSON directamente tampoco es adecuado por la ausencia de comentarios y los problemas de comas faltantes; por estas incomodidades se terminó usando YAML
Jsonnet es un lenguaje de plantillas de datos para generar configuración JSON
- YAML es un superconjunto de JSON, así que la conversión entre JSON y YAML es simple
- Muchas aplicaciones y lenguajes de programación pueden parsear o convertir JSON y YAML de forma nativa
- En Python también se puede leer YAML y emitir JSON
python -c 'import json, sys, yaml ; y=yaml.safe_load(sys.stdin.read()) ; print(json.dumps(y))'
- Jsonnet se define a sí mismo como un lenguaje de plantillas de datos, y su objetivo principal es generar configuración JSON
- El contexto de diseño de Jsonnet se puede consultar en su design rationale
Variables externas y manejo de campos opcionales
- Jsonnet puede inyectar valores de configuración usando variables externas
{
image: std.extVar('image'),
}
- Si se pasan variables externas desde la CLI, se genera el resultado JSON
jsonnet image.jsonnet -V image="my-image"
{
"image": "my-image"
}
- Los campos opcionales pueden expresarse como condiciones de código, sin insertar condicionales de plantilla dentro de strings
// 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 es null, el campo resourceGroup no se incluye en el resultado
- Si se especifica un valor, ese campo se emite
Manipular maps y objetos es más simple que lidiar con la indentación YAML
- En casos donde se inserta un map en la configuración, como una annotation de un pod de Kubernetes, en Jsonnet se puede definir el valor como variable y ubicarlo dentro del objeto
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,
},
}
- Este enfoque es mucho más simple que ajustar la indentación en una plantilla YAML
- El resultado generado es un objeto JSON con el map de annotations debajo de
metadata.annotations
{
"metadata": {
"annotations": {
"nginx.ingress.kubernetes.io/app-root": "/",
"nginx.ingress.kubernetes.io/enable-cors": true
}
}
}
- Agregar annotations a un objeto existente también puede manejarse en Jsonnet con el operador
+
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',
},
},
}
- En el objeto resultante se agrega
something: "nothing" a las annotations existentes
{
"metadata": {
"annotations": {
"nginx.ingress.kubernetes.io/app-root": "/",
"nginx.ingress.kubernetes.io/enable-cors": true,
"something": "nothing"
}
}
}
- En ejemplos simples, el código puede parecer más largo, pero a medida que la configuración se vuelve más compleja, la capacidad de manipular objetos de esta manera se vuelve útil
kr8 maneja la configuración de Kubernetes al estilo Jsonnet
- kr8 usa estos métodos para crear y manipular de forma fácil y simple la configuración de varios clústeres de Kubernetes
- El flujo central consiste en generar objetos de configuración JSON y transformarlos de la manera necesaria, en lugar de ensamblar plantillas YAML con espacios y condicionales
1 comentarios
Comentarios de Hacker News
Ya estoy completamente harto de la configuración escrita en YAML. Es la parte que más odio de GitHub Actions, y es peor que solo un problema de confiabilidad
Cuando veo que una herramienta interesante exige archivos YAML para configurarse, de inmediato me da mala espina. Me pasa lo mismo con lenguajes de configuración propietarios como HCL de Terraform o ASL de AWS Step Functions
Está bien querer una API declarativa, pero ojalá permitieran generar esa declaración con un programa. La configuración declarada y generada con código me ha dado una experiencia mucho mejor, y AWS CDK hizo esto realmente bien
Puedes definir infraestructura en la nube con un lenguaje con seguridad de tipos y buen soporte de IDE, sin depender de plugins que no se actualizan desde hace 2 años
deno fmttiene formateador para JSON, pero no para YAMLEl formateador de JSON es un solo binario que corre en milisegundos, mientras que para autoformatear YAML en la práctica hay que usar Prettier, y Prettier depende de media NPM y tarda como 2 segundos en arrancar y ejecutarse
Por eso, en el repositorio de la empresa pasé a JSON todos los archivos YAML que se podían convertir, y al menos yo estoy mucho más satisfecho. Nadie se quejó
Varios editores también soportan la etiqueta
$schemade JSON. Le agregué esta función al producto y quedó muy bien poder crear archivos de configuración solo presionando tab, sin leer la documentaciónEn YAML también se puede con el YAML language server, pero como la tecla tab también se necesita para la indentación, la experiencia de uso no es muy buena. JSON tampoco es perfecto, pero al menos el texto
"no"no significa verdadero¿No bastaría con poner un filtro que elimine los comentarios antes de leer la configuración? No puede ser más difícil que convertirlo todo a YAML
Tampoco entiendo mucho eso de que YAML es más fácil de leer. El dolor de trabajar con configuración no viene de ahorrarse unos segundos al interpretar llaves y corchetes, sino de lo difícil que es saber qué salió mal dentro de cientos de líneas por culpa de un espacio o tabulación faltante
Ansible comete el mismo error, y muchísimas herramientas también
No sé bien si CDK funciona de esa manera. Cuando lo probé un poco, se sintió bastante distinto de la experiencia de “generar CloudFormation” que yo había hecho, y no terminé de captar bien las ventajas de CDK
Se sentía como cambiar el problema de YAML/plantillas por un problema de herencia/magia. Me gustaría escuchar más experiencias de gente que haya usado AWS CDK, Terraform CDK o Pulumi
https://github.com/actions/runner/issues/1182
Aunque estoy de acuerdo en que las plantillas YAML son una locura bastante grande, nunca he entendido por qué no dejan de usar lenguajes falsos y usan lenguajes de programación de verdad
Si necesitas lógica compleja, simplemente puedes generar YAML/JSON/lo que sea con un lenguaje de programación. Ruby, Python o cualquier otro lenguaje te da lo que necesitas sin seudolenguajes raros como Jsonnet o las plantillas de Go
Si solo escribes código, te metes mucho menos en problemas raros y opacos de los motores de plantillas. Cualquier lenguaje real es mucho mejor
He usado Chef para trabajos parecidos, y me gustaba que, al ser Ruby, era fácil definir la lógica que quería y usar bucles y variables de verdad
Entiendo que Ansible fue diseñado para gente no programadora, pero para alguien con nociones básicas de programación no hay infierno peor que encerrar un playbook de Ansible con muchas condiciones e iteraciones dentro de la sintaxis verbosa de las plantillas Jinja
Pero ahora lo normal es traer un parser de JSON/TOML/YAML y hacer una función
readConfig, incluso en lugares donde un intérprete embebido sería más apropiadoDesde la perspectiva del desarrollador, es más fácil meterle complejidad a un formato de configuración que ofrecer un lenguaje embebido completo con bindings para la aplicación. Así que da la impresión de que se olvidaron del método, o ni siquiera consideran que sea posible
En la época de Chef/Puppet hubo muchos lugares donde empezaron a meter lógica en IaC y eso terminó convertido en un desorden gigantesco imposible de actualizar o mantener. El enfoque de Chef/Pulumi también funciona, pero necesitas gente muy estricta con el estilo y el mantenimiento
Para equipos grandes y mantenimiento a largo plazo, me parece mejor el modelo de Terraform/Puppet. Aunque HCL sea molesto y usar Python/TypeScript y similares se sienta liberador, el código puramente declarativo evita muchísimo espagueti
Quieren meter los elementos de diseño de lenguajes que están de moda, quieren self-hosting, y además que también sirva para escribir servidores web rápidos y multihilo, así que termina siendo algo conceptualmente complejo
Hace falta un lenguaje juguete simple, tipo Logo, para ingenieros de sistemas/DevOps. Idealmente debería poder explicarse en un solo libro del tamaño del K&R de C
Necesita tipado dinámico, estructuras de control que puedas aprender en un fin de semana, nada de threading ni concurrencia, nada de orientación a objetos ni herencia, diseño funcional/modular, y un modelo de FFI que pueda llamar y ser llamado fácilmente desde otros lenguajes y frameworks
El problema es que los fanáticos de los lenguajes no saben contenerse, así que siguen agregando funciones, y eso termina metido en la librería estándar y en la guía de estilo, obligando también a la gente principiante a aprenderlo todo
A mí mismo me darían ganas de agregar funciones tipo
each/mapa arrays/hash maps y meter funciones de primera clase y closures, pero eso podría ser un error. Ya existen lenguajes funcionales inmutables para configuración, pero a más del 95% de quienes usan YAML con plantillas no les interesa aprender a programar de esa manera, así que es difícil que se vuelvan masivosEso hace que la configuración sea más simple, más fácil de consumir y también más fácil de documentar. Pero al momento de escribir esos archivos de configuración, deberías usar un lenguaje de programación, idealmente uno de tipado estático que ofrezca validación de errores, autocompletado y documentación inline
AWS CDK es un buen ejemplo. Escribir CloudFormation puro es doloroso, pero CDK no le agrega capacidades de programación a CloudFormation, sino que genera CloudFormation. La entrada que AWS consume sigue siendo un CloudFormation relativamente simple y estable
Apenas vi el título, pensé que sería sobre Kubernetes.
La API de Kubernetes es bastante intuitiva y tiene un esquema JSON bien definido. La mayor parte del tiempo al aprender k8s debería dedicarse a entender cómo usar la API, pero en la práctica se va en descifrar cómo usar los charts de Helm.
No diría que Jsonnet, Ksonnet, Nu o CUE hayan alcanzado tanta popularidad. Parece que la mayoría usa Kustomize, probablemente porque es relativamente intuitivo y viene integrado en
kubectl.La herramienta ideal debería ofrecer verificación de tipos contra el esquema de k8s, validación y alertas de deprecación de versiones para quien escribe las definiciones, producir un único artefacto fácil de inspeccionar para el usuario, fallar de forma atómica si el clúster no soporta algún objeto o versión, y estar integrada en la cadena de herramientas por defecto.
Algo como un script de TypeScript en Bun o Deno que exporte una función que reciba argumentos y devuelva una lista de definiciones encajaría bien con
deno compiley similares, pero no cumpliría la condición de estar integrado en la cadena de herramientas por defecto.Uno queda protegido de los detalles de bajo nivel, pero cuando algo falla tiene que lidiar con una enorme pila de abstracciones que dificulta el diagnóstico y la depuración.
Se vuelve mucho más difícil averiguar qué está pasando en realidad, y terminas dependiendo de capas de abstracción, cargando además con las actualizaciones del proveedor y otros problemas dentro del grafo de dependencias.
Hace casi todo lo que necesitamos sin problemas, es multiplataforma y puede usarse desde varios lenguajes. Lo he integrado en ejecutables de C++, .NET y la JVM.
La configuración JSON resultante puede aprovechar una enorme cantidad de herramientas que cuesta encontrar con alternativas como toml/yaml/hocon/ini, etc. Intenté usar HOCON fuera de la JVM, pero siempre aparecía algún caso límite.
Pero cuando realmente administras sistemas grandes, al final no puedes evitar las ventajas de las plantillas.
Da risa ver lo poco que los desarrolladores piensan en cómo manejar bien la configuración.
Parece solo un conjunto de claves y valores guardados en un archivo o generados por código, pero en realidad eso lo es todo. Es programación en sí misma.
Todo es configuración, y todos los argumentos de funciones también son una forma de configuración. Toda configuración en archivos externos termina convirtiéndose en argumentos de función de una forma u otra.
El problema es su representación como texto plano del código. Los archivos de configuración declarativos parecen buenos porque puedes ver todo en un solo lugar, pero cuando conviertes la configuración en un programa, se vuelve difícil encontrar qué hay que cambiar.
Si el código pudiera ejecutarse en tiempo real para mostrar la representación de la configuración final, y además permitiera rastrear cómo se generó cada valor final, no habría problema. Esa función es bastante sencilla, pero no existen sistemas diseñados así. La configuración siempre es algo que se considera al final.
Si extiendes esta idea a toda la programación, deberías poder ver todo el código y sus transformaciones que dependen de un único valor de configuración.
Además, la mayor parte de la configuración es relacional o de tipo grafo, así que quizá sería mejor ponerla en una base de datos central. Distintos valores de configuración están relacionados entre sí. Por eso la configuración debería verse en un editor de base de datos o de grafos.
En cuanto sales del texto plano, todo empieza a simplificarse bastante, aunque todavía hacen falta las funciones de lenguaje mencionadas antes.
Están intentando usar convenciones de nombres para agrupar variables relacionadas dentro de las configuraciones.
Quieren una estructura de datos realmente anidada, probablemente moverlo a JSON, pero como los ingenieros se niegan por completo a escribir código, la configuración como código no es posible. También están las desventajas ya mencionadas.
La siguiente idea fue que debería existir una mejor manera de mostrar y editar la configuración. Pensé en una UI visual donde se pueda explorar la representación del producto final, seleccionar piezas y modificar así los parámetros.
Me pregunto si esa dirección tiene sentido. Si no, me gustaría que lo explicaras un poco más. El núcleo de esta aplicación es la configuración.
Peor aún, en entornos como CI/CD YAML casi se convierte en un lenguaje de programación. Y además uno muy verboso, poco intuitivo, mal especificado y distinto según el proveedor.
Incluso con DTD y validación XML, tenía ese comportamiento ya conocido de fallar tarde y dar mensajes de error difíciles de interpretar.
En aquel entonces mucha frustración se dirigía al XML, pero viendo el infierno YAML de mediados de los 2020, queda claro que el problema no era el lenguaje de marcado en sí.
De verdad odio enterrar lógica en alguna parte dentro de una plantilla YAML.
[0] https://tanzu.vmware.com/developer/guides/ytt-gs/
Es realmente triste que Helm haya ganado. Trabajo en una empresa haciendo cosas open source relacionadas con k8s, y el 100% de los usuarios nos pedía que hiciéramos charts de Helm, así que al final tuvimos que hacerlo
Es miserable trabajar con eso. El archivo se llama algo como
foo.yaml, pero en realidad no es YAML, así que el editor no te puede ayudar. Hay que pasar todos los datos porindent 4para que la alineación de YAML quede bienLo más deprimente es que hay que volver a exponer todas las funciones de Kubernetes a su manera. Si alguien quiere agregar
deployment.spec.template.spec.fooBars, tienes que agregardeploymentFooBarsavalues.yamly conectarlo. Se repite para cada funciónEs un caso clarísimo de “lo malo es bueno” saliendo mal. Yo también llegué a intentar implementar plantillas haciendo horrores como
sed -e s/$FOO/foo/g, y probablemente Helm empezó así. El resultado es un desastrePersonalmente, he usado Kustomize desde antes de que entrara en
kubectl, y siempre he quedado bastante satisfecho. Tiene muchas rarezas, pero al menos entiende el significado de los objetos que genera y te ahorra tiempoJsonnet es mucho mejor. Como parte de nuestra app de k8s, también distribuimos despliegues de Envoy para enrutamiento de tráfico complejo, y la configuración de Envoy es verbosa, pero fácil de manejar con Jsonnet: https://github.com/pachyderm/pachyderm/blob/master/etc/gener...
Estoy considerando seriamente transpilar jsonnet al lenguaje de plantillas de Go e implementar todo en Jsonnet. Al menos sería un poco mantenible, y como
helm installsimplemente funcionaría, nadie se daría cuentaPero creo que Helm será el fin de Kubernetes. Si alguna herramienta competidora de asignación de cómputo/ejecución de contenedores aparece con un lenguaje decente para la configuración, la gente se cambiará de un día para otro
sed -e s/$FOO/foo/g, quizá te convenga revisar envsubst como una solución un poco más estándar y mejorSi el tema es plantillar o modificar charts de Helm con jsonnet, Tanka también puede ayudar: https://tanka.dev/helm
Pero los lugares donde he trabajado siguen usando tf/hcl y helm tal cual, porque todavía le tienen miedo al cambio. Al menos en proyectos personales uno puede respirar un poco más
Creo que aquí sí hay un problema. Solo que no estoy seguro de que el tipo de persona que elige YAML como lenguaje de configuración lo vea como un problema
Hay un choque directo entre la representación de datos centrada en humanos y la representación de datos centrada en computadoras. A las computadoras les gusta algo parecido a Lisp, y a las personas algo parecido a Python
Si quieres manipular la configuración de Kubernetes con computadoras, probablemente te va a irritar en silencio que Kubernetes use YAML. Pero la comunidad de Kubernetes parece estar compuesta sobre todo por gente del lado de YAML, así que supongo que no les importa por qué el trabajo con archivos de configuración se vuelve terrible cuando metes lógica de programación
Justamente esa es la desventaja de YAML, y creo que la gente de k8s en general es lo bastante inteligente como para haberlo anticipado
La frase “YAML es un superconjunto de JSON” no me parece cierta en la práctica, sin importar lo que el autor de la especificación haya escrito en los documentos. Si convirtieras toda la configuración YAML a JSON, el equipo de DevOps se enojaría
Los dos formatos de datos pueden tener la misma capacidad de expresar significado, pero lo mismo pasa con todos los lenguajes que compilan a la misma arquitectura de CPU. JSON y YAML son cosas distintas en la práctica, y mezclarlos no es buena idea
Claro, la gente terminó escribiéndolos a mano de todos modos, y cuando se volvió insoportable empezaron a pegarles plantillas. Parece que las cosas siempre terminan así
El texto escrito a mano no es reemplazado por texto de serialización de configuración generado por máquinas, sino por texto que originalmente seguía siendo escrito a mano pero ahora con plantillas encima
Mi principio personal es que no se debe usar interpolación de cadenas para generar código que leen las máquinas. Un lenguaje de plantillas no es más que una interpolación de cadenas elegante
He visto los resultados de la inyección SQL y del cross-site scripting. Mientras se siga metiendo texto arbitrario en un intérprete, estas cosas van a seguir pasando
Por eso también creo que no se deberían usar archivos de plantilla para crear HTML
Como alternativas a los lenguajes de plantilla para HTML, están Haml de Ruby y Pug de JavaScript. Estos lenguajes ofrecen una forma definida de especificar el árbol completo de etiquetas, atributos y nodos de texto
Si no te gusta la indentación significativa al estilo Python, en JavaScript está JSX. La parte con apariencia de HTML en JSX se compila a expresiones
createElementque construyen un árbol de documento web, y ese árbol luego puede renderizarse como HTML si hace faltaHaml, Pug y JSX no son lenguajes de plantilla aunque puedan producir HTML. Del mismo modo,
JSON.stringify(myObj)no es un lenguaje de plantilla para JSONEl código que leen las máquinas, cuando sea posible, debería generarse con herramientas que entiendan y aprovechen la estructura conocida del lenguaje de destino
Haml es un sistema de plantillas para evitar código inline en documentos web y hacer que el HTML sea más limpio, y Pug es un motor de plantillas con muchas funciones para Node.js
Puedo aceptar que, estrictamente hablando, JSX no sea un lenguaje de plantilla
Al final, todos se compilan a HTML. Solo que no mediante interpolación de cadenas, sino como lenguajes que se parsean a árboles sintácticos y se renderizan como HTML con base en una comprensión interna de la estructura válida
Las plantillas de YAML sí son interpolación de cadenas elegante, y no son un lenguaje de plantilla, o al menos son un lenguaje de plantilla pésimamente implementado
Mi regla personal es que cada vez que un valor entra en una cadena, debe codificarse correctamente
Antes escribí sobre este tema: https://kevincox.ca/2022/02/08/escape-everything/
En resumen, toda cadena tiene un formato que debe respetar, ya sea HTML, SQL o salida de terminal legible por humanos. Cada vez que metes un valor en una cadena, deberías codificarlo correctamente para ese formato, pero casi nunca lo hacemos
Nos estamos pasando a cuelang [1]. Personalmente me parece mejor diseñado que Jsonette
Kubernetes ya tiene reconciliación de estado, así que lo único que faltaba en esta configuración era la eliminación, y ahora eso se puede resolver con la función de prune [2]
[1] https://cuelang.org/docs/integrations/k8s/
[2] https://kubernetes.io/blog/2023/05/09/introducing-kubectl-ap...
Algunos mensajes de error son un poco difíciles de interpretar, pero compensa por la enorme cantidad de errores que detecta de antemano. Las pocas veces que ahora tengo que escribir yaml directamente se sienten demasiado tediosas en comparación
En estos casos normalmente me meto con un “¿han oído hablar de nuestro salvador CUELang?”: https://cuelang.org/
Todavía no es Turing completo, pero es lo bastante expresivo para eliminar duplicación, permite definir esquemas y datos en el mismo archivo o en archivos separados, y también tiene tipos unión
Puede generar YAML o JSON, y puede validar tanto a sí mismo como archivos YAML/JSON
Su mayor desventaja es que la implementación actual solo existe en Go, así que puede requerir subprocesos o FFI
Luego crea archivos JSON para cada aplicación, alguna herramienta genera definiciones XML, esas definiciones se aplican a un XLS que manejan los arquitectos, y de ahí sale YAML para aplicarlo a charts de Helm
Los charts despliegan el cliente de k8s, y ese cliente interactúa con el clúster principal en JSON mediante la API
Tomó algo de tiempo, pero estamos usando la mejor herramienta para cada trabajo