2016/06/29

Let us play with some puppet Modules - Part II: Puppetizing DNS/bind Installation and Configuration with camptocamp/bind

In the series of "Let us play with some puppet Modules" posts, I'm willing to share my experience related to the usage of some Forge Puppet Modules. To make it more understandable, I'm trying to make use of a set of well-known Puppet's best practice, with a great emphasis on the following (Check the reference section for Websites where you can learn more about Puppet's best practice):
  • Roles and Profiles Pattern
  • Hiera for Configuration Data
The posts in this series are all following the below structure:

  1. Module Installation and others prerequisites
  2. Profile Module creation
  3. Hiera Configuration
  4. Roles Configuration
  5. Puppet Agent Single run

This post is the second within that "Let us play with some puppet Modules" series and it aims to describe bind (named) Installation and configuration using  camptocamp/bind Module. 
It's true that there's more than one Module on Forge that can help achieve DNS Server Installation and Configuration and the reasons behind choosing one instead of another depends on many factors. In this case, my requirement was to use the same Module for named Installation, zone configuration and addition/modification of DNS Records.  

   I. Module Installation and others prerequisites:

The installation of the module from Puppet Forge,

[root@pe-master ~] # puppet module install camptocamp-bind

   II. Profile Module Creation:

Let us create a specific Profile for DNS Servers , note that I'm using a parameterized class for that profile, with some default values for each parameters. These default values are set as an example and without any other modifications, Applying this Profile Class will install bind (non-chroot), create an example.com zone and insert NameServer (NS) record, some A records and an MX record (last dns_records in the parameters is for any other records type -like TXT, SRV...-)


class profiles::dnsservers (
  $named_chroot         = false,
  $named_default_view   = {},
  $named_config         = {
                           'allow-query'            => ['localhost'],
                           'auth-nxdomain'          => 'no',
                           'bindkeys-file'          => '"/etc/named.iscdlv.key"',
                           'directory'              => '"/var/named"',
                           'dnssec-enable'          => 'no',
                           'dnssec-validation'      => 'no',
                           'dump-file'              => '"/var/named/data/cache_dump.db"',
                           'managed-keys-directory' => '"/var/named/dynamic"',
                           'memstatistics-file'     => '"/var/named/data/named_mem_stats.txt"',
                           'pid-file'               => '"/run/named/named.pid"',
                           'listen-on'              => ['127.0.0.1'],
                           'listen-on-v6'           => ['::1'],
                           'session-keyfile'        => '"/run/named/session.key"',
                           'statistics-file'        => '"/var/named/data/named_stats.txt"',
                          },
  $logging              = {},
  $dns_zones            = [ { 
                           zonename                 => 'example.com',
                           ensure                   => 'present',
                           zone_contact             => 'SystemAdministration@mtncameroon.net',
                           zone_ns                  => ['ns0.example.com'],
                           zone_serial              => '2016061401',
                           zone_ttl                 => '604800',
                           zone_origin              => 'example.com',
                           is_dynamic               => false,
                           allow_update             => [],
                           view                     => 'default',
                           zone_type                => 'master',
                           zone_refresh             => '3h',
                           zone_retry               => '1h',
                           zone_expiracy            => '1w',
                           zone_xfers               => undef,
                           zone_forwarders          => undef,
                           zone_notify              => undef,
                           zone_masters             => undef,
                           transfer_source          => undef,
                           hash_a_entries           => { 
                                            'ns0'   => { owner => '192.168.0.2', }, 
                                            'ns1'   => { owner => '192.168.0.3', }, 
                                            },
                          } ],
  $dns_mxs              = [ {
                           mxnamevar                => 'mx1',
                           zone                     => 'example.com',
                           owner                    => '@',
                           priority                 => '1',
                           host                     => 'mail.example.com',
                          } ],
  $dns_acls             = [ {
                           aclnamevar               => 'test acl',
                           ensure                   => 'present',
                           acls                     => ['192.168.0.2'],
                          } ],
  $dns_records          = [], 
)
{

  # Add the bind packages and services
  class { bind:
    chroot         => $named_chroot,
    default_view   => $named_default_view,
    config         => $named_config,
    logging        => $logging,
  }
  
  # Configure zones
  $dns_zones.each |$dns_zone| {
    bind::zone { $dns_zone[zonename]:
      ensure           => $dns_zone[ensure],
      zone_contact     => $dns_zone[zone_contact],
      zone_ns          => $dns_zone[zone_ns],
      zone_serial      => $dns_zone[zone_serial],
      zone_ttl         => $dns_zone[zone_ttl],
      zone_origin      => $dns_zone[zone_origin],
      is_dynamic       => $dns_zone[is_dynamic],
      allow_update     => $dns_zone[allow_update],
      view             => $dns_zone[view],
      zone_type        => $dns_zone[zone_type],
      zone_refresh     => $dns_zone[zone_refresh],
      zone_retry       => $dns_zone[zone_retry],
      zone_expiracy    => $dns_zone[zone_expiracy],
      zone_xfers       => $dns_zone[zone_xfers],
      zone_forwarders  => $dns_zone[zone_forwarders],
      zone_notify      => $dns_zone[zone_notify],
      zone_masters     => $dns_zone[zone_masters],
      transfer_source  => $dns_zone[transfer_source],
    }
    # Configure Inital A entries in zone
    bind::a { "Hosts in ${dns_zone[zonename]}":
      ensure    => 'present',
      zone      => "${dns_zone[zone_origin]}",
      ptr       => false,
      hash_data => $dns_zone[hash_a_entries],
    }
  }
  # Configure MX entries in zone
  $dns_mxs.each |$dns_mx| {
    bind::mx { $dns_mx[mxnamevar]:
      zone     => $dns_mx[zone],
      owner    => $dns_mx[owner],
      priority => $dns_mx[priority],
      host     => $dns_mx[host],
    }
  }

  $dns_acls.each |$dns_acl| {
    bind::acl {$dns_acl[aclnamevar]:
      ensure      => $dns_acl[ensure],
      acls        => $dns_acl[acls],
    }
  }

  $dns_records.each |$dns_record| {
    bind::record {$dns_record[namevar]:
      zone        => $dns_record[zone],
      record_type => $dns_record[record_type],
      hash_data   => $dns_record[hash_data],
    }
  }

  
}


   III. Hiera Configuration:

