Multitenant control repository

Larger organizations may need a multitenant setup of Puppet Enterprise Code Manager. While fundamentally, the workflow is the same, the way that we structure the control repository is slightly different.

We attempt to minimize the impact of the control repository, turning it into a call to libraries of sorts. We want to position our control repository to store references to code, rather than code itself. Moving role and profile manifests to external repositories allows us to manage them as a versioned artifacts, and declare which version is available to each and every enviroinment directly. Our control repository only contains the Puppetfile, things applied globally with site.pp, and values that we'd like to make available to the whole organization, to use in Hiera.

We make a few minor changes to the workflow to facilitate larger groups, as follows:

  • Roles and profiles are exported to standalone modules, tagged with versions, and imported by the Puppetfile.
  • Only values that serve for use across multiple modules, such as LDAP settings, are maintained in the environment-level Hiera. All direct calls to a class, such as profile::ntp::servers, are stored in data, in modules in the appropriate repo (in this case, the profile repository).

Roles and profiles are migrated to be standalone modules, and each team receives their own module, as well. These modules then incorporate their own robust Hiera layer in the module, and can be used to provide roles and profiles to each team. If we had a team developing an application called myapp, they would create a module called myapp and include a role and profile folder. Our namespacing changes a little bit, but allows us to look at modules as a collection of roles and profiles per team. The original role and profile repositories become a house for code commonly used by the whole organization, such as security baselines or web server defaults.

The following code can then be produced by the myapp team, which provides the strengths of Hiera, roles, and profiles to each of these repositories:

class myapp::role::app_server {
# Global Baseline used by entire organization
include profile::baseline
# Profile generated specifically by myapp team
include myapp::profile::application
}

class myapp::profile::application {
# Profile has some custom code from the Myapp Team
include myapp::application
# Profile also uses the standard Webserver profile of the organization
include profile::webserver
}

This methodology, combined with other practices in this chapter, such as protected branches, allows teams to work at different paces on different projects, while not holding other teams in the organization back. It limits the control repository to describing an environment, and opens up roles and profiles to receive code contributions from anywhere in the organization, with RBAC and governance in place to ensure that proper code reviews are performed before accepting code for the entire organization.

Our significantly smaller control repository now looks as follows:

$ tree control-repo
control-repo
├── hiera.yaml
├── environment.conf
├── Puppetfile
├── data
│ ├── common.yaml
│ . └── datacenter
│ ├── us.yaml
│ ├── uk.yaml
│ └── can.yaml
└── manifests
└── site.pp

And our team module acts like a small control repo for us, with a hiera hierarchy, roles and profiles:

$ tree team
team
├── README.md
├── hiera.yaml
├── data
│ ├── common.yaml
│ └── os
│ ├── RedHat.yaml
│ ├── Ubuntu.yaml
│ └── Windows.yaml
│ └── datacenter
│ ├── us.yaml
│ ├── uk.yaml
│ └── can.yaml
├── files
├── manifests
│ ├── profile
│ │ └── myapp.pp #team::profile::myapp
│ └── role
│ └── myapp.pp #team::role::myapp which includes team::profile::myapp
├── metadata.json
└── templates
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.134.78.106