Ask Your Question
0

How would you handle injection of a configuration file for a Puppet module?

asked 2016-10-07 22:35:31 -0500

notgoodatpuppet gravatar image

I'm writing a puppet module for an inhouse application that needs configuration information to access several services: internal APIs, AMQP services, MongoDB database. It accepts a configuration file which specifies the various parameters on setting it up. S

The application is deployed as a Debian package delivered from an internal APT repository. The package does not supply a default configuration file. There is a reliance on Puppet for deployment.

Question: What is a good way to supply configuration data for this specific use-case (in-house application, in-house module that will not be published on puppetforge) while still abiding by good practices of separating Puppet code & data?

To help understand where I'm coming from, here are the ideas I have already thought of:

(1) Break the configuration down into several granular parameters, then use Hiera to supply each individual parameter. These parameters would then be supplied into a template which constructs the configuration file.

(2) Supply the configuration data as a string parameter (as shown in the below sketch of the module).

(3) Supply the configuration data as a fileserver supplied (puppet://) file.

I find (1) particularly annoying since Puppet now has to know the schema of the configuration file and it would be prudent to also do parameter validation. This means additional Puppet DSL code which I would very much like to avoid.

I have an affinity for (2) but it seems like a very lazy approach. The nice thing about it is, that I can supply the configuration file data directly in Hiera in YAML. But maybe this is not a great idea since I will be bloating Hiera and basically using it as a file-server.

I think (3) makes the most sense, except I don't want to put configuration files in the module directory, because this will again mix code & data. Is it possible to serve the files from the directory environment and instead supply the 'puppet:///' url as a parameter. Even better if we can mix (2) and (3) so that you can supply either a string or URL to plop the data in.


Here is a sketch of the puppet module for reference:

class application(
    $config_pathname = "/etc/application/config.toml",
    $config_data = "",
)
{
   package{'application':}

   file{$config_pathname:
       content => $config_data,
       require => Package['application'],
   }

   supervisrod::program {'application':
       command => "/path/to/app ${config_pathname}",
       require => Package['application'],
       refresh => File[$config_pathname],
   }
}

Example configuration file:

[services_api]
baseurl = "http://services/api"
hmac_id = ""
hmac_provider = ""
hmac_secret = ""

[job_queue]
amqp_uri = "amqp://user:pass@127.0.0.1:5672/jobs"
queue = "jobs"

[finished_queue]
amqp_uri = "amqp://user:pass@127.0.0.1:5672/jobs"
queue = "finished"
exchange = "jobs"
exchange_type = "x-modulus-hash"
route_key = "finished.#"

[mongodb]
hostname = "127.0.0.1"
username = ""
password = ""
ssl = false
db_name_auth = ""
db_name = "jobs"
collection = "job_transcripts"
edit retag flag offensive close merge delete

Comments

We currently have a similar 'configuration' problem. Across all/most of our nodes, we have a common .properties file that gets populated with values. We have our own custom module that populates that file only to keep it separate, and we supply the parameters via hiera or environmental lookups

DarylW gravatar imageDarylW ( 2016-10-08 15:09:19 -0500 )edit

In most cases, we probably would have the individual entries as input to the profile for each piece of software that needs the configuration, and manage that per profile, and use hiera to divy of the information that way (In your case, each section could be maanged with ini_file)

DarylW gravatar imageDarylW ( 2016-10-08 15:11:03 -0500 )edit

1 Answer

Sort by ยป oldest newest most voted
0

answered 2016-10-08 14:57:43 -0500

lupin gravatar image

updated 2016-10-08 14:59:22 -0500

If there's heaps of variable entries inside the configuration file, I prefer to use a template. Hiera will then supply the known variable values as class parameter.i.e

 class app (  
          db_name          = hiera('app::db') ,
          db_name_auth = hiera('app:db_auth')
    ) {

 # You can do param value validate check here if you want to.
 # generate config file from template and param values
  file { '/path/to/config_file',
     ensure  => 'file'
      content => template('class/config.erb'), 
   }
}

Excerpt content of config.erb

[mongodb]
hostname = <%= @ipadress %>
username = ""
password = ""
ssl = false
db_name_auth = <%= @db_name_auth %>
db_name = <%= @db_name %>
collection = "job_transcripts"

So within the template you can access system facts such as @ipaddress etc..

edit flag offensive delete link more

Comments

I see. So if I don't break down the configuration into granular parameters and build it back up as a template, then I forgo the ability to use facts. On the other hand, YAML can interpolate hiera lookups.

notgoodatpuppet gravatar imagenotgoodatpuppet ( 2016-10-08 22:28:21 -0500 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2016-10-07 22:35:31 -0500

Seen: 106 times

Last updated: Oct 08 '16