As said during the brief introduction above, I'm exclusively using Hiera to store Nodes' configuration data. Below, a sample of Hiera Configuration to create stivesso.local zones with few NS entries, some A entries, but also MX and CNAMEs entries. Note that you can add much more parameters
Because creating such a yaml file for an existing DNS with thousands entries might seem a bit daunting as task, I've written a script available on github that generates a YAML output ready to use for Hiera Configuration based on an existing zone file.


---
profiles::dnsservers::named_chroot:      false
profiles::dnsservers::named_config:
  'allow-query'            :
    - 'any'
  'auth-nxdomain'          : 'no'
  'bindkeys-file'          : '"/etc/named.iscdlv.key"'
  'directory'              : '"/var/named"'
  'dnssec-enable'          : 'yes'
  'dnssec-validation'      : 'yes'
  'dump-file'              : '"/var/named/data/cache_dump.db"'
  'managed-keys-directory' : '"/var/named/dynamic"'
  'memstatistics-file'     : '"/var/named/data/named_mem_stats.txt"'
  'pid-file'               : '"/run/named/named.pid"'
  'listen-on'              : 
    - 'any'
  'listen-on-v6'           : 
    - 'any'
  'session-keyfile'        : '"/run/named/session.key"'
  'statistics-file'        : '"/var/named/data/named_stats.txt"'
profiles::dnsservers::dns_zones:
  -
    zonename                 : 'stivesso.local'
    ensure                   : 'present'
    zone_contact             : 'stivesso@gmail.com'
    zone_ns                  : 
      - 'ns0.stivesso.local'
    zone_serial              : '2016061401'
    zone_ttl                 : '604800'
    zone_origin              : 'stivesso.local'
    hash_a_entries           :
      'ns0'                  :
        owner                :
          '192.168.0.2'
      'ns1'                  :
        owner                :
          '192.168.0.3'
      'sip'                  :
        owner                :
          '192.168.0.10'
profiles::dnsservers::dns_mxs:
  -
    mxnamevar                : 'Mail Server 1 for stivesso.local'
    zone                     : 'stivesso.local'
    owner                    : '@'
    priority                 : '1'
    host                     : 'mail.stivesso.local'
  -
    mxnamevar                : 'Mail Server 2 for stivesso.local'
    zone                     : 'stivesso.local'
    owner                    : '@'
    priority                 : '2'
    host                     : 'mail2.stivesso.local'
