Tuesday, August 20, 2013

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:

node ip-10-0-8-11 {
include role::web_portal
}
node ip-10-0-8-12 {
include role::enterprise_server
}
view raw site.pp hosted with ❤ by GitHub

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:

# file /biz/puppet/modules/role/manifests/init.pp
class role {
include profile::base
}
# file /biz/puppet/modules/role/manifests/web_portal.pp
class role::web_portal inherits role {
include profile::web_server
class { 'configuration' :
env => "${environment}",
application => 'web_app_1',
}
}
# file /biz/puppet/modules/role/manifests/enterprise_server.pp
class role::enterprise_server inherits role {
# out of the blog post scope - install tomcat+java
# include profile::tomcat_server
class { 'configuration' :
env => "${environment}",
application => 'enterprise_app_1',
}
}
view raw roles hosted with ❤ by GitHub

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:

# file /biz/puppet/modules/profile/manifests/init.pp
class profile {
}
# file /biz/puppet/modules/profile/manifests/web_server.pp
class profile::web_server {
class { "apache": }
}
# file /biz/puppet/modules/profile/manifests/base.pp
class profile::base {
include networking
include timezone::utc
include users
}
view raw profiles hosted with ❤ by GitHub

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

{
"ntp::restrict" : true,
"ntp::autoupdate" : true,
"ntp::enable" : true,
"ntp::servers" : [
"0.centos.pool.ntp.org iburst",
"1.centos.pool.ntp.org iburst",
"2.centos.pool.ntp.org iburst"
]
}
view raw common.json hosted with ❤ by GitHub

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

{
"apache::vhost::priority": "10",
"apache::vhost::vhost_name": "web_server.sampup.com",
"apache::vhost::port": "80",
"apache::vhost::docroot": "/var/www",
}

Continue with Jenkins and application configuration.

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

No comments: