Create a file which lists all server names with a given environment variable

70 views
Skip to first unread message

phundisk

unread,
Apr 26, 2013, 1:36:21 PM4/26/13
to puppet...@googlegroups.com
I am presuming that this is something I need to do with stored configs, but there might also be another way to do it.

I am looking to create a file called /root/production.servers which will list all my production servers.  All production servers have the puppet variable of $environment='production' in the nodes.pp.  Is there a way I can utilize this variable to create this file?  Is stored configs the best option here?

jcbollinger

unread,
Apr 29, 2013, 9:53:26 AM4/29/13
to puppet...@googlegroups.com


On Friday, April 26, 2013 12:36:21 PM UTC-5, phundisk wrote:
I am presuming that this is something I need to do with stored configs, but there might also be another way to do it.

I am looking to create a file called /root/production.servers which will list all my production servers.  All production servers have the puppet variable of $environment='production' in the nodes.pp.  Is there a way I can utilize this variable to create this file?  Is stored configs the best option here?

There are basically two approaches:
  1. The master knows at all times which nodes are supposed to be production servers.  This would involve an exhaustive list of the production servers in a Puppet manifest or in a data file read by the master.  In this case, you would probably just build the file via a template and apply it as a normal File resource.  No stored configs are needed for this.
  2. What I think you're saying, though, is that you want Puppet to dynamically recognize nodes based on their self-declared environment (if the master were choosing the environment rather than the agent, then you would have case 1).  The most natural way to handle this situation is via exported resources (which requires stored configs).
For case 2, the key thing to remember is that each production server must declare and export a distinct resource that describes its own node-specific data.  That's not the whole file, but rather just a piece of one.  The Concat add-in module is perfect for this sort of thing.  You might use it like so:

# This class must be included on production servers
# (and not on other nodes).
class prod::server {
  # Export a line of the production server list
  @@concat::fragment { "prodserver-${hostname}":
    target => '/root/production.servers',
    content => "${hostname}\n"
  }
}

# Nodes that should have the server list declare this class;
# they may be production servers, but do not need to be.
class prod::serverlist {

  # The target file
  concat { '/root/production.servers':
    owner => 'root',
    group => 'root',
    mode => '0644'
  }

  # Import all the fragments:
  Concat::Fragment<<| target == '/root/production.servers' |>>
}


The final piece, then, is to ensure that class 'prod::server' gets declared on all the production servers, and only those.  If you're going to use the $environment variable to control this, then that means putting a conditional statement such as this one somewhere that that is evaluated for every node:

if $environment == 'production' {
  include 'prod::server'
}

That could go in a shared base node or in a common class that all nodes declare.


John

Reply all
Reply to author
Forward
0 new messages