Are there some folks that *DO* think YAML might be useful as an option?


#1

I thought of a way to maybe still support it in an interesting hybrid kind of way. Let me know your thoughts if you think you MIGHT like this. It would be something we document in the advanced language features page.


#2

Hi Michael,

Mitogen was extracted from a project that had quite a complex Python DSL. That project is still on the backburner because I saw more immediate value in trying to understand and fix an existing system ;) Meanwhile, one thing I did not realize until quite late with Ansible is the extraordinarily flat learning curve it features and how that contributes to its success. A great deal of its users are afraid of Python, YAML addresses that fear simply by not being "code" in the sense that it's some scary thing I imagine in kind of the same way "math" gives me the heebie-jeebies :)

Similarly the learning curve around a YAML based system can be much gentler, because you're not asking people to write code, you're asking them essentially to edit config files, and almost everyone perceives that as a simple task.

There is extraordinary value in a Python-based DSL, however I'm not convinced it is sensible to have an interface that is on hard mode by default, which really is the perception for a lot of non-developing users.

Any sensibly designed declarative system should easily be able to swap out its frontend without affecting a core model -- as long as that model actually exists as opposed to say, basically being a neat macro language for running/extending a bunch of built-in functions.

So definitely a +1 on YAML support, if not for end users, then at least for the design discipline that comes along with maintaining multiple frontends

edit: to add a counterpoint/another angle: overly model-heavy systems scare people too. It's an interesting balance

edit 2: it'd be a glorious evolution if something like TOML was used in place of YAML. They're both loathsome, but at least it's possible to comprehend why TOML is loathsome ;)


#3

Hey dmw! Nice to see you here!

I'm in a bit of a unique position in that I can build tools for less-than-maximum-size audiences. So if this is "Ansible for People who like Python" that is ok for me. I'm happy to have a small crowd of people that really like it and am not so much trying to please everyone, but of course, listening to everyone is important too!

I personally like Python, and like the power that the compiler gives you. Things get checked up front, there's so much more power. So far, the experience of writing content has been REALLY good. There is one stylistic nit I've been debating and that is just this. Whether it is better to do the classic Python DSL thing:

def set_resources(self, r):
r.File(...)

The trick is implementing that, you run the risk of quickly doing a lot of getattr() magic that leads to some gross tracebacks. That's minor though.

I just DO know there are situations where there are teams might want to break out of Python, or have folks that don't want to deal with it.

TOML is interesting conceptually, but I worry it is a tricky language to describe a tree structure. A gist of converting one of my examples (or any old ansible playbook) into TOML might serve to prove me wrong in that?

I mean I like this idea:

[role_name.handlers]

[role_name.resources]

But what would you put inside the handlers and resources section? I'm worried that if we do

[role_name.resource.File]

That gets long quick, and also doesn't stand out.

So IMHO, that doesn't work out, but I'm open to be proven wrong there.

I also mostly don't want multiple backends, in a way, because it bloats the list of examples a fair amount, and that becomes a chore to maintain, and then the community has trouble sharing between those that prefer Latin and those that prefer Greek, as it were?

So the thinking here is that this is part of a compromise - it says - this is here if you need it, but we're not going to make this the suggested thing.

Because, ultimately, this is a system for those that like Python, and we are going to double down on that?

In the past ansible was pretty successful at teaching people python who wanted to work on the modules, so I'm not super worried about it.

In the very earliest drafts of OpsMop (I dont' think the code ever got pushed), it could actually fully deserialize and serialize to JSON, but I ruled out having a need for it. That structure definitely would not translate to a good human readable format for sure :)


#4

if the frontends were truly equivalent, you could write examples in one and have them regexed into the other :) Microsoft used to have a thing called CodeDOM that did basically that, all the .NET doc examples appeared in every language, because the languages were equivalent.

On the pure-Python front, you also have those inline ascii art variable annotations that nobody seems to use for anything but type hints. I'm not sure what niceties become possible with a Python 3 DSL, but they certainly look insanely useful.

No opinions on your target userbase -- just throwing in some opinions about config vs. code perceptions. :)


#5

Have you looked at HCL as another option? Config language used for Terraform, but GitHub also decided to use it for their new Actions definitions.


#6

I didn't even think the variable annotations were pluggable. But yeah, nobody does seem to use those.


#7

I'm trying to be nice but as Mitchell was pretty down on YAML on Twitter in the past I'll respond about the same - I'm not a fan. I don't like the way it's variables and loops work, and think rather than getting easier to use subsequent editions of Terraform are getting worse and more academically complex.

That's not to say HCL here would have the issues TF has for simple static representations as an optional data format, but I don't want to tie myself to an unpredictable upstream.


#8

I should qualify this a bit - I like where OpsMop is headed a lot - this is about if people don't want to code in Python can we maybe accomodate them a little.

So if there was a way to do specifically YAML, what might the gist look like? Do we need it at all?

If everybody is here because we like Python, but just think other people might like it, we don't need it :)


#9

Also maybe this helps explain where I was going:

I'm still thinking individual resource lists, not encoding everything in YAML. I kind of want to force people to use some Python. An example might be that they want to maintain a list of users in a text file.

This is something you could write some code to do, but if you don't have to, all the better.


#10

Updated the gist with a comment - I'm kind of liking this new syntax:


#11

If we take @dmw's suggestion about TOML and the Bundle idea and merge them, this might work out:

[User]
name=jsmith
full_name="John Smith" 
email="foo@example.com"

[User]
name=artvandelay
full_name="Art VanDelay"
email="art@example.com"

[User]
name=badguy
absent=1

This actually works pretty nicely, I think! You could only use it to declare a list of resources and it approaches the original goal Ansible had - keeping things as simple as grocery lists.

You could define multiple resources per file or just one.

Even more friendly than YAML, but avoids the problem of nested TOML, which gets ugly, by basically keeping this at INI file complexity.

It might be used like this:

class AddAllUsers(Role):

    def set_resources(self):

       user_bundle = Bundle("users/*.toml").filter_type('User')
       resources = Resources.add_bundle(user_bundle)
       for x in user_bundle:
            key = "ssh_keys/%s.id_rsa.pub" % x.name
            if os.path.exists(key)
                resources.add(File(user=x.name, from_file="ssh_keys/%s" % x, owner=x.name, group=x.name))
       return resources

#12

I went over https://github.com/toml-lang/toml#example and it seems neat on first site.

I also have no idea what any of the python code is supposed to signify. I'd say I'm average with Python but it makes no sense whatsoever.

Perhaps a working sample would be easier to grasp.


#13

Sure! There can definitely be an example when this is implemented.

At this point I’m talking about loading an array of objects from a file that may contain different types of objects.

I’m also trying to show you could just easily add those to resources but if you want to walk the bundle and filter in code that would work too