Secrets store integrations and agent-side data retrieval


Puppet agents can fetch or calculate data for themselves at catalog application time. One use case for this is to securely retrieve sensitive information like passwords from a secrets store.

The Deferred type enables these two capabilities. It instructs agents to execute a function locally to resolve a data value at the time of catalog application. When compiling catalogs, functions are normally executed on the master, with results entered into the catalog directly. The complete and fully resolved catalog is then sent to the agent for application. Starting in Puppet 6.0, you can defer the function call until the agent applies the catalog, meaning the agent calls the function on the agent instead of on the master. This way, agents can use a function to fetch data like secrets directly, rather than having the master act as an intermediary.

Integrations with secret stores

The Forge already hosts some community modules that provide integrations with secret stores.

Modules with secret store integrations:

Using a Deferred function

An example of using the Deferred type to wrap a function and execute on the agent.

Deferred function example

Prior to Puppet 6.0, you used a function executed on the master to evaluate a result and store it in the catalog. See the Puppet code below, which prints the result of myfunction.

$d = myfunction("myarg1", “myarg2”)

node default {
  notify { example :
    message => $d
To execute this function on the agent, wrap it with the Deferred type. In this case, the function name is the first parameter and the function's parameters are passed as an array. Converting the same call to myfunction using Deferred looks like this:
$d = Deferred(“myfunction”, ["myarg1", “myarg2”])

Using a template with Deferred values

Templates are rendered on the master during catalog compilation. However, this won't work with deferred functions because their values aren't known at compile time. Instead, you need to defer the template rendering.

To defer the template rendering, you need to compile the template source into the catalog, and then render the string using the inline_epp() function. The template source must be in the files directory of your module for it to be accessible to the file() function.

 $variables = {
      'password' => Deferred('vault_lookup::lookup',
                      ["secret/test", 'https://vault.docker:8200']),

    # compile the template source into the catalog
    file { '/etc/secrets.conf':
      ensure  => file,
      content => Deferred('inline_epp',
                   [file('mymodule/secrets.conf.epp'), $variables]),
Note: You cannot defer .erb style templates like this because of the way they use scope. Use .epp templates instead.
How helpful was this page?

If you leave us your email, we may contact you regarding your feedback. For more information on how Puppet uses your personal information, see our privacy policy.

Puppet sites use proprietary and third-party cookies. By using our sites, you agree to our cookie policy.