inkblot/puppet-bind

Allow the whole definition to be defined in the resource name

Closed this issue · 3 comments

Hi,

first of all thanks for this module. I search a lot for a module that updates my DNS via nsupdate because this is the only way I can think of to allow modifications from other sources two.

I only have one Problem here: If I want to include all my dns configuration in this module so that we can manage them via puppet even with our relatively small (little bit more than 200 RRs) Zonefile this would bloat the puppet confiration to a extend that it is no longer readable because, (as I understood the documentation) I would have to add at least put

  resource_record { 'www.example.com address':
    record  => 'www.example.com',
    type    => 'A',
    data    => [ '172.16.32.10'],
  }

for each RR.

It would compress the puppet file a lot if the type would interpret the name as complete RR if @record@,@type@ and/or @DaTa@ is not specified.
I would prefer something like

resource_record {
 [
  'www A 172.16.32.10',
  'ns A 172.16.32.10',
  'www NS 10 ns',
]:
zone    => 'example.com',
}

That way I could import the whole zone file to puppet and keep it readable.

It's not necessary to specify all resource records in a zone as Puppet resources. You can still manually manipulate RRs using nsupdate and you can also initialize your zone by placing an existing fully specified zone file in the location where the module expects it. This will be the starting point for the zone once it is managed by the module. If you intend to keep backups of the zone, this is also the file that needs to be stored in order to recover.

This way of handling DNS resource records is not much different from how Puppet users typically manage files in the filesystem. You can have Puppet manage a file, or not and in that case you have a backup or some other means of recovery. The module is designed so that DNS RRs can have similar mixed Puppet and manual management.

If you still have lots of records that you want to specify using Puppet, I recommend against making a big long list of them. Instead what you can do is an export and collect to create them. The export would occur on nodes that are effectively publishing RRs and the collect would happen on the nameserver where you could then specify administrative properties like TSIG keys. The saz/ssh module uses a similar technique for populating ssh host keys into known_hosts files on client nodes.

For example you can do something like this:

  node webserver {
    @@resource_record { "webserver $::fqdn address":
      zone => 'example.com',
      type  => 'A',
      data  => $::ipaddress,
    }
  }

  node nameserver {
    Resource_record <<| |>> {
      ensure => present,
    }
  }

In a different kind of scenario, where you have many different zones, or names within zones that are all structurally similar, you can use a define as an abstract way of manage multiple RRs resources in a repeatable way. For example, three zones that all have a website and email in the same place:

  define hosted_zone (
    $address = $::ipaddress,
    $mail_exchanger = $::fqdn,
  ) {
    @@resource_record { "hosted zone ${name} on ${::fqdn} address":
       zone => $name,
       type => 'A',
       data => [ $address ],
    }
    @@resource_record { "hosted zone ${name} on ${::fqdn} mail exchanger":
      zone => $name,
      type => 'MX',
      data => [ $mail_exchanger ],
    }
  }

  node host1 {
    hosted_zone { [ 'example.com', 'someother.ex' ]: }
  }

  node host2 {
    hosted_zone { [ 'example.org' ]: }
    hosted_zone { [ 'subexample.org' ]:
       mail_exchanger => [ 'internalmail.example.org' ], # sub.example.org's email is not hosted here
    }
  }

I'm going to make a change so that a zone definition has a source parameter, which will populate a new zone file from the supplied source file. This should make it more obvious how to bootstrap a nameserver with existing zone files.

Think pull request #14 should take care of your issue of importing a large number of existing records.