1

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
        end
    end
end

# /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

Mike Purcell
  • 1,708
  • 7
  • 32
  • 54
  • A parser function seems like a rather painful approach; would you be open to other options? – Shane Madden Jan 11 '13 at 01: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 01: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 02: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 03:22

1 Answers1

2

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..

:backends:
  - yaml

:hierarchy:
  - common

:yaml:
   :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}")
Shane Madden
  • 114,520
  • 13
  • 181
  • 251
  • Nice. Thanks for the response, I will look into and post back. – Mike Purcell Jan 11 '13 at 06: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 07:08