amazon-ec2environment-variablespuppetcloud-initfacter

Puppet agent daemon not reading a facter fact (EC2, cloud-init)


I am using puppet to read a fact from facter, and based on that I apply a different configuration to my modules.

Problem:

the puppet agent isn't seeing this fact. Running puppet agent --test interactively works as expected. Even running it non-interactively from a script seems to work fine. Only the agent itself is screwing up.

Process:

I am deploying an Ubuntu-based app stack on EC2. Using userdata (#cloud-config), I set an environment variable in /etc/environment:

export FACTER_tl_role=development

then immediately in #cloud-config, i source /etc/environment. only THEN i apt-get install puppet (i moved away from using package: puppet to eliminate ambiguity in the sequence of #cloud-config steps)

Once the instance boots, I confirm that the fact is available: running facter tl_role returns "development". I then check /var/log/syslog, and apparently the puppet agent is not seeing this fact - I know this because it's unable to compile the catalog, and there's nothing (blank) where I'm supposed to be seeing the value of the variable set depending on this fact.

However, running puppet agent --test interactively compiles and runs the catalog just fine. even running this from the #cloud-config script (immediately after installing puppet) also works just fine.

How do I make this fact available to the puppet agent? Restarting the agent service makes no difference, it remains unaware of the custom fact. Rebooting the instance also makes no difference.

here's some code:

EC2 userdata:

#cloud-config

puppet:
  conf:
    agent:
      server: "puppet.foo.bar"
      certname: "%i.%f"
      report: "true"

runcmd:
- sleep 20
- echo 'export FACTER_tl_role=development' >> /etc/environment
- . /etc/environment
- apt-get install puppet
- puppet agent --test

Main puppet manifest:

# /etc/puppet/manifests/site.pp
node default {
case $tl_role {
    'development':  { $sitedomain = "dev.foo.bar"}
    'production':   { $sitedomain = "new.foo.bar"}
}
class {"code" : sitedomain => $sitedomain}
class {"apache::site" : sitedomain => $sitedomain}
class {"nodejs::grunt-daemon" : sitedomain => $sitedomain}

And then I see failures where $sitedomain is supposed to be, so $tl_role appears to be not set.

Any ideas? This is exploding my brain....


Solution

  • Another easy option would be to drop a fact into an external fact.

    Dropping a file into /etc/facter/facts.d/* is fairly easy, and you can use a text file, yaml json or an executable to do it.

    http://docs.puppetlabs.com/guides/custom_facts.html#external-facts

    *that's on Open source puppet, on unix-y machines. See the link for the full docs.