- Kubernetes जैसे environments में जहां configuration targets बढ़ते जाते हैं, YAML files को सीधे बढ़ाते जाना जल्द ही अपनी सीमा पर पहुंच जाता है, और YAML template के बजाय configuration data generate करने वाला approach अधिक उपयुक्त हो जाता है
- Helm chart
values.yaml और Go templates से values inject करता है, लेकिन optional fields, arrays और maps आते ही conditionals और indentation का बोझ बढ़ जाता है
- YAML में whitespace rules सख्त होते हैं, जबकि Helm template parser YAML structure को नहीं समझता, इसलिए
toYaml और indent का combination आसानी से fragile configuration generation में बदल जाता है
- YAML, JSON का superset है, इसलिए दोनों के बीच conversion सरल है, और Jsonnet external variables, conditional fields, map composition और object merging के जरिए configuration objects generation को code की तरह handle करता है
- kr8, Jsonnet-based flow से कई Kubernetes clusters की configurations बनाता और manipulate करता है, और complex YAML strings assemble करने के बजाय objects को सीधे create और transform करने का रास्ता चुनता है
Configuration complexity तब शुरू होती है जब YAML files की संख्या बढ़ती है
- Applications और infrastructure एक निश्चित scale से आगे बढ़ते ही configuration complexity तेजी से बढ़ती है
- अगर deployment targets 1–2 हों तो YAML configuration files हाथ से लिखना काफी हो सकता है, लेकिन उससे आगे बढ़ने पर configuration को व्यवस्थित तरीके से manage करना जरूरी हो जाता है
- कई configuration files की जरूरत आमतौर पर इसलिए होती है क्योंकि एक ही target के लिए भी कुछ values अलग-अलग होती हैं
dev, stg, prod जैसे environment-wise deployments
- Europe, North America जैसे region-wise deployments
- सारी configurations अलग नहीं होतीं, लेकिन जब differences काफी बड़े हों तो common parts और अलग parts को अलग करके manage करना पड़ता है
- Configuration management field लंबे समय से ऐसे issues से निपटती रही है, और कई tools ने अपने-अपने तरीके से YAML का उपयोग किया है
- Puppet में शामिल hiera variables को hierarchical तरीके से lookup कर सकता है, इसलिए यह powerful और flexible है, और YAML को खुद template करने की जरूरत काफी कम कर देता है
Helm chart में दिखने वाली YAML templates की समस्या
- Cloud computing और Kubernetes के साथ configuration targets operating system से ऊपर की layers तक फैल गए, और CloudFormation तथा Helm जैसे tools सामने आए
- Helm chart
values.yaml में defined external parameters लेकर render कर सकता है
- Simple string values अपेक्षाकृत आसान होती हैं
image: "{{ .Values.image }}"
values.yaml में image value specify करने पर वह value template में चली जाती है
- Optional fields जैसी ज्यादा complex configuration handle करना शुरू करते ही समस्या बढ़ जाती है
{{- with .resourceGroup }}
resourceGroup: {{ . }}
{{- end }}
- Optional values को खाली नहीं छोड़ा जा सकता, इसलिए conditionals और loops की जरूरत पड़ती है, और template आसानी से messy हो जाता है
- Arrays या maps डालते समय
toYaml और indent को combine करना पड़ता है
{{- with .Values.podAnnotations }}
annotations:
{{ toYaml . | indent 8 }}
{{- end }}
toYaml से YAML को फिर YAML में बदलने वाला function call भी अटपटा है, लेकिन बड़ा मुद्दा whitespace handling है
YAML whitespace rules और template engine का टकराव
- YAML में indentation और whitespace rules सख्त होते हैं
- नीचे दिया example valid या complete YAML नहीं है
something: nothing
hello: goodbye
- अगर इंसान सीधे लिख रहा हो तो backspace कुछ बार दबाकर इसे ठीक कर सकता है, लेकिन template system से YAML generate करते समय यह आसान नहीं होता
- अगर configuration files 5–10 से ज्यादा हो जाएं, तो हाथ से लिखने के बजाय configuration generation की जरूरत पड़ती है
.Values.podAnnotations value को पहले से indented annotations के नीचे डालना हो तो value को भी बिल्कुल सही level तक indent करना पड़ता है
- Go template parser YAML को नहीं समझता, इसलिए template syntax को readable बनाने के लिए indent करने की कोशिश भी समस्या पैदा कर सकती है
{{- with .Values.podAnnotations }}
annotations:
{{ toYaml . | indent 6 }}
{{- end }}
- जब template system YAML structure नहीं जानता और whitespace तथा conditionals को साथ में handle करना पड़ता है, तो complex configuration generation धीरे-धीरे कठिन होती जाती है
- JSON को सीधे लिखने का तरीका भी comments न होने और commas छूट जाने जैसी समस्याओं के कारण उपयुक्त नहीं है; इन्हीं असुविधाओं की वजह से YAML इस्तेमाल में आया
Jsonnet, JSON configuration generate करने वाली data templating language है
- YAML JSON का superset है, इसलिए JSON और YAML के बीच conversion सरल है
- कई applications और programming languages JSON और YAML को default रूप से parse या convert कर सकते हैं
- Python में भी YAML पढ़कर JSON output किया जा सकता है
python -c 'import json, sys, yaml ; y=yaml.safe_load(sys.stdin.read()) ; print(json.dumps(y))'
- Jsonnet खुद को data templating language कहता है, और इसका मुख्य उद्देश्य JSON configuration generate करना है
- Jsonnet की design background design rationale में देखी जा सकती है
External variables और optional fields handling
- Jsonnet external variables का उपयोग करके configuration values inject कर सकता है
{
image: std.extVar('image'),
}
- CLI में external variable pass करने पर JSON result generate होता है
jsonnet image.jsonnet -V image="my-image"
{
"image": "my-image"
}
- Optional fields को template conditionals की तरह string के अंदर ठूंसने के बजाय code की conditional expression के रूप में express किया जा सकता है
// 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,
}
- अगर
rg null है, तो resourceGroup field result में शामिल नहीं होगा
- Value specify करने पर वह field output होगा
Maps और objects manipulate करना YAML indentation से सरल है
- Kubernetes pod annotation जैसे map को configuration में डालने के मामले में, Jsonnet में value को variable के रूप में define करके object में रखा जा सकता है
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,
},
}
- यह तरीका YAML template में indentation मिलाने की तुलना में कहीं ज्यादा सरल है
- Generated result एक JSON object है जिसमें annotation map
metadata.annotations के नीचे जाता है
{
"metadata": {
"annotations": {
"nginx.ingress.kubernetes.io/app-root": "/",
"nginx.ingress.kubernetes.io/enable-cors": true
}
}
}
- Existing object में annotation add करने का काम भी Jsonnet में
+ operator से किया जा सकता है
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',
},
},
}
- Result object में existing annotations के साथ
something: "nothing" जुड़ जाता है
{
"metadata": {
"annotations": {
"nginx.ingress.kubernetes.io/app-root": "/",
"nginx.ingress.kubernetes.io/enable-cors": true,
"something": "nothing"
}
}
}
- Simple example में code लंबा लग सकता है, लेकिन configuration जटिल होने के साथ objects को इस तरीके से manipulate करने की क्षमता उपयोगी हो जाती है
kr8 Jsonnet तरीके से Kubernetes configuration handle करता है
- kr8 कई Kubernetes clusters की configurations को आसानी और सरलता से बनाने तथा manipulate करने के लिए इन तरीकों का उपयोग करता है
- Core flow यह है कि YAML templates को whitespace और conditionals से assemble करने के बजाय JSON configuration objects generate किए जाएं और जरूरत के अनुसार transform किए जाएं
1 टिप्पणियां
Hacker News की टिप्पणियां
YAML में लिखी configuration से अब पूरी तरह ऊब चुका हूं। यह GitHub Actions का सबसे नापसंद हिस्सा है, reliability से भी ज्यादा खराब
जब कोई बढ़िया tool configuration के लिए YAML file मांगता है, तो तुरंत बेचैनी होने लगती है। Terraform की HCL, AWS Step Functions की ASL जैसी proprietary configuration languages के साथ भी यही है
declarative API चाहना ठीक है, लेकिन काश उस declaration को programmatically generate करने दिया जाए। code में declare करके generate की गई configuration का experience कहीं बेहतर था, और AWS CDK ने यह सच में बहुत अच्छे से किया
type-safe language और अच्छे IDE support के साथ cloud infrastructure definition लिख सकते हैं, और ऐसे plugin पर निर्भर नहीं रहना पड़ता जो 2 साल पहले के बाद update भी नहीं हुआ
deno fmtमें JSON formatter है, लेकिन YAML formatter नहींJSON formatter millisecond में चलने वाला single binary है, जबकि YAML auto-formatting के लिए practically Prettier इस्तेमाल करना पड़ता है, और Prettier आधे NPM पर depend करता है तथा start और run होने में करीब 2 सेकंड लेता है
इसलिए company repository में जिन YAML files को JSON में बदला जा सकता था, वे सब JSON में move कर दीं, और कम से कम मैं तो काफी ज्यादा संतुष्ट हूं। किसी ने शिकायत नहीं की
कई editors JSON के
$schematag को भी support करते हैं। हमने product में यह feature जोड़ा, और docs पढ़े बिना सिर्फ tab दबाकर configuration file बना पाना सच में बढ़िया हैYAML में भी YAML language server से यह संभव है, लेकिन tab key indentation के लिए भी चाहिए होती है, इसलिए usability खास नहीं रहती। JSON भी perfect नहीं है, लेकिन कम से कम text
"no"true नहीं होताconfiguration पढ़ने से पहले comments हटाने वाला एक filter लगा दें, इतना ही तो है? यह YAML में बदलने से मुश्किल नहीं होना चाहिए
YAML ज्यादा readable है, यह बात भी मुझे ठीक से समझ नहीं आती। configuration संभालने की तकलीफ curly braces और square brackets को कुछ सेकंड कम parse करने से नहीं आती, बल्कि सैकड़ों lines की configuration में missing spaces या tabs की वजह से यह पता न चलने से आती है कि गलती कहां है
Ansible भी वही गलती करता है, और ढेरों tools भी ऐसा ही करते हैं
CDK उसी तरह काम करता है या नहीं, यह ठीक से नहीं जानता। थोड़ा हाथ लगाया था तो वह मेरे बनाए “CloudFormation generation” experience से काफी अलग लगा, और CDK की खूबियां ठीक से समझ नहीं आईं
ऐसा लगा मानो YAML/template problem को inheritance/magic problem में बदल दिया गया हो। AWS CDK, Terraform CDK, Pulumi इस्तेमाल कर चुके लोगों के experience और सुनना चाहूंगा
https://github.com/actions/runner/issues/1182
मैं मानता हूँ कि YAML templates काफ़ी पागलपन वाली चीज़ हैं, लेकिन यह बात हमेशा समझ नहीं आती कि नकली language छोड़कर असली programming language क्यों नहीं इस्तेमाल करते
अगर complex logic चाहिए, तो programming language से YAML/JSON/जो भी हो generate कर सकते हैं। Ruby, Python या कोई भी दूसरी language Jsonnet या Go templates जैसी अजीब pseudo-language के बिना भी ज़रूरी चीज़ें दे देती है
बस code लिखें तो template engine की opaque अजीब समस्याओं में बहुत कम फँसते हैं। कोई भी असली language इस्तेमाल करें, वह कहीं बेहतर होगी
मिलते-जुलते काम के लिए मैंने Chef इस्तेमाल किया था, और Ruby होने की वजह से अपनी logic आसानी से define कर पाना, loops और सही variables इस्तेमाल कर पाना अच्छा लगा
मैं समझता हूँ कि Ansible non-programmers के लिए design किया गया है, लेकिन जो लोग basic programming से परिचित हैं, उनके लिए conditional tasks और loops से भरी Ansible playbook को Jinja templates के verbose syntax में कैद करने से बड़ा नरक कुछ नहीं
लेकिन अब आम तौर पर JSON/TOML/YAML parser लाकर
readConfigfunction बना दिया जाता है, और जहाँ embedded interpreter ज़्यादा सही होता, वहाँ भी ऐसा ही किया जाता हैdeveloper के नज़रिए से complete language embedding और application bindings देने की तुलना में config format में complexity जोड़ना आसान है। इसलिए लगता है कि लोग तरीका ही भूल गए हैं, या यह संभव है—यह सोचते भी नहीं
Chef/Puppet के दौर में कई जगहों ने IaC में logic डालना शुरू किया और फिर वह ऐसा बड़ा mess बन गया जिसे upgrade करना या maintain करना असंभव था। Chef/Pulumi तरीका भी संभव है, लेकिन style और maintenance को लेकर बहुत सख्त व्यक्ति चाहिए
बड़ी teams और long-term maintenance के लिए मुझे Terraform/Puppet model बेहतर लगता है। HCL irritate करता हो और Python/TypeScript वगैरह इस्तेमाल करना मुक्तिदायक लगे, फिर भी pure declarative code बहुत सारी spaghetti रोक देता है
वे आजकल trend में चल रहे language design elements डालना चाहते हैं, self-hosting चाहते हैं, और उसे तेज multithreaded web server लिखने लायक भी बनाना चाहते हैं, इसलिए यह conceptually complex हो जाता है
system engineers/DevOps के लिए Logo जैसी simple toy language चाहिए। मूल रूप से उसे K&R C book जितनी size की एक किताब में समझाया जा सके
dynamic typing, weekend में सीखे जा सकने वाले control structures, threading या concurrency नहीं, object-orientation या inheritance नहीं, functional/modular design, और ऐसा FFI model चाहिए जिसे दूसरी languages और frameworks से आसानी से call किया जा सके और जो उन्हें call कर सके
समस्या यह है कि language geeks खुद को रोक नहीं पाते और features जोड़ते रहते हैं, और वे core libraries और style guides में शामिल हो जाते हैं, जिससे beginners को भी सब सीखना पड़ता है
मैं खुद भी arrays/hashmaps में
each/mapजैसी functions जोड़ना और first-class functions व closures डालना चाहूँगा, लेकिन यह गलती हो सकती है। config के लिए immutable functional languages पहले से हैं, लेकिन templated YAML इस्तेमाल करने वाले 95% से ज़्यादा लोग उस तरीके से programming सीखना नहीं चाहते, इसलिए उनका widespread होना मुश्किल हैconfig simple हो जाती है, consume करना आसान होता है, और documentation भी बेहतर होती है। लेकिन config file लिखते समय programming language इस्तेमाल करनी चाहिए, और हो सके तो error checking, autocomplete और inline documentation देने वाली statically typed language बेहतर है
AWS CDK इसका अच्छा example है। pure CloudFormation लिखना पीड़ादायक है, लेकिन CDK CloudFormation में programming features जोड़ता नहीं, बल्कि CloudFormation generate करता है। AWS जो input consume करता है, वह अब भी relatively simple और stable CloudFormation ही है
शीर्षक देखते ही लगा था कि यह Kubernetes की बात होगी
Kubernetes API काफी सहज और अच्छी तरह परिभाषित JSON schema रखता है। k8s सीखने का ज्यादातर समय API इस्तेमाल करने का तरीका समझने में लगना चाहिए, लेकिन असल में वह Helm chart इस्तेमाल करने का तरीका खोजने में जा रहा है
मुझे नहीं लगता Jsonnet, Ksonnet, Nu, CUE को इतनी बड़ी लोकप्रियता मिली है। ज्यादातर लोग शायद Kustomize इस्तेमाल करते हैं, क्योंकि यह अपेक्षाकृत सहज है और
kubectlमें built-in हैमुझे जो tool चाहिए वह k8s schema के लिए type checking, validation और version deprecation warnings definition author को दे, user को आसानी से inspect किया जा सकने वाला single output दे, cluster किसी object/version को support न करे तो atomically fail हो, और default toolchain में built-in हो
अगर Bun या Deno TypeScript script arguments लेने वाला function export करे और definitions की list return करे, तो
deno compileवगैरह के साथ अच्छा बैठेगा, लेकिन यह default toolchain built-in वाली शर्त तोड़ देता हैlower-level details से बचाव तो मिल जाता है, लेकिन problem आने पर diagnosis और debugging को मुश्किल बनाने वाली विशाल abstraction stack से जूझना पड़ता है
असल में क्या हो रहा है यह पता लगाना कहीं ज्यादा कठिन हो जाता है, और abstraction layer पर निर्भरता के कारण provider द्वारा निकाले गए updates और dependency graph की दूसरी समस्याएं भी अपने सिर लेनी पड़ती हैं
जो काम चाहिए वह लगभग बिना समस्या कर देता है, cross-platform है और कई languages में इस्तेमाल किया जा सकता है। मैंने इसे C++, .NET, JVM executables में embed करके देखा है
resulting JSON configuration को ऐसे विशाल tooling के साथ इस्तेमाल किया जा सकता है जो विकल्पों toml/yaml/hocon/ini आदि में मिलना मुश्किल है। HOCON को non-JVM languages में इस्तेमाल करने की कोशिश की, लेकिन हमेशा कोई edge case अटक जाता था
लेकिन असल में बड़ा system manage करते समय आखिरकार templates के फायदे से बचा नहीं जा सकता
यह देखना मजेदार है कि developers configuration को ठीक से handle करने के बारे में कितना कम सोचते हैं
यह बस file में store की गई या code से generate की गई keys और values की गठरी जैसा दिखता है, लेकिन असल में यही सब कुछ है। यह programming खुद है
सब कुछ configuration है, और हर function argument भी एक तरह की configuration है। external file की हर configuration आखिरकार किसी न किसी तरह function argument बनती है
समस्या code के plain text representation की है। declarative configuration file अच्छी लगती है क्योंकि सब कुछ एक जगह दिखता है, लेकिन configuration को program बना दें तो यह ढूंढना मुश्किल हो जाता है कि क्या बदलना है
अगर code real time में execute होकर final configuration का representation दिखाए, और हर final configuration value कैसे बनी यह trace कर सके, तो समस्या नहीं होगी। लेकिन यह feature काफी simple होने के बावजूद इस तरह design किया गया कोई system नहीं है। configuration हमेशा बाद में सोची जाने वाली चीज होती है
इस concept को पूरी programming तक बढ़ाएं तो, किसी एक configuration value पर निर्भर सभी code और उसके transformations दिखने चाहिए
साथ ही ज्यादातर configuration relational/graph-like होती है, इसलिए उसे central database में रखना बेहतर हो सकता है। अलग-अलग configuration values एक-दूसरे से संबंधित होती हैं। इसलिए configuration को database/graph editor में देखना चाहिए
plain text से बाहर निकलने पर चीजें कहीं ज्यादा simple होने लगती हैं, लेकिन ऊपर बताई गई language features तब भी चाहिए
configurations संबंधित variables को group करने के लिए naming conventions इस्तेमाल करने की कोशिश कर रही हैं
वे असली nested data structure, शायद JSON, में जाना चाहते हैं, लेकिन engineers code बिल्कुल नहीं लिखना चाहते, इसलिए configuration-as-code संभव नहीं है। ऊपर बताई गई कमियां भी हैं
अगला विचार यह है कि configuration को बेहतर तरीके से दिखाने और edit करने का कोई तरीका होना चाहिए। मैंने final product के representation को explore करने, parts select करने और उसी तरीके से parameters edit करने वाली visual UI के बारे में सोचा
सोच रहा हूं कि क्या यह दिशा सही है। अगर नहीं, तो थोड़ा और समझा दें। इस application का core configuration ही है
इससे भी बुरी बात यह है कि CI/CD जैसी जगहों में YAML लगभग programming language बन जाता है। वह भी बहुत verbose, intuitive नहीं, खराब specification वाला और हर vendor के लिए अलग language
DTD और XML validation होने के बावजूद उसमें देर से fail होने और समझने में मुश्किल error messages देने वाली परिचित विशेषताएं थीं
तब बहुत निराशा XML पर निकली, लेकिन 2020s के मध्य के YAML hell को देखकर लगता है कि समस्या markup language खुद नहीं थी
YAML template के कहीं अंदर logic दबा देना मुझे सचमुच नापसंद है
[0] https://tanzu.vmware.com/developer/guides/ytt-gs/
Helm के जीतने की बात वाकई दुखद है। मैं कंपनी में open source k8s से जुड़ा काम करता हूँ, और 100% users ने Helm chart बनाने को कहा, इसलिए आखिरकार बनाना ही पड़ा
इस पर काम करना बेहद निराशाजनक है। फ़ाइल का नाम
foo.yamlजैसा होता है, लेकिन असल में वह YAML नहीं होती, इसलिए editor मदद नहीं कर पाता। YAML alignment ठीक रखने के लिए सारा डेटाindent 4से पास करना पड़ता हैसबसे निराशाजनक बात यह है कि Kubernetes की सारी capabilities को अपने तरीके से फिर से expose करना पड़ता है। अगर कोई
deployment.spec.template.spec.fooBarsजोड़ना चाहता है, तोvalues.yamlमेंdeploymentFooBarsजोड़कर उसे wire करना पड़ता है। हर feature के लिए यही दोहराना पड़ता हैयह सचमुच “बुरी चीज़ ही अच्छी है” के गलत दिशा में चले जाने का उदाहरण है। मैंने भी template implement करने के लिए
sed -e s/$FOO/foo/gजैसी भयानक चीज़ें की हैं, और शायद Helm भी ऐसे ही शुरू हुआ होगा। नतीजा गड़बड़ हैनिजी तौर पर, मैं
kubectlमें आने से पहले से Kustomize इस्तेमाल करता रहा हूँ और हमेशा काफ़ी संतुष्ट रहा हूँ। इसमें अजीब चीज़ें बहुत हैं, लेकिन कम से कम यह उन objects का मतलब समझता है जिन्हें यह generate करता है, इसलिए समय बचाता हैJsonnet कहीं बेहतर है। हम अपने k8s app के हिस्से के रूप में complex traffic routing के लिए Envoy deployment साथ में देते हैं, और Envoy config लंबी-चौड़ी है, लेकिन Jsonnet से उसे handle करना आसान है: https://github.com/pachyderm/pachyderm/blob/master/etc/gener...
मैं गंभीरता से jsonnet को Go template language में transpile करके सब कुछ Jsonnet में implement करने पर विचार कर रहा हूँ। कम से कम वह थोड़ा maintainable होगा, और
helm installबस काम करेगा, इसलिए किसी को पता भी नहीं चलेगालेकिन लगता है Helm ही Kubernetes का अंत बन जाएगा। अगर कोई प्रतिस्पर्धी computer allocation/container execution tool config के लिए एक ढंग की language लेकर आया, तो लोग रातोंरात शिफ्ट हो जाएँगे
sed -e s/$FOO/foo/gइस्तेमाल करने का मन हो, तो थोड़ा ज़्यादा standard और बेहतर solution के तौर पर envsubst देखना अच्छा रहेगाHelm charts को jsonnet से template या modify करने के विषय में Tanka भी मददगार हो सकता है: https://tanka.dev/helm
हालांकि जहाँ-जहाँ मैंने काम किया है, वे अब भी बदलाव से डरते हैं और tf/hcl और helm ही इस्तेमाल करते रहते हैं। कम से कम personal projects में थोड़ी राहत मिलती है
मुझे इसमें समस्या दिखती है। हालांकि जो किस्म के लोग config language के रूप में YAML चुनते हैं, वे इसे समस्या मानेंगे या नहीं, यह मुझे पक्का नहीं पता
इंसान-केंद्रित data representation और computer-केंद्रित data representation के बीच सीधा टकराव है। computers को Lisp जैसी चीज़ें पसंद हैं, और लोगों को Python जैसी चीज़ें
जो लोग Kubernetes config को computer से manipulate करना चाहते हैं, उन्हें Kubernetes का YAML इस्तेमाल करना अंदर ही अंदर चिढ़ाएगा। लेकिन Kubernetes community मुख्यतः YAML वाले लोगों जैसी लगती है, तो उन्हें क्यों परवाह होगी कि programming logic आने पर config files के साथ काम करना भयानक हो जाता है
YAML की कमी ठीक यही स्थिति है, और मुझे लगता है k8s से जुड़े लोग इतने समझदार तो आम तौर पर हैं कि इसका अंदाज़ा लगा सकें
“YAML, JSON का superset है” वाली बात, specification लिखने वाले documentation में चाहे जो लिखें, असल में सही नहीं लगती। अगर सारी YAML config को JSON में बदल दिया जाए तो DevOps team नाराज़ होगी
दोनों data formats समान meaning representation रख सकते हैं, लेकिन ऐसा तो उन सभी languages के साथ भी है जो same CPU architecture में compile होती हैं। JSON और YAML practical काम में अलग-अलग हैं, और दोनों को मिलाना अच्छा विचार नहीं है
बेशक लोगों ने आखिरकार उन्हें हाथ से लिखा, और जब वह असहनीय हो गया तो templates जोड़ने शुरू कर दिए। लगता है चीज़ें हमेशा इसी तरह आगे बढ़ती हैं
हाथ से लिखे text की जगह machine-generated config serialization text नहीं लेता; असल में उसकी जगह अक्सर अब भी हाथ से लिखे text में templates जुड़े हुए रूप लेता है
निजी सिद्धांत यह है कि मशीन द्वारा पढ़े जाने वाले code को generate करने के लिए string interpolation का इस्तेमाल नहीं करना चाहिए। template language बस fancy string interpolation ही है
SQL injection और cross-site scripting के नतीजे हम सब देख चुके हैं। जब तक arbitrary text को interpreter में डालते रहेंगे, ऐसी चीजें होती रहेंगी
इसलिए HTML बनाते समय भी template file इस्तेमाल नहीं करनी चाहिए, ऐसा मेरा मानना है
HTML के लिए template language के विकल्पों में Ruby का Haml और JavaScript का Pug है। ये languages tag, attribute और text node की पूरी tree specify करने का defined तरीका देती हैं
अगर आपको Python-style meaningful indentation पसंद नहीं है, तो JavaScript में JSX है। JSX में HTML जैसा दिखने वाला हिस्सा web document tree बनाने वाले
createElementexpressions में compile होता है, और जरूरत पड़ने पर उस tree को HTML के रूप में output किया जा सकता हैHaml, Pug, JSX HTML output कर सकते हैं, फिर भी वे template language नहीं हैं। उसी तरह
JSON.stringify(myObj)JSON के लिए template language नहीं हैमशीन द्वारा पढ़े जाने वाले code को, जहाँ संभव हो, target language की ज्ञात structure को समझने और उसका उपयोग करने वाले tools से generate करना चाहिए
Haml web document के अंदर inline code से बचने और HTML को ज्यादा साफ बनाने के लिए template system है, और Pug Node.js के लिए feature-rich template engine है
JSX strictly template language नहीं है, इस पर सहमति हो सकती है
आखिरकार ये सब HTML में compile होते हैं। फर्क बस इतना है कि ये string interpolation नहीं हैं, बल्कि ऐसी languages हैं जो syntax tree में parse होती हैं और valid structure की internal समझ के आधार पर HTML में render होती हैं
YAML template fancy string interpolation है, और या तो template language नहीं है या कम से कम बहुत खराब तरीके से implement की गई template language है
मेरा निजी rule है कि जब भी कोई value string में जाए, तो उसे अनिवार्य रूप से सही तरह encode किया जाना चाहिए
पहले मैंने इसी विषय पर लिखा था: https://kevincox.ca/2022/02/08/escape-everything/
सार यह है कि हर string का कोई न कोई format होता है जिसका पालन करना होता है—जैसे HTML, SQL, या इंसानों द्वारा पढ़ा जाने वाला terminal output। जब भी किसी value को string में डालते हैं, उसे उस format के मुताबिक ठीक से encode करना चाहिए, लेकिन हम लगभग कभी ऐसा नहीं करते
हम cuelang पर shift कर रहे हैं [1]। निजी तौर पर मुझे इसका design Jsonette से बेहतर लगता है
Kubernetes में पहले से state reconciliation है, इसलिए इस setup में जो चीज गायब थी वह deletion ही थी, और अब prune feature से वह संभव है [2]
[1] https://cuelang.org/docs/integrations/k8s/
[2] https://kubernetes.io/blog/2023/05/09/introducing-kubectl-ap...
कुछ error messages को समझना थोड़ा मुश्किल है, लेकिन यह पहले से ही इतने सारे errors पकड़ लेता है कि यह acceptable है। अब जब कभी सीधे yaml लिखना पड़ता है, तो तुलना में वह बहुत उबाऊ लगता है
ऐसे मौकों पर मैं आम तौर पर बीच में बोल पड़ता हूँ, “क्या आपने हमारे उद्धारकर्ता CUELang के बारे में सुना है?”: https://cuelang.org/
यह अभी Turing-complete नहीं है, लेकिन duplication हटाने के लिए काफी expressive है, उसी language में schema और data को एक ही file या अलग files में define कर सकते हैं, और इसमें union types भी हैं
यह YAML या JSON generate कर सकता है, और खुद को या YAML/JSON files को validate कर सकता है
सबसे बड़ा downside यह है कि मौजूदा implementation केवल Go में है, इसलिए subprocess या FFI की जरूरत पड़ सकती है
फिर वह हर application के लिए JSON files बनाती है, कोई tool XML definitions बनाता है, वे definitions architects के owned XLS पर apply होती हैं, और वहाँ से Helm charts पर apply करने के लिए YAML निकलता है
chart k8s client deploy करता है, और वह client API के जरिए JSON में main cluster से interact करता है
थोड़ा समय लगा, लेकिन हम हर काम के लिए सबसे अच्छे tool का इस्तेमाल कर रहे हैं