16 Ways OpsMop Improves On Ansible: Number 17 Is An Off-By-One Error

Just recently I unveiled OpsMop, my new entry to revisit the IT automation space. It is complements another recent release of mine, Vespene.

There’s been some question: Why this and why now? Do you not like Ansible? Is it just the new declarative Python DSL or is there more to it?

TLDR: Ansible is still great, but after making a tool in 2012 that lit off like a rocket and is now the most popular configuration language today, there wasn’t a lot of time to keep evolving it to where I wanted it to go. I had to spend a lot of my time keeping a early-stage company on track and excessive community size (modules especially!) meant the language didn’t keep improving. As I see a language that was designed to have the complexity of grocery lists evolve to be turned into a programming language, I want to explore the question — what would I do differently now?

I think it’s possible to make two things and for them both to be good. Lambourghini started out making tractors. Ansible is a good tractor — it does hard no-nonsense work. This is my sports car project. It will appeal to different audiences, and some of the same audiences.

Here are the main takeaways of how OpsMop differs from Ansible:

  1. Real Loops. Any programming constructs and external interactions are possible when your programming language is a real programming language. If you want to pull users from a REST call or SQL, you can do it easily. Yes, I have heard all your complaints on this for many years. Finally here you go :)
  2. Explicit and obvious variable scope — rather than having nearly a dozen variable scoping precedence rules, OpsMop variable scoping is just like any programming langauge, and related to depth.
  3. Explicit templating — rather than trying to template everything to figure out what is a variable and what is not, templating in OpsMop happens only when you ask it to. There’s no chance of a “{{“ in a text file mucking up the system.
  4. Traceback granularity — because there are no forks and modules are part of the main program and not external scripts, when a traceback happens, you get the full stack for debugging. Module calls are function calls.
  5. OO API and Internals — the API is exceedingly straightforward, even compared to the Ansible 1.9.X Runner API. The internals, as well, are better designed, and are not so much based on dicts and arrays, an artifact of Ansible being too heavily designed around what YAML is — dicts and arrays. In OpsMop, if you don’t like any behavior, you can replace it and reuse it. There’s no distinction between what is a pluggable module and what is the core API. Similarly, there are object-oriented model providers — strong OO on the backend enables providers to share logic, leading to increasingly easy to develop modules that have a strong consistency with one another.
  6. Speed — by not forking python between every execution, hundreds of resources can be evaluated in seconds (provided you are not, of course, waiting on a package manager).
  7. Strong type checking — all resources are typed checked at construction time, allowing the system to look for missing files or invalid arguments far before it starts to configure a system. Ansible did well, but largely did not have awareness of what resources it was going to run before it ran them, and new tools have sprung up to attempt to add external validation (ansible-lint, etc). With OpsMop, this should never be necessary.
  8. Roles are enforced — Roles were the best thing about Ansible, and OpsMop makes sure you learn them by requiring at least one role for each OpsMop policy. The implementation also eliminates the famous “skipped” bug where when skipping a role you get a message that the system skipped 20 tasks. It just skips the role — roles aren’t a layer on top of the system, roles are real things.
  9. A real graph — while I’ve always been one to fight against making something sound academically complex to sound like “only we could solve it”, OpsMop technically *does* have it’s own directed acyclic graph of sorts now. Each policy is a tree of resources, and handlers are like little dotted lines pointing towards other trees of resources. We still keep handlers listed separately for clarity.
  10. Pull and Push modes — these days, it’s almost more likely a config language will be used at image build time than live against a production running system. That being said, stateful services still need management and task execution too and aren’t going anywhere! Once complete (likely within a month or so) — OpsMop will have exceptionally fast pull and push modes alike, supporting multiple transports. While SSH has been proven to scale well into thousands of systems, solutions like ansible-pull were created to provide alternatives. With OpsMop, such alternatives will be first-class citizens and ideally faster than any system on the market.
  11. Depth vs Breadth — it’s definitely attractive that a tool has thousands of modules, but most users will only need 50 or so. OpsMop will seek to have an exceptionally well engineered set of core modules and will not seek to explore cloud provisioning (except maybe some load balancer support maybe) or network hardware management. This should allow a more robust set of core modules and avoid the GitHub issue queue problems that have been a challenge for the ansible project. We would rather focus on making what we have really razor-honed.
  12. More cohesive modules — small things have been done here and there, like unify “file” and “template”. Rather than having to say “state=present/absent”, there are flags for “absent=True”, making things more explicit and also responsive to boolean truthiness.
  13. Lazy evaluated facts — one of the issues with some ansible playbooks were that fact evaluation could take a very long amount of time, resulting in the creation of “gather_facts: False” as a feature. In OpsMop, facts are functions and are not evaluated until they are needed, and then can be evaluated only once.
  14. Strong API compatibility — by taking years of experience into practice, we can make good up-front language choices and avoid compatibility breaks between releases.
  15. While OpsMop will be code based, we’ll support loading collections of variables from easy TOML, YAML, or JSON lists, or even external programs that generate those lists. If you want a list called “employees.toml” and another list called “former_employees.toml”, making your user policy match would be like 4 lines of code. Of course, there is always LDAP :) Freedom to jump between code and data should be the best of both worlds.
  16. True dry-run modes. Dry-run is more accurately modeled. Ops-Mop generates a plan of actions to perform for any resource. It then fulfills that plan, if you want. If the plan doesn’t match up, it is an error.

I think all of this makes a tool you might have to do a little more to learn, but it will be more easier, more flexible, and more cohesive once you learn it. It won’t have quirks, it will follow a principle of least surprise. None of these things are reasons to stop using Ansible, because it’s still a good program and some people agree with my original intent — that configuration should look like a grocery list. There are a lot of different views — As I always have said, choose what tool fits your brain.

OpsMop is still in a language-preview phase — this week, the most important core modules will be finished for the most popular platforms (CentOS, Ubuntu, Debian) and we’ll be wide open to pull requests on December 1st 2018. At that point, it should be capable of installing and configuring nearly most basic applications, provided you can defer just a bit to the shell module for the odd stuff (the shell module is very good, and conditions and stuff like ‘register’ already exist!).

For more info, check out docs.opsmop.io

For those who are interested and like where this is going, I greatly look forward to working with you. The best parts of open source are all about enabling future surprises. Bring your ideas and let’s design some awesome new tools that we all want to use and work on together!