Ask Your Question

What is your workflow to merge puppet control repo (environment) branches?

asked 2015-06-01 22:39:01 -0600

kaizenCoder gravatar image

We use control-repos (Puppetfile, hieradata, roles & profiles) and r10k to manage environment branches.

Our modules are stored independently of the control-repo and is included via the r10k Puppetfile.

When a new module developed and is pushed to its respective repo, the following occurs:

  1. Create a feature branch off control-repo environment branch i.e: model
  2. Update hieradata key/values
  3. Update profiles
  4. Update roles
  5. Update Puppetfile to require the module
  6. Test feature branch
  7. On success, merge to environment branch i.e: model

At this point, I'm interested to know how I can ensure the remaining environment branches are updated?

I seem to have hit a few issues in figuring out the best way to do this, so I'm keen to know how others approach introducing changes in to their environments?


edit retag flag offensive close merge delete

2 Answers

Sort by » oldest newest most voted

answered 2018-05-29 09:43:00 -0600

CarlP gravatar image

Apologies for the long post. Hopefully it's helpful.

I find using long lived branches works well. Let me explain how we do it....

I create a repo in Bitbucket with development, testing, pre-prod and production branches to hold the hiera code. I create repos to hold each module with only a master branch for each.

The puppet.conf on each development node is configured with "environment = development" to cause them to pull the development code by default. However, the Development environment group configured on the Puppet master is configured as a "agent-specified" to allow their environment to be temporarily switched from Development at will. The remaining environment - testing, pre-prod and production - are configure in the Puppet master with a corresponding, fixed environment group.

The development of code releases, feature changes, etc. begins in the development branch. The Puppetfile contains the details of the each module, its repository and commit reference to include in the environment when r10k pulls the code from the BitBucket server.

A ticket is created within JIRA for the work and an associated temporary branch is created on the Development hiera code repo within BitBucket. Any modification to modules are made by creating a temporary branch on the module's master branches under the same JIRA ticket (so the work is all held together within the same ticket reference). If a module's code has been updated and pushed back to its repo, the associated commit reference within the Puppetfile of the temporary hiera code branch is updated to ensure the new module code is retrieved when r10k pulls the code. The modified hiera code and any module changes are tested against the development nodes using the "puppet agent --environment=<hiera code="" branch="" name=""> -tv" command with --noop as an option.

If all tests are OK, any module changes are merged into the module's master branch. The resulting commit reference is used to replace the module's previous "temporary" commit reference within the Puppetfile of the temporary hiera code branch. The hiera code branch is then merged into the Development branch and testing is carried out. If the tests are successful, the whole Development branch is merged into the Testing branch. Again, testing is performed and, if successful, the testing branch is merged in to Pre-prod. The process repeats once more and Pre-prod is eventually merged to Production.

So. How do we handle the variations in hiera code between the environments, node types, software stack (software grouped together and deployed as a unit), and individual nodes? We use the roles and profiles technique promoted by Gary Larizza, et al.

Each environment configured in the Puppet master given a number of variables. For example, the Development environment is given the variable "environment = development". Nodes of the same type are added to a class and the class given the variable "nodetype = <e.g webserver="">". Nodes with the same software stack are are added to a class and given the variable "softwarestack = <e.g. was="">.

The global hiera ... (more)

edit flag offensive delete link more


Awesome description! There's one thing I'm not sure tough. Do you keep your hiera data and your modules in the same repository, or do you keep the separate?

Alexis Lessard gravatar imageAlexis Lessard ( 2018-10-18 10:34:41 -0600 )edit

answered 2018-02-16 18:17:31 -0600

bentlema gravatar image

updated 2018-02-16 18:22:10 -0600

Hi kaizenCoder,

You've stumbled upon why having unique long-lived branches/environments (other than production) doesn't work well. Peterino's comment from your StackOverflow question is exactly right (In my opinion).

According to my research the r10k developers want us to use simple feature branching (aka GitHub Flow), using production as your main branch. Hence, rename master to production to start with, then always branch off feature branches from production, test them, and merge or rebase the changes into production again. -- Avoid several long-living branches, stick to a single production branch and use short-lived feature branches. – Peterino Aug 4 '17 at 10:20

Rather than keeping different (unique-to-an-environment) versions of Hiera data, or different versions of the Puppetfile, or different versions of your Roles/Profiles, try writing them so that they work across all "App Tiers" or "Server Tiers" (dev, integration, qa, test, staging, production). You can structure your Hiera Hierarchy (in your hiera.yaml) such that you can still provide different data for differing Tiers. In your puppet code, you can use conditionals or case statements when necessary, but if you design your Hiera Hierarchy correctly, you may not even need to, you'll be able to accomplish the same thing you're now, and wont have to duplicate your changes across multiple environments, and cherry pick commits all over the place.

Doing the above can get you around most of the problems, but if you really need to run different versions of modules for an extended period of time in another environment/branch, your Puppetfile will be different (as you've noticed) and you'll still need to deal with that from time to time. One way I've delt with it in the past was to do my merge (say from feature to model) using the --no-commit option, and then manually removing the Puppetfile from the merge before I commit.

I hope that helps!

edit flag offensive delete link more


I would echo the above, structure your heira data so it contains a level/file for your ‘environment’, that way you have a single trunk that contains prod, qa, test, and dev values, with an ‘environment’ fact that is used to choose the right data. That alows a single path/flow without maintaining ..

DarylW gravatar imageDarylW ( 2018-02-17 21:25:54 -0600 )edit

... long lived independent branches with independent merged required into each long lived branch. Unless there is some security reason that the dev environment can’t know the prod passwords or something, that is your best bet.

DarylW gravatar imageDarylW ( 2018-02-17 21:27:36 -0600 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools



Asked: 2015-06-01 22:39:01 -0600

Seen: 1,159 times

Last updated: May 29