Tuesday, August 20, 2013

Puppet+Hiera+Jenkins. Jenkins Integration

Continuation. By now we should have a working bundle of Puppet and Hiera, and in this post we will focus on Jenkins integration, as well as management of the apps configuration.

First, let's recall that roles contain class {'configuration':} declaration. This tiny module allows us to keep a current copy of the apps configuration on the target nodes.
Module's file tree looks as follow:


The manifest file itself (init.pp) is as follows:


It can be summarized as procedure that base on ${environment} name and ${application} name copies configuration files from /biz/puppet/hieradata/${environment}/${application} on Puppet Master to /biz/configuration/${application} on Puppet Agent node.

It is important that destination point has no reference of the ${environment}. This later allows Jenkins to perform configuration update in a complete agnostic way - with only ${application} name being required.

Consider the file tree under files folder. It is grouped by environment and application name. Should you like to add a new application, let's say HelloWorld to the CI env, you would have to:
  1. Make sure that folder /biz/puppet/hieradata/ci exist
  2. Create new subfolder /biz/puppet/hieradata/ci/HelloWorld
  3. Place HelloWorld configuration files into /biz/puppet/hieradata/ci/HelloWorld 
  4. Create/update Jenkins script to take the application configuration files from /biz/configuration/${application}
  5. Create/update a role to reference the HelloWorld:


The flow can be illustrated as:
Fig 1: Deployment process

Last, but not least - let's describe development process on Puppet+Hiera+Jenkins govern cluster:

Fig 2: Development process
Fig 2 illustrates that the framework significantly fast-tracks configuration changes. In summary, we have shown a configuration management framework targeted for small-to-medium sized project, where you are comfortable with file-based configuration for your applications.

Cheers!

Puppet+Hiera+Jenkins. Custom Modules

Continuation. In this second post of the series we will focus on custom modules for the Puppet+Hiera+Jenkins framework. For the sake of brevity we will illustrate our efforts at an example of a single QA environment.

As it is defined in puppet.conf, site.pp file could be found at /biz/puppet/hieradata/${environment}. In terms of QA environment it is /biz/puppet/hieradata/qa:


Here, manifest (aka site.pp) assigns a single role to every node in the cluster. Nodes are identified by the full domain name. Let's assume that:
  • Puppet Master lives at ip-10-0-8-10.sampup.com
  • ip-10-0-8-11.sampup.com and ip-10-0-8-12.sampup.com are Puppet Agents. 
Roles are defined in /biz/puppet/modules/role module:


You might be asking what class {'configuration':} is about? This where actual application configuration is delivered to agent nodes, and we will address this module in the last post of the series.

Corresponding profiles are defined in /biz/puppet/modules/profile module:


Lets discuss Hiera configuration. There is a lot of reading available [1], however we can summarize following:
  1. Hiera data files are named after node's fully qualified domain name
    For instance: ip-10-0-8-12.sampup.com.json
  2. Files contain key-values pairs
    For instance: "ntp::restrict" : true
  3. Each key comprise of the module name and the property name, joined by ::
    For instance, in "ntp::restrict" : true - ntp is the module name
    - restrict is the property name
    - true is the value
  4. Declared key-values are applied during invocation of the parametrized Puppet classes
  5. In case Hiera finds no filename matching the node's domain name, it will first look in common.json
    Puppet will resolve to the default module parameters, should it find no relevant key-values pairs.
/biz/puppet/hieradata/qa/common.json


/biz/puppet/hieradata/qa/ip-10-0-8-12.sampup.com.json


Continue with Jenkins and application configuration.

[1] Hiera reading
http://docs.puppetlabs.com/hiera/1/puppet.html#hiera-lookup-functions

Puppet+Hiera+Jenkins. Concepts

Wouldn't it be great if we could transfer large part of the application configuration from Development to Ops? For instance, typical Java EE application hold tons of external references (such as DB Url, User, Password, Security Certificates, etc). Typical configuration change often requires hours and distracts developers, build engineers and QA. Lots of waste for trivial change.

In this series of three posts we will show a configuration management framework, build of Puppet, Hiera and Jenkins that supports multiple environments:
  • In this post we will review concepts and Puppet's configuration files
  • Second post will be devoted to custom modules and interaction with Hiera
  • Final, third post will focus on Jenkins integration
 Our target environment could be pictured as following:
Fig 1: Deployment schema for two environments

We will build on top of practices [1], and I strongly advice to read that article before proceeding further.

Conceptually, the workflow consist of the following steps:
1. Platform setup: during this step system interfaces and services of the nodes are configured (networking, file-system permissions, users and groups creations, rdbms, http servers, etc)
Fig 2: Puppet workflow


2.  Application setup: during this step business applications are installed and configured on the nodes
Fig 3: Jenkins workflow

Our skeleton's file structure will look as follow:


Three folders form a top-level hierarchy:
  • /etc/puppet soon after puppet package is installed this folder contains standard puppet modules
    In addition, we will place there two configuration files:
    - puppet.conf describing puppet search paths and config
    - hiera.yaml describing Hiera search paths and config
  • /biz/puppet/modules contains all of the custom modules
  • /biz/puppet/hieradata holds Hiera data files grouped by environment
Lets review puppet configuration files from /etc/puppet

puppet.conf

This file should be normally divided into two: one with [main] and [master] sections deployed at Puppet Master node and another with [main] and [agent] sections deployed to Puppet Agent nodes.
puppet.conf provides wide spectrum of settings [3], but here we define only most critical ones, such as:
  • modulepath defines path to the custom modules
  • manifest defines where site.pp files are located
    Note that in our case site.pp files are environment-specific. For instance site.pp for QA environment is stored in /biz/puppet/hieradata/qa/ folder
  • server identifies the Puppet Master domain name
  • environment defines environment of the Agent node. For instance: qa, ci, etc
    Details on the environment setting could be found at [2]

hiera.yaml
Above, we declared that configuration files for particular nodes in the cluster will be in JSON format, grouped by environment and identified by the full domain name.
Note that the attribute -common under :hierarchy: denotes common settings for the environment and in our case refers to the /biz/puppet/hieradata/${environment}/common.json file.

Continue with custom modules.

[1] Craig Dunn: Designing Puppet – Roles and Profiles
http://www.craigdunn.org/2012/05/239/

[2] Defining environment in Puppet/Hiera
http://docs.puppetlabs.com/guides/environment.html

[3] Puppet.conf in details
http://docs.puppetlabs.com/references/latest/configuration.html