I am working on puppetizing my httpd and nginx vhost confs. Right now I have 5 servers which each have their own port and are run on server1, while nginx is running on server2. Obviously I need to keep the manifest calls to httpd and nginx separate because they can be run on different servers.

What I am trying to do is share the ports between both manifests, so all I need to do is pass in the name of the vhost I want, to either httpd, and nginx and it will lookup the port in a central location. I am trying to implement a custom function and currently have it setup like this:

# /path/to/puppet/modules/global/lib/puppet/parser/functions/app_to_port.rb
module Puppet::Parser::Functions
    newfunction(:app_to_port, :type => :rvalue) do |args|
        case args[0]
            when app_1
                return 27960
            when app_2
                return 27961

# /path/to/puppet/modules/httpd/manifests/vhost/conf.pp


$vhost_port = app_to_port($name)


I keep running into various issues, with $name I keep getting undefined local variable or method 'app_1' errors, and if I pass in an int, the $vhost_port variable never gets a value. I'm new to ruby and puppet, which leads me to believe I am missing some language or app construct. I ran ruby -rpuppet /path/to/app_to_port.rb with no response, which leads me to believe that the code is syntactically correct.

For the record, I was reading up on http://docs.puppetlabs.com/guides/custom_functions.html and https://stackoverflow.com/questions/948135/how-to-write-a-switch-statement-in-ruby to get me to this point.

Current env: ruby 1.8.7 and puppet 2.7.19

  • A parser function seems like a rather painful approach; would you be open to other options? – Shane Madden Jan 11 '13 at 1:56
  • Indeed, it seems you get the gist of what I am trying to accomplish. However, I'd prefer to not have to pass a port in the nodes file... Id rather just make a call like this: httpd::vhost {'app_1':} – Mike Purcell Jan 11 '13 at 1:59
  • 1
    Seems like I'm recommending this a lot lately, but how about storing the app-to-port mapping in a Hiera YAML file and doing a lookup from the vhost setup once you have the application name? – Shane Madden Jan 11 '13 at 2:24
  • That sounds perfect, if you could give an example that would be great, otherwise I can google around. – Mike Purcell Jan 11 '13 at 3:22

Hiera is included in Puppet 3.0 - in 2.7, you'll need to install it separately on your masters.

Since it sounds like you'll want the mapping to be global, you'll want to put it in a Hiera file that applies to all systems. So in your hiera.yaml, you'll want something like..

  - yaml

  - common

   :datadir: /etc/puppet/hieradata

Then in /etc/puppet/hieradata/common.yaml, set up your port mappings:

port_app_1: "27960"
port_app_2: "27961"

With that in place, you can look it up in your vhost config.

$vhost_port = hiera("port_${name}")
  • Nice. Thanks for the response, I will look into and post back. – Mike Purcell Jan 11 '13 at 6:43
  • Worked like a charm. I did have to do a gem install hiera hiera-puppet, then symlink /usr/lib/ruby/gems/1.8/gems/hiera-puppet-1.0.0 hiera-puppet within my modules directory, but after doing so, it worked as expected. Thanks again. – Mike Purcell Jan 11 '13 at 7:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.