Hi all,
I have been a bit lurking on this thread, as I find the subject very interesting, and have been loging to solve similar use cases.
First of all, to answer Jeffrey Lee’s initial question, no, ansible does not have anything specific to manage versions of playbooks/roles. I might have an idea on how to hack it into ansible currently, but I’m not sure that would scale well. See further down this post on this idea.
My use case primarily involves what could be called something like an application’s life cycle manageent. Let me give a more or eless simple example.
My main $cust is a Java shop, and manages around 100+ different Tomcat applications. This basically translates to 1 tomcat role to deploy all of them, with differences between the application being defined withing the appliactions artefact/code - obviously - and other parameters in the inventory.
This leads to two problems: easily manage e.g. the needed java version and tomcat version, per application, per version of the application, and this separately for every environment (development, testing, staging, production, …) where the app gets deployed. This can be done of course with inventory variables, but standard ansible inventory (the ini files) don’t scale well when you have 600-1000 apps-environments to manage and to have those variables evolve. Some higher level application exporting it’s data with an Ansible Inventory script come to mind here.
Now this is only one part: managing parameters in the inventory. Managing role versions is another one. Granted, there is an overlap: e.g. tomcat and java versions could be hard coded in a specific role version for that app.
The main issue one wants here, is tightly coupling a specific version of the application to a specific version of whatever deploys that application. (Yes, part of that is what docker tries to do, but docker is only a tool here, one still has to manage the application in its total lifecycle.)
A big part of this is IMHO important when thinking of the future of the Ansible inventory - which is one of the reasons I bring this up here.
(
On a side note, I have been thinking the Inventory should be able to be The Single Source of Truth for your infra. At that point, the difference between inventory and facts caching might stop to exist. Small example: I could configure in inventory to deploy version X of app Y. But when looking at the inventory, how would I know which is the currently deployed version? If I have multiple nodes for app Y, I might be upgrading them over a longer amount of time. So the configured version X might apply to some of the nodes, whilst others still have X-1. The last deployed version is a fact that results of a previous deploy, which I’d like to keep track of in my inventory.
)
But I digressed. Back to the OP’s question, a possible solution with current stable Ansible (up to 1.9***), could be this:
-
version all your roles
-
multiple versions of a role means those multiple instances live next to each other on the file system, not multiple versions in some VCS
-
define groups for your
each
applications: appA (and probably will need appA-dev, appA-test, appA-prod), which will hold the nodes for this app
-
define a matching group in inventory for every role-version you have: roleA-versionX
-
define playbooks that match role roleA-versionX to the group roleA-versionX
-
have you
r
appA group become a child of the roleA-versionX, as to match the application to a role version
-
as this evolves, move appA from roleA-versionX to roleA-versionY
Managing the groups roleA-versionX could perhaps be handled by the group_by module, from version variables for appA
Perhaps part of this might become simplier if some post-v2 (***) would allow dynamic role inclusions based on inventory variables
This could all be possible within ini files, in theory, but as I said that would scale badly for a larger environments.
Thoughts?
Serge van Ginderachter
(svg on irc, srvg on github)