2 पॉइंट द्वारा GN⁺ 2024-01-24 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • 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 टिप्पणियां

 
GN⁺ 2024-01-24
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 भी नहीं हुआ

    • इस point पर मुझे YAML से ज्यादा pure JSON बेहतर लगने लगा। निर्णायक बात यह थी कि 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 के $schema tag को भी support करते हैं। हमने product में यह feature जोड़ा, और docs पढ़े बिना सिर्फ tab दबाकर configuration file बना पाना सच में बढ़िया है
      YAML में भी YAML language server से यह संभव है, लेकिन tab key indentation के लिए भी चाहिए होती है, इसलिए usability खास नहीं रहती। JSON भी perfect नहीं है, लेकिन कम से कम text "no" true नहीं होता
    • YAML इस्तेमाल करने के फायदे के तौर पर अक्सर सुनता हूं कि JSON में comments नहीं होते, लेकिन समझ नहीं आता कि इसके लिए पूरी तरह अलग language पर क्यों switch करना पड़े
      configuration पढ़ने से पहले comments हटाने वाला एक filter लगा दें, इतना ही तो है? यह YAML में बदलने से मुश्किल नहीं होना चाहिए
      YAML ज्यादा readable है, यह बात भी मुझे ठीक से समझ नहीं आती। configuration संभालने की तकलीफ curly braces और square brackets को कुछ सेकंड कम parse करने से नहीं आती, बल्कि सैकड़ों lines की configuration में missing spaces या tabs की वजह से यह पता न चलने से आती है कि गलती कहां है
    • GitHub Actions चाहे जिस चीज़ से configure किया जाता, खराब ही रहता। क्योंकि यह data structures से program को describe करने की कोशिश करता है
      Ansible भी वही गलती करता है, और ढेरों tools भी ऐसा ही करते हैं
    • AWS CloudFormation के दिनों से ही मैं कुछ ऐसा ही सोचता आया हूं। 4 साल पहले मैंने AWS द्वारा publish की गई JSON file से सभी resources और Python type hints generate करने वाला एक experimental CloudFormation generator बनाया था, और वह काफी ठीक चलता था: https://github.com/weberc2/nimbus/blob/master/examples/src/n...
      CDK उसी तरह काम करता है या नहीं, यह ठीक से नहीं जानता। थोड़ा हाथ लगाया था तो वह मेरे बनाए “CloudFormation generation” experience से काफी अलग लगा, और CDK की खूबियां ठीक से समझ नहीं आईं
      ऐसा लगा मानो YAML/template problem को inheritance/magic problem में बदल दिया गया हो। AWS CDK, Terraform CDK, Pulumi इस्तेमाल कर चुके लोगों के experience और सुनना चाहूंगा
    • GitHub Actions में YAML anchors support नहीं हैं, इसलिए तकलीफ और बढ़ जाती है। यह कम से कम minimal composability तो दे सकता था, अफसोस
      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 इस्तेमाल करें, वह कहीं बेहतर होगी

    • एक समय मुझे बहुत बड़ी संख्या में servers पर bootstrap और patching के लिए periodic तौर पर चलने वाली Ansible playbooks manage करने का काम मिला था
      मिलते-जुलते काम के लिए मैंने Chef इस्तेमाल किया था, और Ruby होने की वजह से अपनी logic आसानी से define कर पाना, loops और सही variables इस्तेमाल कर पाना अच्छा लगा
      मैं समझता हूँ कि Ansible non-programmers के लिए design किया गया है, लेकिन जो लोग basic programming से परिचित हैं, उनके लिए conditional tasks और loops से भरी Ansible playbook को Jinja templates के verbose syntax में कैद करने से बड़ा नरक कुछ नहीं
    • आजकल के stack में language embedding नाम की architecture लगभग भुला दी गई लगती है। पहले, अगर application पर्याप्त complex होती थी, तो core C/C++/Java आदि में बनाते थे, और scripting चाहिए होती तो ऊपर LISP या Lua जैसी चीज़ embed कर देते थे
      लेकिन अब आम तौर पर JSON/TOML/YAML parser लाकर readConfig function बना दिया जाता है, और जहाँ embedded interpreter ज़्यादा सही होता, वहाँ भी ऐसा ही किया जाता है
      developer के नज़रिए से complete language embedding और application bindings देने की तुलना में config format में complexity जोड़ना आसान है। इसलिए लगता है कि लोग तरीका ही भूल गए हैं, या यह संभव है—यह सोचते भी नहीं
    • Pulumi आकर्षक है क्योंकि आप अपनी पसंद की language में लिख सकते हैं और HCL छोड़ सकते हैं, लेकिन व्यक्तिगत रूप से मुझे यह स्पष्ट रूप से ज़्यादा खराब लगता है। infrastructure code declarative होना चाहिए, तभी predictability, reproducibility और maintainability बढ़ती है
      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 रोक देता है
    • समस्या यह है कि language geeks दूसरे language geeks के लिए languages बनाते हैं
      वे आजकल 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 files generate की जा रही हैं। config को खुद JSON file आदि में रखे जा सकने वाले रूप तक सीमित करना बहुत उपयोगी है
      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 वाली शर्त तोड़ देता है

    • यह पूरे software में दिखने वाला pattern है। system जिन primitive elements और fundamentals पर आधारित है उन्हें सीखने के बजाय, उन्हें बहुत कठिन मानकर उनके ऊपर की ढेर सारी abstractions सीख ली जाती हैं
      lower-level details से बचाव तो मिल जाता है, लेकिन problem आने पर diagnosis और debugging को मुश्किल बनाने वाली विशाल abstraction stack से जूझना पड़ता है
      असल में क्या हो रहा है यह पता लगाना कहीं ज्यादा कठिन हो जाता है, और abstraction layer पर निर्भरता के कारण provider द्वारा निकाले गए updates और dependency graph की दूसरी समस्याएं भी अपने सिर लेनी पड़ती हैं
    • हमारे system में हम jsonnet इस्तेमाल करते हैं और इसका k8s से कोई संबंध नहीं है। यह बड़ी लोकप्रियता पाने की बजाय complex configuration के लिए एक niche tool है, और बहुत promote किया गया tool भी नहीं है
      जो काम चाहिए वह लगभग बिना समस्या कर देता है, cross-platform है और कई languages में इस्तेमाल किया जा सकता है। मैंने इसे C++, .NET, JVM executables में embed करके देखा है
      resulting JSON configuration को ऐसे विशाल tooling के साथ इस्तेमाल किया जा सकता है जो विकल्पों toml/yaml/hocon/ini आदि में मिलना मुश्किल है। HOCON को non-JVM languages में इस्तेमाल करने की कोशिश की, लेकिन हमेशा कोई edge case अटक जाता था
    • दूसरी requirement शायद पूरी न हो, और तीसरी तो निश्चित रूप से पूरी नहीं होगी, लेकिन: https://cdk8s.io/docs/latest/
    • simple रखने का विचार अच्छा है, और install method के तौर पर हम भी जितना हो सके kustomize या plain yaml इस्तेमाल करने की कोशिश करते हैं
      लेकिन असल में बड़ा system manage करते समय आखिरकार templates के फायदे से बचा नहीं जा सकता
    • kustomize और खासकर helm बहुत confusing हैं, जबकि Kubernetes YAML files लिखना और समझना बहुत आसान है
  • यह देखना मजेदार है कि 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 तब भी चाहिए

    • एक client इसी तरह का काम बहुत गंभीरता से करने की कोशिश कर रहा है। हर product के लिए 1500 lines से ज्यादा की “configuration” file है, और इसका इस्तेमाल technical drawings और production files बनाने में होता है
      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

    • यह 2010s की शुरुआत वाले Java की गलती दोहराने जैसा ही है। उस समय अक्सर पूरी application dependency injection configure करने वाले विशाल XML blob से जुड़ी होती थी
      DTD और XML validation होने के बावजूद उसमें देर से fail होने और समझने में मुश्किल error messages देने वाली परिचित विशेषताएं थीं
      तब बहुत निराशा XML पर निकली, लेकिन 2020s के मध्य के YAML hell को देखकर लगता है कि समस्या markup language खुद नहीं थी
    • बिल्कुल। हम ytt[0] इस्तेमाल करते हैं, जो “Python dialect Starlark programming language का थोड़ा modified version” है
      YAML template के कहीं अंदर logic दबा देना मुझे सचमुच नापसंद है
      [0] https://tanzu.vmware.com/developer/guides/ytt-gs/
    • Kubernetes से जुड़े कुछ workplaces में सचमुच YAML engineer शब्द इस्तेमाल होता है
    • YAML serialization formats की दुनिया का Bradford Pear जैसा है। शुरुआत में अच्छा दिखता है, लेकिन जैसे-जैसे project पुराना होता है और YAML बड़ा होता है, यह अपनी ही शाखाओं के वजन से ढह जाता है
    • इससे भी बुरी बात यह है कि हर generation यही गलती दोहराती है। S-expressions जवाब हैं या नहीं, पता नहीं, लेकिन Terraform HCL तो शुरू से बनना ही नहीं चाहिए था
  • 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
    • मैं इस अनुमान पर विश्वास करना चाहता हूँ कि Helm Kubernetes का अंत बन जाएगा
      हालांकि जहाँ-जहाँ मैंने काम किया है, वे अब भी बदलाव से डरते हैं और 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 काम में अलग-अलग हैं, और दोनों को मिलाना अच्छा विचार नहीं है

    • विडंबना यह है कि अगर मेरी याद सही है, तो k8s manifests शुरुआत से ही machine-generated होने के लिए माने गए थे, लोगों द्वारा सीधे लिखे जाने के लिए नहीं
      बेशक लोगों ने आखिरकार उन्हें हाथ से लिखा, और जब वह असहनीय हो गया तो templates जोड़ने शुरू कर दिए। लगता है चीज़ें हमेशा इसी तरह आगे बढ़ती हैं
      हाथ से लिखे text की जगह machine-generated config serialization text नहीं लेता; असल में उसकी जगह अक्सर अब भी हाथ से लिखे text में templates जुड़े हुए रूप लेता है
    • “YAML, JSON का superset है” का मतलब बस इतना है कि हर JSON document एक valid YAML document है। इसका मतलब यह नहीं कि YAML, JSON जैसा ही है
  • निजी सिद्धांत यह है कि मशीन द्वारा पढ़े जाने वाले 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 बनाने वाले createElement expressions में compile होता है, और जरूरत पड़ने पर उस tree को HTML के रूप में output किया जा सकता है
    Haml, Pug, JSX HTML output कर सकते हैं, फिर भी वे template language नहीं हैं। उसी तरह JSON.stringify(myObj) JSON के लिए template language नहीं है
    मशीन द्वारा पढ़े जाने वाले code को, जहाँ संभव हो, target language की ज्ञात structure को समझने और उसका उपयोग करने वाले tools से generate करना चाहिए

    • Haml, Pug, JSX template language नहीं हैं—यह बात तब तक समझ में नहीं आती, जब तक template language को “fancy string interpolation” मानने वाली निजी definition न अपनाई जाए
      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 है
    • हर template language string template language नहीं होती। उदाहरण के लिए, अगर PHP को text के लिए template language माना जाए, तो उसी logic से XQuery XML के लिए template language है
    • यही समस्या का मूल है। YAML और templates तो बस ध्यान भटकाने वाली चीजें हैं। अंततः बात इस पर आती है कि string बहुत generic type है और हम उसे आलस में इस्तेमाल करते हैं
      मेरा निजी 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...

    • मैं cuelang recommend कर सकता हूँ। हमने company में इसे इस्तेमाल करना शुरू किया है और यह वाकई अच्छा है
      कुछ 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 की जरूरत पड़ सकती है

    • हमारे पास एक pipeline है जो बहुत concise cuelang files accept करती है
      फिर वह हर 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 का इस्तेमाल कर रहे हैं
    • dhall से तुलना करें तो कैसा है?