profiles::dnsservers::dns_records:
  -
    namevar                  : 'CNAMES for stivesso.local'
    zone                     : 'stivesso.local'
    record_type              : 'CNAME'
    hash_data                :
      'ns3'                  :
        owner                :
          'ns1.stivesso.local'
      'ns4'                  :
        owner                :
          'ns2.stivesso.local'
  -
    namevar                  : 'SRV for stivesso.local'
    zone                     : 'stivesso.local'
    record_type              : 'SRV'
    hash_data                :
      '_sip._tls'            :
        owner                :
          '1 100 443 sip.stivesso.local'


   IV. Roles Configuration:

Using the dnsservers profile described in Section II, with the right Hiera Data, we can move forward with the roles modules configuration,

class roles::dns  {
 
    # Install Oracle Server
    include profiles::dnsservers

}


   IV. Puppet Agent Single run:

And finally, let us trigger a puppet convergence and enjoy the output...


[root@dns-server01 ~]# puppet agent -t
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Loading facts
Info: Caching catalog for dns-server01.mtncameroon.net
Info: Applying configuration version '1467114345'
Notice: /Stage[main]/Profiles::Dnsservers/Bind::Zone[stivesso.local]/Concat::Fragment[default.zone.stivesso.local]/File[/opt/puppetlabs/puppet/cache/concat/_etc_named_views_default.zones/fragments/10_default.zone.stivesso.local]/ensure: defined content as '{md5}2bbf22e9890bad139489e2f951766b52'
Info: /Stage[main]/Profiles::Dnsservers/Bind::Zone[stivesso.local]/Concat::Fragment[default.zone.stivesso.local]/File[/opt/puppetlabs/puppet/cache/concat/_etc_named_views_default.zones/fragments/10_default.zone.stivesso.local]: Scheduling refresh of Exec[concat_/etc/named/views/default.zones]
Info: Concat::Fragment[default.zone.stivesso.local]: Scheduling refresh of Exec[reload bind9]
Notice: /Stage[main]/Bind::Config/Bind::View[default]/Concat[/etc/named/views/default.zones]/Exec[concat_/etc/named/views/default.zones]/returns: executed successfully
Notice: /Stage[main]/Bind::Config/Bind::View[default]/Concat[/etc/named/views/default.zones]/Exec[concat_/etc/named/views/default.zones]: Triggered 'refresh' from 1 events
Notice: /Stage[main]/Bind::Config/Bind::View[default]/Concat[/etc/named/views/default.zones]/File[/etc/named/views/default.zones]/content: 
--- /etc/named/views/default.zones      2016-06-23 14:07:11.451145673 +0100
+++ /tmp/puppet-file20160628-63755-1sm2sa0      2016-06-28 12:45:53.089162457 +0100
@@ -1,2 +1,3 @@

+include "/etc/named/zones/stivesso.local.conf";

