Change Management
Version 2 (Anonymous, 03/13/2010 08:01 pm)
| 1 | 1 | # Change Management |
|
|---|---|---|---|
| 2 | 1 | ||
| 3 | 1 | Many environments require some kind of change management workflow |
|
| 4 | 1 | -- changes must pass through multiple phases (e.g., development, |
|
| 5 | 1 | testing, production) and often require approval to move between |
|
| 6 | 1 | phases. How might such a system be built into Puppet, or built |
|
| 7 | 1 | externally and integrated with Puppet? |
|
| 8 | 1 | ||
| 9 | 1 | This problem is usually known as "Change Management", and it must |
|
| 10 | 1 | be solved for multiple problem spaces, including software |
|
| 11 | 1 | development. We should be able to take examples from those other |
|
| 12 | 1 | problem spaces, but I have not done sufficient research on those |
|
| 13 | 1 | other spaces at this point (other than trawling the 'net but not |
|
| 14 | 1 | finding much in the way of examples). |
|
| 15 | 1 | ||
| 16 | 1 | # Potential Solutions |
|
| 17 | 1 | ||
| 18 | 1 | Rather than going through a complicated analysis of all of the |
|
| 19 | 1 | options and what effect the different choices have, I'm just going |
|
| 20 | 1 | to lay out what I consider to be the basic options, to provide a |
|
| 21 | 1 | framework for discussion. From there, we can hopefully reduce the |
|
| 22 | 1 | scope of discussion to the more obviously appropriate solutions. |
|
| 23 | 1 | ||
| 24 | 1 | ## Parse Trees in a Database |
|
| 25 | 1 | ||
| 26 | 1 | Because Puppet's language is declarative, it's relatively |
|
| 27 | 1 | straightforward to model it with a database. It wouldn't |
|
| 28 | 1 | necessarily be easy, but it would at least be straightforward. With |
|
| 29 | 1 | everything in a database, you could provide an interface for |
|
| 30 | 1 | selecting values based on whatever criteria you want, and those |
|
| 31 | 1 | decisions could be implemented via conditional structures in the |
|
| 32 | 1 | database. The approval process could also be relatively |
|
| 33 | 1 | straightforward, because they become approvals of an SQL |
|
| 34 | 1 | statement. |
|
| 35 | 1 | ||
| 36 | 1 | The downside of this solution, of course, is that it's a heckuva |
|
| 37 | 1 | lot of work. First is creating the database modelling and the |
|
| 38 | 1 | necessary interfaces into it, but you are also suddenly limited in |
|
| 39 | 1 | code-sharing because you have to translate back and forth between |
|
| 40 | 1 | SQL and Puppet code, and the scope of your solution is almost |
|
| 41 | 1 | entirely open-ended -- where does your change management |
|
| 42 | 1 | application end and Puppet begin? |
|
| 43 | 1 | ||
| 44 | 1 | Because of the open-ended nature of this solution, and the large |
|
| 45 | 1 | amount of work involved, I do not think this is a good idea. |
|
| 46 | 1 | ||
| 47 | 1 | ## Functional Approval Lookup |
|
| 48 | 1 | ||
| 49 | 1 | The simplest solution is just to connect Puppet to an external |
|
| 50 | 1 | approval mechanism via a Puppet function and simple keyword lookup. |
|
| 51 | 1 | The approval system would have registered values that could be |
|
| 52 | 1 | modified as necessary, and then the appropriate values could be |
|
| 53 | 1 | looked up in the Puppet language: |
|
| 54 | 1 | ||
| 55 | 1 | package { apache: |
|
| 56 | 1 | ensure => approved("apache-version") |
|
| 57 | 1 | } |
|
| 58 | 1 | ||
| 59 | 1 | The biggest problem with this solution is that systems in different |
|
| 60 | 1 | service levels vary by much more than just simple values -- |
|
| 61 | 1 | sometimes a different package version has different dependencies or |
|
| 62 | 1 | renames a file, and re-factoring an implementation often looks |
|
| 63 | 1 | different enough from the original that the difference cannot be |
|
| 64 | 1 | modelled with simple values. |
|
| 65 | 1 | ||
| 66 | 1 | The function could be enhanced to support returning code segments |
|
| 67 | 1 | to apply, but then you're back to modelling Puppet elements in the |
|
| 68 | 1 | database. |
|
| 69 | 1 | ||
| 70 | 1 | ## Version Control Solutions |
|
| 71 | 1 | ||
| 72 | 1 | Probably the easiest way to handle differences between machines |
|
| 73 | 1 | with slightly different configurations is to create a branch in |
|
| 74 | 1 | your version control system for each service level, and then create |
|
| 75 | 1 | a mechanism for approving individual changes and merges between |
|
| 76 | 1 | branches. This allows you to reuse the version control model for |
|
| 77 | 1 | everything except the approval process. This approval process |
|
| 78 | 1 | should not be too complicated, although it will almost certainly be |
|
| 79 | 1 | tied to a specific version control system. You could use |
|
| 80 | 1 | post-commit hooks for registering changes and merges and then have |
|
| 81 | 1 | the approval system migrate approved changes and merges into a |
|
| 82 | 1 | separate branch. |
|
| 83 | 1 | ||
| 84 | 1 | The big upside to this approach is that it's the most minimalist |
|
| 85 | 1 | approach and thus the easiest, and it should support creating a |
|
| 86 | 1 | decoupled approval system that could be used with any text-based |
|
| 87 | 1 | system, and it should be relatively easy to hook into different |
|
| 88 | 1 | version control systems. The downside is that it's entirely |
|
| 89 | 1 | unsemantic -- approvers will get plain diffs, rather than semantic |
|
| 90 | 1 | modifications (e.g., they'll get two lines mentioning the package |
|
| 91 | 1 | version, rather than a single statement along the lines of |
|
| 92 | 1 | "changing version from X to Y"). |
|
| 93 | 1 | ||
| 94 | 1 | ## Filtering |
|
| 95 | 1 | ||
| 96 | 1 | This isn't really a complete solution, but it's an idea, anyway. |
|
| 97 | 1 | There are multiple points at which a configuration could be |
|
| 98 | 1 | filtered through an approval process. |
|
| 99 | 1 | ||
| 100 | 1 | The parse tree could be passed through an approval filter that |
|
| 101 | 1 | modified it in some way, probably something like creating |
|
| 102 | 1 | conditional structures where there previously were none. |
|
| 103 | 1 | Alternatively, each individual host's compiled configuration could |
|
| 104 | 1 | be passed through a filter which could fill in values based on the |
|
| 105 | 1 | results of approvals. This option probably limits what can be done |
|
| 106 | 1 | via the approval mechanism, because again it mostly affects values, |
|
| 107 | 1 | not the elements themselves. |
|
| 108 | 1 | ||
| 109 | 1 | You could also potentially directly modify the database cache of |
|
| 110 | 1 | host configurations via the approval mechanism, but I think that |
|
| 111 | 1 | would again limit your flexibility while requiring too much |
|
| 112 | 1 | knowledge of Puppet's internals. |
|
| 113 | 1 | ||
| 114 | 1 | # Conclusion |
|
| 115 | 1 | ||
| 116 | 1 | This document is meant more as an entry point to discussion, rather |
|
| 117 | 1 | than a real solution, so it should not be seen as a complete |
|
| 118 | 1 | listing of options nor should it be expected to be complete. |
|
| 119 | 1 | Hopefully it's sufficient to continue discussion, anyway. |