Here's the list of the main features and design-goals I have in mind for freckles:
Very minimal code
One of the main goals was to provide very minimal and easy-to-use command-line and configuration interfaces. Basically, one command (what to do), and an absolute minimal set of parameters (details on how to do it). Independent of how complex the task is. Something simple like:
- user-exists: name: admin uid: 1001
or quite involved, with a set of services being setup under the hood (MariaDB, PHP, Nginx, LetsEncrypt in this case):
- wordress-standalone: wp_title: My wordpress site host: dev.frkl.io use_https: true wp_admin_email: [email protected] wp_admin_password: ask
Both should look similar, and readers should be able to grasp instantly what is going to happen.
More than one task can be bundled into a new single, more specialized task straight away, with very little overhead. Instantly abstracting away whatever input is not needed for that specific tasks desired outcome. Not incurring any 'complexity-debt' by waiting until the last layer to think about the interface to the user -- the interface sorts itself out, almost. A little bit like some aspects of functional programming, sorta, kinda.
By default, a user should get by with only having to specify the minimal amount of instructions and information to get a certain task done. If necessary, the interface should allow for more flexibility though, at the expense of readability and ease-of-use. Adjustable-leakiness-abstractions, in a way.
I don't know yet how controversial the elastic, non-schema data format freckles uses will prove to be. I admit this was a very subjective design decision -- the exact kind of interface I would want to use. This might or might not work for others. We'll see, I guess.
As I've said in other places: it's an experiment, I haven't seen anything like this (although I'm sure somebody did something similar before), and I don't know how it will pan out, which sort of problems it'll create, how often those problems will arise, and how severe they'll be. If worse comes to worse, it is easily possible to just use the exploded 'proper' schema, so if you feel very strongly about this point but still want to use freckles, this is an option.
Re-usable configuration
freckles make it easy to share your frecklet and the the context it is run in, with your team, or the wider public. Equally, it is very easy for you to re-use frecklets somebody else wrote, and integrate them into your own personal collection(s).
As for combining frecklets: I think one of the reasons why Docker turned out to be so successful is the way Dockerfiles depend on each other. The user never sees it, but when you inherit from another image you basically just use the instructions from the parent image Dockerfile, and that parents Dockerfile, and so on. You basically just glue your Dockerfile onto the bottom of it all. If you'd see all that came before, and had everything in one place, it'd look quite ugly and confusing (depending on how many levels of inheritance there was, of course). But, because you only see your part, and rely on the parent Dockerfiles to have done their thing (black-box-style -- even though, of course, you can have a peek under the hood), the format ends up to be quite readable, and the whole thing is easy to use.
freckles does something similar, but it takes the concept a bit further by formalizing a few things around the edges. With the intention to make it simpler to create generic tooling around it. Which, in turn, should make it relatively easy to create really specific tooling around that generic layer. We'll see how that works out.
Simple integration
freckles only requires a single list or dict-type data structure, which you can create with whatever programming language you like. As long as you can convert it to either yaml, json, or toml, you'll be good.
Until language-specific client libraries are available, you'll have to make one external call to the freckles binary within your code. That's easily done in most programming languages though.
There'll be a freckles service component sooner or later, as the client-server architecture makes sense in a lot of scenarios. This will be build on top of the framework, not the other way around. Plus, it's quite easy to do it yourself (esp. if you use Python) if you need something like that now.
Self-sufficient, portable
No requirements except the freckles executable. Not even that, if you choose to use the freckles bootstrap script (which you can of course host yourself, if you want): in that case all you need is an installed wget or curl and a string to paste into your console window.
No dependencies on any external, internal services, or technologies (except the ones it ships with and uses transparently).
You don't need to use Docker (although you can use freckles with it, both as a RUN
command inside a Dockerfile, and to control it), or Kubernetes (same), or any other technology in that field. And no dependency on any cloud service like AWS, GCE, or that other one. But, again, you can use freckles with/on them if you want to.
In general, I do think there is a danger in having your infrastructure and container configuration/state management in a technology- or provider-dependent format. Not always, but I do think vendor- or technology lock-ins are a worry. Short and medium term it never really seems that way, and the advantages of ignoring it are often just too compelling. This is a longer discussion of course, and this here is obviously not the place to have it. freckles enables you to implement the core of your workflow quick and easy, and it lets you run it with whatever or wherever you want. There will be some adjustments necessary if you switch technologies or providers, but (hopefully) less than you'd have to implement without freckles.
One could argue when using freckles you still depend on freckles. Which is true for now, but in time, if this idea has any merit, I'd imagine similar implementations of some of its ideas to crop up. And the basic units, frecklets, are structured and simple enough that they don't really need to follow a standard to be easily re-used and converted.
Auto-documenting
freckles has a self-documenting feature, the binary provides access to and auto-generates the documentation of all its sub-systems.
More importantly, freckles auto-generates documentation and argument lists for all frecklets that live in the current context. This was implemented to support rapid prototyping and frictionless development, and it can easily be re-used in tools that are build on top of it. `frecklecute`` is an example here, it auto-generates cli arguments including the automated validation of user input.
Full ownership
Thinking about whether I would use a tool like freckles myself, I knew I would only do that if it allowed me full control, and I could use it on my own terms, poke its code, all that jazz. That also means it needs to be available locally (not just via an API), with the full source code available and me being allowed to change/fix whatever I want. Without having to rely on any SaaS/PaaS/*aas provider, which usually comes with proprietary and non-re-usable configuration and adapter code, etc.
Also, personally, I don't like the 'pay-monthly/yearly/regularly' business model all that much, even though it seems to be easier for businesses in many cases. Which is why I decided on the license model I have at the moment: you buy it, you own it. There might be an (additional, optional) subscription-based private/company license later on though, ping me if that interests you.
Leaky abstractions
Note: Just ignore this section if you don't know what a leaky abstraction is. If you know what it is, and have a firm opinion on it which you are prone to voice on social media, please also ignore this :-)
I like leaky abstractions, I'm half-ashamed to say. In freckles, I consider them to be a feature. Not in and by themselves of course. But because they are managed and funnelled in a way so that they are hidden to an end-user by default, as much as practically possible. But the deeper you dive into freckles itself or a task described by a frecklet, the more you get exposed to that layers abstraction. And you have the full power of that layer at your disposal. And also the full power to ignore it...
I should probably write a longer post about this topic, but in short: I consider this a very pragmatic approach, the alternative would have been to implement a system that hides those abstractions 100%, or at least as much as possible. Which would have had some advantages. But I believe that the managed approach is better overall, and it is more sustainable as well. By not having the developer or architect decide in advance which layer should be shielded, and which one should be accessible, freckles gives more power to the user (which was also in itself a very deliberate design-decision).