openlang

Swapping the config language won't fix drift

Replacing HCL with a general-purpose language gets pitched as loops and functions, and drift rides along as a complaint. Drift isn't a language problem. It's the real resource changing behind the file's back, a disk resized by hand, and a Python program emitting the same desired state drifts the same way. What a real language changes is how much a reviewer has to execute in their head. Keep the plain syntax and run a scheduled plan that fails loudly when reality and the file disagree.

后续讨论 5

顺着彼此的依据读下去
  1. 固定链接

    Not convinced. Drift isn't the language's fault, agreed, as far as it goes. I read more HCL than I write, but the files I've seen grow a programming language anyway. for expressions, conditionals, functions, modules calling modules. You end up writing real logic, just with much thinner tooling for stepping through it or testing one piece alone.

    At that point I'd rather have a real language and a rule that the program stays dumb. Flat data in, resource list out, no cleverness in between.

  2. 固定链接

    A plan check fails loudly only if the policy reading it can fail. A rule whose body tests input.resource.encrypted == false is undefined when the field is absent, so the rule produces nothing and the resource passes. Remove that field. What does the query return? Try a missing attribute and an explicit false as inputs, because only one of them is denied.

  3. 固定链接

    Editor types are the part I'd actually want, and catching a misspelled attribute before anything runs is worth something. It still only describes what the program meant to send. What happens if the provider hands back a field our type doesn't have? The plan is the first place the real state shows up, and nothing on our side has inspected it.

  4. 固定链接

    Fair, as far as the editor goes. Tried that in Python on a small generated config. With a TypedDict the checker did flag a misspelled key at the call site, before anything ran. The other half went the way you'd fear.

    from typing import TypedDict
    
    class Disk(TypedDict):
        name: str
        size_gb: int
    
    loaded = {"name": "data", "size_gb": "40", "zone": "b"}
    d = Disk(**loaded)
    print(type(d).__name__, repr(d["size_gb"]))   # dict '40'

    A string where an int belongs and a key nobody declared, both accepted without a sound, because at runtime the class is a plain dict. So typed construction comes free with annotations and checked input doesn't, and I haven't found a way to make the second one cheap.

  5. 固定链接

    There are three inputs to try, not two. Next to an absent field and an explicit false, the plan JSON can mark a value as known only after apply. It then sits in after_unknown as true and is simply missing from after. A rule that only looks at after reads that case the same as the absent one.

    When I decode something like this I want each case to have a name before any rule runs. In OCaml that's a small variant with Absent, Unknown and Known of bool, and a match that forgets Unknown gets a warning. Policy languages don't give you that warning, so the three test inputs are the closest substitute.

同一个问题的其他角度

  1. Launching the consumer on a stopped event

    Got a question about a supervisor rule that treats a stopped process as a finished one, and a tiny repro makes the problem ob…

    回复 17最近活动 bashpython
  2. What does a --hash line actually pin?

    A requirements file with --hash on every line installs cleanly on my laptop and fails with a hash mismatch in a fresh Linux c…

    回复 8最近活动 python
  3. After the Kotlin DSL move, subprojects can no longer find implementation

    Moving an old multi-project build from the Groovy DSL to the Kotlin DSL. The root build.gradle had this block. The root I con…

    回复 2最近活动 kotlingroovy