0

I have an issue wherein i am trying to set external facts and then copy a template file which gets populated with values from hiera yaml file. The template file is dependent on certain facts(such as the owner and group of the of the template file) which gets set by the external facts file. Below is the puppet code.

    file {['/etc/facter/','/etc/facter/facts.d']:
            ensure => directory,
            owner => 'root',
            group => 'root',
            mode => '0755',
    }

    file {"/etc/facter/facts.d/domain_facts.sh":
            ensure => present,
            owner => 'root',
            group => 'root',
            mode => '0755',
            source => $::hostname?{
                    'hostname1' => 'puppet:///modules/vfecare/hostname1.sh',
                    },
            require => File['/etc/facter/','/etc/facter/facts.d'],
    }

    file {"/tmp/testing123":
            ensure => present,
            owner => "${::remoteuser}",
            group => "${::remotegroup}",
            content => template("vfecare/testscript.erb"),
            require => File["/etc/facter/facts.d/domain_facts.sh"]
    }

However during execution, i see that the template gets copied first to the puppet agent machine and since the template has some values that it needs from the external facts file, it cannot find and it throws error saying "Invalid owner and group value".

Below is the content of the external facts file

#!/bin/bash

echo "remoteuser=tempuser"
echo "remotegroup=tempuser"

Why does puppet seem to ignore the dependency cycle here?

Iowa
  • 2,171
  • 4
  • 22
  • 31

1 Answers1

3

Facts are collected by the agent at the very start of a Puppet run, before the catalog containing your file resources gets executed. It isn't possible to deploy an external fact during the run and use it like this as the facts will be missing.

Instead, you need to rely on Puppet's "pluginsync" mechanism that copies external facts from the master to the agent before it collects facts.

Move the vfecare/files/hostname1.sh fact file in the module to vfecare/facts.d/hostname1.sh, remove the file resources you have for /etc/facter and copying the external fact, then re-run the agent. It should first download the hostname1.sh fact file, then evaluate the /tmp/testing123 file resource correctly with the remoteuser/group values.

See the docs at Auto-download of agent-side plugins for more information.

Dominic Cleal
  • 3,205
  • 19
  • 22
  • But the thing is that the pluginsync will simply copy all the fact files, rather than copy files based on the hostname of the machine. Is there a way to accomplish this? – Iowa Oct 19 '16 at 10:37
  • 3
    I assumed that was a dummy example, sorry. I think you'd be far better off using Hiera or similar for per-hostname configuration. Facts are about discovering information from a host, it makes little sense to deploy per-host facts to the agent this way and then read them back to the master. – Dominic Cleal Oct 19 '16 at 13:22
  • 1
    Good explanation, but he is trying to use external facts and not custom facts. Also, while Hiera does make more sense than this from a design perspective, some kind of ENC or CMDB that Puppet can access would be even more efficient and clean. – Matthew Schuchard Oct 19 '16 at 13:30
  • 1
    @MattSchuchard, external facts can be subject to pluginsync, too, just as m0dlx describes. This is covered in the doc he linked. He's used the wrong term, but the procedure he describes is valid. – John Bollinger Oct 19 '16 at 15:34
  • Yep, sorry, I did mean to say external facts. I'll correct the answer! – Dominic Cleal Oct 20 '16 at 07:07