r10k was written because librarian was too slow for large
deployments. But it covers more than just managing code: it also
manages environments and is designed to run on the Puppet master. It
doesn't have dependency resolution or a `Puppetfile.lock`,
however. See [this ticket](https://github.com/puppetlabs/r10k/issues/38), closed in favor of [that one](https://tickets.puppetlabs.com/browse/RK-3).
r10k is more complex and very opiniated: it requires lots of
configuration including its own YAML file, hooks into the Puppetmaster
and can [take a while to deploy](http://garylarizza.com/blog/2014/02/18/puppet-workflow-part-3/). r10k is still in [active
development](https://github.com/puppetlabs/r10k/releases) and is supported by Puppetlabs, so there's [official
documentation](https://puppet.com/docs/pe/2019.1/r10k.html) in the Puppet documentation.
Often used in conjunction with librarian for dependency resolution.
One cool feature is that r10k allows you to create dynamic
environments based on branch names. All you need is a single repo with
a Puppetfile and r10k handles the rest. The problem, of course, is
that you need to trust it's going to do the right thing. There's the
security issue, but there's also the problem of resolving dependencies
and you *do* end up double-committing in the end if you use branches
in sub-repositories. But maybe that is unavoidable.
(Note that there are ways of resolving dependencies with external
tools, like [generate-puppetfile](https://github.com/rnelson0/puppet-generate-puppetfile)([introduction](https://rnelson0.com/2015/11/06/introducing-generate-puppetfile-or-creating-a-ruby-program-to-update-your-puppetfile-and-fixtures-yml/)) or [this hack
that reformats librarian output](https://github.com/dharmabruce/lp2r10k/blob/master/lp2r10k) or [those rake tasks](https://github.com/voxpupuli/ra10ke). there's
also a [go rewrite called g10k](https://github.com/xorpaul/g10k) that is much faster, but with
similar limitations.)
## git subtree
[This article](https://web.archive.org/web/20171107082413/http://somethingsinistral.net/blog/scaling-puppet-environment-deployment/) mentions git subtrees from the point of view of
Puppet management quickly. It outline how it's cool that the history
of the subtree gets merged as is in the parent repo, which gives us
the best of both world (individual, per-module history view along with
a global view in the parent repo). It makes, however, rebasing in
subtrees impossible, as it breaks the parent merge. You do end up with
some of the disadvantages of the monorepo in the all the code is
actually committed in the parent repo and you *do* have to commit
twice as well.
## subrepo
TODO. https://github.com/ingydotnet/git-subrepo
## myrepos
[myrepos](https://myrepos.branchable.com/) is one of many solutions to manage multiple git
repositories. It has been used in the past at my old workplace
(Koumbit.org) to manage and checkout multiple git repositories.
Like Puppetfile without locks, it doesn't enforce cryptographic
integrity between the master repositories and the subrepositories: all
it does is define remotes and their locations.
Like r10k it doesn't handle dependencies and will require extra setup,
although it's much lighter than r10k.
Its main disadvantage is that it isn't well known and might seem
esoteric to people. It also has weird failure modes, but could be used
in parallel with a monorepo. For example, it might allow us to setup
specific remotes in subdirectories of the monorepo automatically.