Travis Sturzl
Jul 25, 2017 · 3 min read

Also no configuration management system I have ever seen would be properly described as “imperative”. In fact using a DSL in its very essence, to me, seems to describe it as declarative.

I get your point, but I don’t think its really the right terminology. Imperative configuration management, to me, would be literally using shell scripts to configure your host. In ansible you might have something relatively(relative to config mngmt) when you right a role, but really the state of the system is not controlled by a series of logic, but rather a module that sets something is the state that you **declare**, for example you declare whether or not a file exists with the file module rather than checking the state of the existence of the file then performing your action based on that. Technically you can do exactly that, but its not in any way idiomatic. Really this is the general premise of configuration management tools in the modern day is that they specifically are declarative.

Ansible roles are however procedural, rather than dependent on the state of eachother. So in a higher level sense imperative might be somewhat applicable, simply because you aren’t managing the entire thing declaratively in a very high level sense like you might with puppet. Instead you declare the state of things in a relatively low level sense; per file, package, a single line or block in a file, etc. rather that defining the state of things as a homogenous unit. However, that’s only considering roles, when you make a playbook the idiomatic way of doing that is creating roles which do exactly that, they configure something to be set in a specific state from a high level perspective, such as configuring a DB(installing it, configuring it, setting up a restricted account for it, selinux profiles, tweaking ulimits, etc). From the playbook perspective, if done idiomatically, you achieve something I would consider strictly declarative.

Of course you can still run shell scripts and commands, or do something that doesn’t consider the state, but in many cases ansible will warn you that you should use a module intended for that, and at the end of the play it gives you a run down of state changes on the machine, this is really to just fill the gap where a module might not be available to suit that specific need(I’d consider that an edge case); Regardless, that isn’t exclusive to configuration management, and certainly Puppet doesn’t evade that, and more specifically orchestration management doesn’t evade that either. None of them do, or probably ever will cover every use case. In fact the only means of configuring via terraform or cloudfront in my experience has been shell scripts unless you use something else on top of them(which is what my other rant is about).

In summary, I don’t think you can say any of these things are actually imperative, because you aren’t changing your state with a series of logic or logic that needs to check its own state, you are declaring the state. You aren’t specifying the control flow, but rather specifying the state in which the control flow is determined for you. In otherwords I personally feel like declarative means you’re state is almost irrelevant and you error out when the declared state cannot be reached, this sounds very much aligned to what configuration management tools do.

    Travis Sturzl

    Written by