Use local file as puppet template

deploymentpuppetrpmtemplate

I'm developer of a java software and try to find a smart way to get my app distributed and configured in our datacenter. For that, I build an rpm package and we have set up a satellite. Target OS is Red Hat Enterprise. For configuration management we use puppet.

Until now, everything is running fine. We are setting DB connection strings and hostnames based on node configurations in puppet. These go into erb template files that we also have in the puppet master.

But now, I need to patch a single file that is part of the RPM. This is a file that is generated on build and changes with every build, so we do not like to put it into puppet. There is an identifier in (freely chosen, like <% baseURL %>). Unfortunately, we need to set a base URL in this file which depends on the node where it goes. I thought about putting our file in the RPM as .erb, but it seems that puppet can not use local files from the target system as templates, in all examples I've seen the templates are located on the puppet master.

The other problem is, that the transformation from the template into the real config file must happen if either the package is updated or the baseUrl configuration changes.

I would like to utilize the puppet templating for this, but I'm not sure if this works.

My current solution is:
I use puppet to create a node-dependent file on every machine in /etc/myapp/webstart_baseurl. It looks like:

MYAPP_WEBSTART_BASEURL=http\\:\\/\\/10.12.1.42\\/myapp_ws\\/
export MYAPP_WEBSTART_BASEURL

Then I wrote a shell script, that I included in my RPM. This is placed in /usr/bin/patchHostnameForWebstart.sh

#!/bin/sh

#the file where to load the baseUrl from (in property $MYAPP_WEBSTART_BASEURL)
MYAPP_WEBSTART_SERVERCONFIG=/etc/myapp/webstart_baseurl

MYAPP_JNLP_TOKEN=@@myapp.webstart.baseurl@@

if [ -f $MYAPP_WEBSTART_SERVERCONFIG ]
then
    source $MYAPP_WEBSTART_SERVERCONFIG
    echo "found config for webstart server, baseUrl is $MYAPP_WEBSTART_BASEURL"
    echo "replacing tokens MYAPP_JNLP_TOKEN .."

    find /var/www/html/myapp_ws -name *.jnlp -print -exec sed -i  "s/${MYAPP_JNLP_TOKEN}/${MYAPP_WEBSTART_BASEURL}/g" {} \;
    echo "url tokens of all .jnlp files in /var/www/html/myapp_ws have been processed"

else
    echo "WARNING! no config for webstart server found, baseUrl of .jnlp files might not be set"
    exit 1

fi

To separate the script from puppet has the advantage that it can be run directly in rpm install as well as from puppet in case the baseUrl config changes.

However, the downsides of this solution are that I had to implement the substitution on my onw and that I need to write the baseUrl config in this very ugly, double quoted way with lots of backslashes. I think this is quite error-prone if somebody else should change it.

Any improvement suggestions would be great. Thanks in advance

Michel

Best Answer

puppet can use local information.. If you write a facter script that sets a fact.. you can reference that value from inside puppet.

Example

$ facter puppetversion
2.6.4

I can use $puppetversion in my template or pp file to get 2.6.4. Writing a facter script is pretty easy and you can use puppet to distribute the facter script to place it in the correct location so when you run facter it will add it to the list.

http://projects.puppetlabs.com/projects/1/wiki/Adding_Facts