A classic organization has a minimum of two environments in which the infrastructure is run: development and production. Very often, a lot of environments are seen, such as staging, testing, alpha or beta. It's entirely up to the organization to model the infrastructure according to its needs, and the complexity can grow very quickly. The good news is that Chef helps a lot in mapping this model to the infrastructure. There's a set of information that will be different in two distinct environments, such as cookbook versions or attributes, and Chef makes it as easy as possible to manage these environments. By default, nodes without an environment set will run in a _default
environment.
In this section, we'll see how to create different environments, how to set nodes (both existing and new) in a dedicated environment, how to set cookbook constraints, and finally how to override the attributes in each environment.
To step through this recipe, you will need:
Chef environments live in a folder named environments
at the root of chef-repo
. If the folder doesn't exist, create it:
$ mkdir environments
To create a production environment, follow these steps:
production
environment in a production.rb
file:name 'production' description 'The production environment'
$ knife environment from file environments/production.rb Updated Environment production
$ knife environment list _default production
We see we have two environments available: production
and _default
.
To set an already existing node to this new production
environment, execute the following command:
$ knife node environment set my_node_name production my_node_name: chef_environment: production
If we're bootstrapping a node with the knife bootstrap
command, we can start in the required environment right from the beginning (using an user named vagrant
like the previous examples):
$ knife bootstrap a.b.c.d -N vagrant -x vagrant --sudo --environment production --run-list 'recipe[mysite]'
Let's say our production systems are running a perfectly stable mysite
cookbook in version 0.3.1, but we want to try a new feature in the development infrastructure in the 0.4.0 version of the same cookbook. As every cookbook version can live together, each environment can call its own version. The production.rb
file would contain the following for the production
environment:
cookbook_versions 'mysite' => '= 0.3.1'
The development.rb
file would contain the following for the development environment:
cookbook_versions 'mysite' => '= 0.4.0'
A Chef environment file may contain many cookbook constraints, as follows:
cookbook_versions: { 'mysite': '= 0.4.0', 'apache': '= 0.6.0' }
Each environment can override any value, and, in Chef, it's the highest level of override. Nothing else can override a value set for an environment. So, if we simply want to override the value of the sitename
attribute to production.rb
, it will look like this:
override_attributes 'sitename' => 'mysite_production'
With Puppet, environments are located in distinct directories on the Puppet server. You probably noticed this in Chapter 6, Fundamentals of Managing Servers with Chef and Puppet; we created the code in the /etc/puppetlabs/code/environments/production
directory.
This is because the default Puppet environment is production
. Other environments, for example test
, should be created under /etc/puppetlabs/code/environments/
.
Let's start with samples from Chapter 6, Fundamentals of Managing Servers with Chef and Puppet, and try creating a new environment, namely test
. On the Puppet server, we just need to do this:
$ sudo -s # cd /etc/puppetlabs/code/environments/ # cp -a production test
On the node side, the environment to use can be controlled using --environment
:
# puppet agent --test --environment test
To use this environment as the default one, without using --environment
, we can configure it in /etc/puppetlabs/puppet/puppet.conf
with the following:
[agent] environment = test
As for Chef, we can get the name of the running environment from any manifest. This is done by using the $environment
variable, which is set by the Puppet server.
To illustrate this, let's modify our index.php
file (manifests/site.pp
), both in production
and test
:
file {"${docroot}/index.php": ensure => present, owner => 'www-data', group => 'www-data', mode => '0644', content => "<?php echo "Running from ${environment}" ?>" }
We can now switch between test
and production
and see the changes:
# puppet agent --test Info: Using configured environment 'production' … @@ -1 +1 @@ -<?php echo "Running from test" ?> +<?php echo "Running from production" ?> … # puppet agent --test --environment test Info: Using configured environment 'test' @@ -1 +1 @@ -<?php echo "Running from production" ?> +<?php echo "Running from test" ?>
We edited the environments and code directly in the Puppet master, which is not recommended. Fortunately, r10k (which we already used in Chapter 6, Fundamentals of Managing Servers with Chef and Puppet, to install modules) can be used to create environments from a Git repository. Each branch from the Git repository will be checked out into a distinct directory and will be available as an environment. This feature is dynamic: each new branch added to the Git repository will be deployed by r10k.
Let's try it from our workstation. Until now, the job of the shared folder of our Vagrant setup was to map the relative directory puppetcode
to /etc/puppetlabs/code/environments/production
in the puppet.pomes.pro
box. We are about to use multiple environments, so we need to change the mapping to /etc/puppetlabs/code/
.
We need a Git repository with two branches, production
and test
, with all of the previous code. An example is available at https://github.com/ppomes/r10k_sample.git.
The r10k tool needs a global configuration file, which must be created at the same level as our Vagrantfile, with the following content:
:sources: :my-repos: remote: 'https://github.com/ppomes/r10k_sample.git' basedir: 'puppetcode/environments'
Now let's use r10k:
$ r10k -c ./r10k.yaml deploy environment -p $ ls -l puppetcode/environments/ total 0 drwxr-xr-x 8 ppomes staff 272B 26 Nov 16:40 production/ drwxr-xr-x 8 ppomes staff 272B 26 Nov 16:40 test/
Both branches from the Git repository have been deployed, and we can now fire up Vagrant and play with our boxes and branches.
The r10k tool also takes care of the Puppetfile
file in each branch, as we already saw in Chapter 6, Fundamentals of Managing Servers with Chef and Puppet, and deploys external modules, if any.
3.133.138.177