Using a different ENC per environment

I found the ENC must be hard coded in puppet.conf to a single environment, such as:

external_nodes        = $codedir/environments/production/bin/enc.rb  However, I would like to use a different enc for each environment. I read there is a new variable available called "agent_specified_environment", but this only seems available in my modules, I can't find a way to load an enc based on this variable. I was hoping something like this would work: external_nodes =$codedir/environments/${::agent_specified_environment}/bin/enc.rb  Or even accessing that$agent_specified_environment variable from inside the ENC to choose which one to load, but nothing outside modules seems to have access to it, which is already too late as the ENC has already run by then.

For background, I use the enc script to set a role name, and other config info for a node, and I want to be able to make changes in a dev branch and test before merging those changes to production.

Thanks

edit retag close merge delete

This is a bit strange since an ENC is used to determine which environment a node should have (possibly allowing the env to be the one specified by the agent). That means it is kind of impossible to have an "ENC per environment" since you don't know which one to use. You could use your own terminus.

( 2018-03-07 11:36:25 -0600 )edit

Sort by » oldest newest most voted

----- In response to Henrik's comment above about the purpose of this: Maybe I'm using the wrong term, and it should be "node_terminus". It looks like this:

node_terminus         = exec
external_nodes        = \$confdir/environments/production/bin/enc.rb


I know systems like Foreman want to define the environment of a server, and this can't be changed in puppet.conf or on command line. I do testing manually on servers using --environment so I want to be able to have the enc script inside each environment for testing. The enc script is only for providing more info about the node and helping hiera, it's not to tell the node about classes or environments. Node decides environment, and roles/profiles modules define classes.

Since I can only define a single path to the external_nodes in puppet.conf, I have that one find the "agent_specified_environment" fact in the puppetdb, then use that to include the enc_local.rb script inside that environment directory for classifying nodes. This gives facts like "role" and "location" which can be used as paths in hiera. I get a few other things from a mysql db which is only really possible in a ruby script. If I define these in site.pp or a module, it's too late since hiera.yaml doesn't recognize those, and I can't access the mysql db from .pp files or hiera.

An example of hiera.yaml to give you an idea:

---
:backends:
- yaml

:yaml:

:hierarchy:
- "fqdn/%{::fqdn}"
- "role/%{::role_name}/app_%{::app_version}"
- "role/%{::role_name}"
- "location/%{::location}/app_%{::app_provider}"
- "location/%{::location}"
- "group/%{::group}"
- "os/%{::operatingsystem}/%{::operatingsystemmajrelease}"
- "os/%{::operatingsystem}"
- common


The %role_name is created by enc.rb using regex based on hostname, %app_version and %app_provider are from the database that controls our application, %location is based on the domainname. So you can see that there are a lot of hiera locations that depend on the enc script for these paths.

I wanted to do this a long time ago, I actually had a discussion with you on tickets.puppetlabs.com about it here: https://tickets.puppetlabs.com/browse...

And you were the one that mentioned to me that agent_specified_environment was coming, and I should make a wrapper script.

It seems I have a different workflow in my environment than you do, but it actually works really well for me. Every part of our environment exists as pure code inside git branches for easy branching and testing (a tool like foreman can't give me this). If you're interested in learning more about how I have it set up, send me a message to "Colin" on the slack channel and I can tell you more.

---- Official answer that solved my issue

I was able to resolve this by looking into puppetdb in the ENC script for "agent_specified_environment"

curl -X GET http://puppetdb001.example.com:8080/pdb/query/v4/facts --data-urlencode 'query=["and", ["=", "name", "agent_specified_environment"], ["=", ["fact", "clientcert"], "puppettest001.example.com"]]'


Inside a ruby script, it would be like ...

more