Info: Computing checksum on file /etc/named/views/default.zones
Info: /Stage[main]/Bind::Config/Bind::View[default]/Concat[/etc/named/views/default.zones]/File[/etc/named/views/default.zones]: Filebucketed /etc/named/views/default.zones to puppet with sum 105b1a46d7a92b49f09f8432ce31b929
Notice: /Stage[main]/Bind::Config/Bind::View[default]/Concat[/etc/named/views/default.zones]/File[/etc/named/views/default.zones]/content: content changed '{md5}105b1a46d7a92b49f09f8432ce31b929' to '{md5}ee24b18125334f0d2d1bee701c51cf5d'
Info: Class[Bind::Config]: Scheduling refresh of Class[Bind::Service]
Info: Class[Bind::Service]: Scheduling refresh of Service[bind9]
Notice: /Stage[main]/Profiles::Dnsservers/Bind::Zone[stivesso.local]/Concat[/etc/named/zones/stivesso.local.conf]/File[/opt/puppetlabs/puppet/cache/concat/_etc_named_zones_stivesso.local.conf]/ensure: created
Info: /Stage[main]/Profiles::Dnsservers/Bind::Zone[stivesso.local]/Concat[/etc/named/zones/stivesso.local.conf]/File[/opt/puppetlabs/puppet/cache/concat/_etc_named_zones_stivesso.local.conf]: Scheduling refresh of Exec[concat_/etc/named/zones/stivesso.local.conf]
Notice: /Stage[main]/Profiles::Dnsservers/Bind::Zone[stivesso.local]/Concat[/etc/named/zones/stivesso.local.conf]/File[/opt/puppetlabs/puppet/cache/concat/_etc_named_zones_stivesso.local.conf/fragments]/ensure: created
Info: /Stage[main]/Profiles::Dnsservers/Bind::Zone[stivesso.local]/Concat[/etc/named/zones/stivesso.local.conf]/File[/opt/puppetlabs/puppet/cache/concat/_etc_named_zones_stivesso.local.conf/fragments]: Scheduling refresh of Exec[concat_/etc/named/zones/stivesso.local.conf]
Notice: /Stage[main]/Profiles::Dnsservers/Bind::Zone[stivesso.local]/Concat[/etc/named/zones/stivesso.local.conf]/File[/opt/puppetlabs/puppet/cache/concat/_etc_named_zones_stivesso.local.conf/fragments.concat]/ensure: created
Notice: /Stage[main]/Profiles::Dnsservers/Bind::Zone[stivesso.local]/Concat[/etc/named/zones/stivesso.local.conf]/File[/opt/puppetlabs/puppet/cache/concat/_etc_named_zones_stivesso.local.conf/fragments.concat.out]/ensure: created
Notice: /Stage[main]/Profiles::Dnsservers/Bind::Zone[stivesso.local]/Concat::Fragment[bind.zones.stivesso.local]/File[/opt/puppetlabs/puppet/cache/concat/_etc_named_zones_stivesso.local.conf/fragments/10_bind.zones.stivesso.local]/ensure: defined content as '{md5}a517b1bba36bd1097e7903d9c93146b6'
Info: /Stage[main]/Profiles::Dnsservers/Bind::Zone[stivesso.local]/Concat::Fragment[bind.zones.stivesso.local]/File[/opt/puppetlabs/puppet/cache/concat/_etc_named_zones_stivesso.local.conf/fragments/10_bind.zones.stivesso.local]: Scheduling refresh of Exec[concat_/etc/named/zones/stivesso.local.conf]
Info: Concat::Fragment[bind.zones.stivesso.local]: Scheduling refresh of Exec[reload bind9]
Notice: /Stage[main]/Profiles::Dnsservers/Bind::Zone[stivesso.local]/Concat[/etc/named/zones/stivesso.local.conf]/Exec[concat_/etc/named/zones/stivesso.local.conf]/returns: executed successfully
Notice: /Stage[main]/Profiles::Dnsservers/Bind::Zone[stivesso.local]/Concat[/etc/named/zones/stivesso.local.conf]/Exec[concat_/etc/named/zones/stivesso.local.conf]: Triggered 'refresh' from 3 events
Notice: /Stage[main]/Profiles::Dnsservers/Bind::Zone[stivesso.local]/Concat[/etc/named/zones/stivesso.local.conf]/File[/etc/named/zones/stivesso.local.conf]/ensure: defined content as '{md5}a517b1bba36bd1097e7903d9c93146b6'
Info: Concat[/etc/named/zones/stivesso.local.conf]: Scheduling refresh of Exec[reload bind9]
Notice: /Stage[main]/Profiles::Dnsservers/Bind::Zone[stivesso.local]/Concat[/etc/named/pri/stivesso.local.conf]/File[/opt/puppetlabs/puppet/cache/concat/_etc_named_pri_stivesso.local.conf]/ensure: created
Info: /Stage[main]/Profiles::Dnsservers/Bind::Zone[stivesso.local]/Concat[/etc/named/pri/stivesso.local.conf]/File[/opt/puppetlabs/puppet/cache/concat/_etc_named_pri_stivesso.local.conf]: Scheduling refresh of Exec[concat_/etc/named/pri/stivesso.local.conf]
Notice: /Stage[main]/Profiles::Dnsservers/Bind::Zone[stivesso.local]/Concat[/etc/named/pri/stivesso.local.conf]/File[/opt/puppetlabs/puppet/cache/concat/_etc_named_pri_stivesso.local.conf/fragments]/ensure: created
Info: /Stage[main]/Profiles::Dnsservers/Bind::Zone[stivesso.local]/Concat[/etc/named/pri/stivesso.local.conf]/File[/opt/puppetlabs/puppet/cache/concat/_etc_named_pri_stivesso.local.conf/fragments]: Scheduling refresh of Exec[concat_/etc/named/pri/stivesso.local.conf]
Notice: /Stage[main]/Profiles::Dnsservers/Bind::Zone[stivesso.local]/Concat[/etc/named/pri/stivesso.local.conf]/File[/opt/puppetlabs/puppet/cache/concat/_etc_named_pri_stivesso.local.conf/fragments.concat]/ensure: created
Notice: /Stage[main]/Profiles::Dnsservers/Bind::Zone[stivesso.local]/Concat[/etc/named/pri/stivesso.local.conf]/File[/opt/puppetlabs/puppet/cache/concat/_etc_named_pri_stivesso.local.conf/fragments.concat.out]/ensure: created
Notice: /Stage[main]/Profiles::Dnsservers/Bind::Zone[stivesso.local]/Concat::Fragment[00.bind.stivesso.local]/File[/opt/puppetlabs/puppet/cache/concat/_etc_named_pri_stivesso.local.conf/fragments/01_00.bind.stivesso.local]/ensure: defined content as '{md5}29645f8c7d75136d38f864f00a73539b'
Info: /Stage[main]/Profiles::Dnsservers/Bind::Zone[stivesso.local]/Concat::Fragment[00.bind.stivesso.local]/File[/opt/puppetlabs/puppet/cache/concat/_etc_named_pri_stivesso.local.conf/fragments/01_00.bind.stivesso.local]: Scheduling refresh of Exec[concat_/etc/named/pri/stivesso.local.conf]
Notice: /Stage[main]/Profiles::Dnsservers/Bind::Mx[Mail Server 1 for stivesso.local]/Concat::Fragment[bind.Mail Server 1 for stivesso.local]/File[/opt/puppetlabs/puppet/cache/concat/_etc_named_pri_stivesso.local.conf/fragments/10_bind.Mail Server 1 for stivesso.local]/ensure: defined content as '{md5}84250fe317e5527e18e5f15b1fc5f42e'
Info: /Stage[main]/Profiles::Dnsservers/Bind::Mx[Mail Server 1 for stivesso.local]/Concat::Fragment[bind.Mail Server 1 for stivesso.local]/File[/opt/puppetlabs/puppet/cache/concat/_etc_named_pri_stivesso.local.conf/fragments/10_bind.Mail Server 1 for stivesso.local]: Scheduling refresh of Exec[concat_/etc/named/pri/stivesso.local.conf]
Info: Concat::Fragment[bind.Mail Server 1 for stivesso.local]: Scheduling refresh of Service[bind9]
Notice: /Stage[main]/Profiles::Dnsservers/Bind::Mx[Mail Server 2 for stivesso.local]/Concat::Fragment[bind.Mail Server 2 for stivesso.local]/File[/opt/puppetlabs/puppet/cache/concat/_etc_named_pri_stivesso.local.conf/fragments/10_bind.Mail Server 2 for stivesso.local]/ensure: defined content as '{md5}030ee262b314c0f140c8a51df92c2f96'
Info: /Stage[main]/Profiles::Dnsservers/Bind::Mx[Mail Server 2 for stivesso.local]/Concat::Fragment[bind.Mail Server 2 for stivesso.local]/File[/opt/puppetlabs/puppet/cache/concat/_etc_named_pri_stivesso.local.conf/fragments/10_bind.Mail Server 2 for stivesso.local]: Scheduling refresh of Exec[concat_/etc/named/pri/stivesso.local.conf]
Info: Concat::Fragment[bind.Mail Server 2 for stivesso.local]: Scheduling refresh of Service[bind9]
Notice: /Stage[main]/Profiles::Dnsservers/Bind::Record[CNAMES for stivesso.local]/Concat::Fragment[stivesso.local.CNAME.CNAMES for stivesso.local]/File[/opt/puppetlabs/puppet/cache/concat/_etc_named_pri_stivesso.local.conf/fragments/10_stivesso.local.CNAME.CNAMES for stivesso.local]/ensure: defined content as '{md5}0889d0534fbd925a16bcb7fc73967e46'
Info: /Stage[main]/Profiles::Dnsservers/Bind::Record[CNAMES for stivesso.local]/Concat::Fragment[stivesso.local.CNAME.CNAMES for stivesso.local]/File[/opt/puppetlabs/puppet/cache/concat/_etc_named_pri_stivesso.local.conf/fragments/10_stivesso.local.CNAME.CNAMES for stivesso.local]: Scheduling refresh of Exec[concat_/etc/named/pri/stivesso.local.conf]
Info: Concat::Fragment[stivesso.local.CNAME.CNAMES for stivesso.local]: Scheduling refresh of Service[bind9]
Notice: /Stage[main]/Profiles::Dnsservers/Bind::Record[SRV for stivesso.local]/Concat::Fragment[stivesso.local.SRV.SRV for stivesso.local]/File[/opt/puppetlabs/puppet/cache/concat/_etc_named_pri_stivesso.local.conf/fragments/10_stivesso.local.SRV.SRV for stivesso.local]/ensure: defined content as '{md5}f79273ae3d3e002d12857256fef43d4c'
Info: /Stage[main]/Profiles::Dnsservers/Bind::Record[SRV for stivesso.local]/Concat::Fragment[stivesso.local.SRV.SRV for stivesso.local]/File[/opt/puppetlabs/puppet/cache/concat/_etc_named_pri_stivesso.local.conf/fragments/10_stivesso.local.SRV.SRV for stivesso.local]: Scheduling refresh of Exec[concat_/etc/named/pri/stivesso.local.conf]
Info: Concat::Fragment[stivesso.local.SRV.SRV for stivesso.local]: Scheduling refresh of Service[bind9]
Notice: /Stage[main]/Profiles::Dnsservers/Bind::A[Hosts in stivesso.local]/Bind::Record[Hosts in stivesso.local]/Concat::Fragment[stivesso.local.A.Hosts in stivesso.local]/File[/opt/puppetlabs/puppet/cache/concat/_etc_named_pri_stivesso.local.conf/fragments/10_stivesso.local.A.Hosts in stivesso.local]/ensure: defined content as '{md5}7800b26988a663f0efcef7d0d9e32c68'
Info: /Stage[main]/Profiles::Dnsservers/Bind::A[Hosts in stivesso.local]/Bind::Record[Hosts in stivesso.local]/Concat::Fragment[stivesso.local.A.Hosts in stivesso.local]/File[/opt/puppetlabs/puppet/cache/concat/_etc_named_pri_stivesso.local.conf/fragments/10_stivesso.local.A.Hosts in stivesso.local]: Scheduling refresh of Exec[concat_/etc/named/pri/stivesso.local.conf]
Notice: /Stage[main]/Profiles::Dnsservers/Bind::Zone[stivesso.local]/Concat[/etc/named/pri/stivesso.local.conf]/Exec[concat_/etc/named/pri/stivesso.local.conf]/returns: executed successfully
Notice: /Stage[main]/Profiles::Dnsservers/Bind::Zone[stivesso.local]/Concat[/etc/named/pri/stivesso.local.conf]/Exec[concat_/etc/named/pri/stivesso.local.conf]: Triggered 'refresh' from 8 events
Notice: /Stage[main]/Profiles::Dnsservers/Bind::Zone[stivesso.local]/Concat[/etc/named/pri/stivesso.local.conf]/File[/etc/named/pri/stivesso.local.conf]/ensure: defined content as '{md5}868143982d89632bb6b9273bf43b879b'
Info: Concat[/etc/named/pri/stivesso.local.conf]: Scheduling refresh of Exec[reload bind9]
Info: Concat::Fragment[stivesso.local.A.Hosts in stivesso.local]: Scheduling refresh of Service[bind9]
Notice: /Stage[main]/Bind::Service/Service[bind9]: Triggered 'refresh' from 6 events
Notice: /Stage[main]/Bind/Exec[reload bind9]: Triggered 'refresh' from 4 events
Notice: Applied catalog in 3.42 seconds

Done, DNS Installation and Configuration Puppetised!

References:
http://www.cakesolutions.net/teamblogs/puppet-and-friends 


1 comment:

  1. This comment has been removed by a blog administrator.

    ReplyDelete