DevOps:Puppet,Docker,and Kubernetes
上QQ阅读APP看书,第一时间看更新

Using exported host resources

In the previous example, we used the spaceship syntax to collect virtual host resources for hosts of type database or type web. You can use the same trick with exported resources. The advantage to using exported resources is that as you add more database servers, the collector syntax will automatically pull in the newly created exported host entries for those servers. This makes your /etc/hosts entries more dynamic.

Getting ready

We will be using exported resources. If you haven't already done so, set up puppetdb and enable storeconfigs to use puppetdb as outlined in Chapter 2, Puppet Infrastructure.

How to do it...

In this example, we will configure database servers and clients to communicate with each other. We'll make use of exported resources to do the configuration.

  1. Create a new database module, db:
    t@mylaptop ~/puppet/modules $ mkdir -p db/manifests
    
  2. Create a new class for your database servers, db::server:
    class db::server {
      @@host {"$::fqdn":
        host_aliases => $::hostname,
        ip           => $::ipaddress,
        tag          => 'db::server',
      }
      # rest of db class
    }
  3. Create a new class for your database clients:
    class db::client {
      Host <<| tag == 'db::server' |>>
    }
  4. Apply the database server module to some nodes, in site.pp, for example:
    node 'dbserver1.example.com' {
      class {'db::server': }
    }
    node 'dbserver2.example.com' {
      class {'db::server': }
    }
  5. Run Puppet on the nodes with the database server module to create the exported resources.
  6. Apply the database client module to cookbook:
    node 'cookbook' {
      class {'db::client': }
    }
  7. Run Puppet:
    [root@cookbook ~]# puppet agent -t
    Info: Caching catalog for cookbook.example.com
    Info: Applying configuration version '1413782501'
    Notice: /Stage[main]/Db::Client/Host[dbserver2.example.com]/ensure: created
    Info: Computing checksum on file /etc/hosts
    Notice: /Stage[main]/Db::Client/Host[dbserver1.example.com]/ensure: created
    Notice: Finished catalog run in 0.10 seconds
    
  8. Verify the host entries in /etc/hosts:
    [root@cookbook ~]# cat /etc/hosts
    # HEADER: This file was autogenerated at Mon Oct 20 01:21:42 -0400 2014
    # HEADER: by puppet. While it can still be managed manually, it
    # HEADER: is definitely not recommended.
    127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 
    ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
    83.166.169.231 packtpub.com
    192.168.122.150 dbserver2.example.com dbserver2
    192.168.122.151 dbserver1.example.com dbserver1
    

How it works...

In the db::server class, we create an exported host resource:

@@host {"$::fqdn":
  host_aliases => $::hostname,
  ip           => $::ipaddress,
  tag          => 'db::server',
}

This resource uses the fully qualified domain name ($::fqdn) of the node on which it is applied. We also use the short hostname ($::hostname) as an alias of the node. Aliases are printed after fqdn in /etc/hosts. We use the node's $::ipaddress fact as the IP address for the host entry. Finally, we add a tag to the resource so that we can collect based on that tag later.

The important thing to remember here is that if the ip address should change for the host, the exported resource will be updated, and nodes that collect the exported resource will update their host records accordingly.

We created a collector in db::client, which only collects exported host resources that have been tagged with 'db::server':

Host <<| tag == 'db::server' |>>

We applied the db::server class for a couple of nodes, dbserver1 and dbserver2, which we then collected on cookbook by applying the db::client class. The host entries were placed in /etc/hosts (the default file). We can see that the host entry contains both the fqdn and the short hostname for dbserver1 and dbserver2.

There's more...

Using exported resources in this manner is very useful. Another similar system would be to create an NFS server class, which creates exported resources for the mount points that it exports (via NFS). You can then use tags to have clients collect the appropriate mount points from the server. In the previous example, we made use of a tag to aid in our collection of exported resources. It is worth noting that there are several tags automatically added to resources when they are created, one of which is the scope where the resource was created.