Setting custom puppet facts from within your Vagrantfile

Want to help support this blog? Try out Oh Dear, the best all-in-one monitoring tool for your entire website, co-founded by me (the guy that wrote this blogpost). Start with a 10-day trial, no strings attached.

We offer uptime monitoring, SSL checks, broken links checking, performance & cronjob monitoring, branded status pages & so much more. Try us out today!

Profile image of Mattias Geniar

Mattias Geniar, May 15, 2013

Follow me on Twitter as @mattiasgeniar

You may want to set custom puppet facts in your development environment by specifying them in your Vagrantfile, so you can have a unique fact per developer or identify your own environment. Here’s a quick way to do that.

First: make sure you are running the latest version of facter (yum update facter), it should be at least version 1.7 as it supports custom facts easily (check with ‘facter –version’).

$ facter --version
1.7.1

Now, before the Vagrantfile changes, your facter facts will look like this. The solution is within the :shell provider, in the first few lines of the Vagrantfile.

$ facter | grep 'custom'
[empty]

Your Vagrantfile can now be modified to look like this, to set up custom facts.

Vagrant::Config.run do |config|
  # First: run a shell provisioner to set up the custom facts
  config.vm.provision :shell do |shell|
    shell_cmd = ""

    # Make sure the facts directory exists
    shell_cmd << "mkdir -p /etc/facter/facts.d/; "

    # Add as much of these lins for any custom fact you want
    shell_cmd << "echo 'custom_fact1=the value of the fact' > /etc/facter/facts.d/custom_fact1.txt; "

    # Run the inline shell to create those facts
    shell.inline = "#{shell_cmd}"
  end

  # Then: run puppet like you normally would
  config.vm.provision :puppet do |puppet|
    puppet.manifests_path = "manifests"
    puppet.manifest_file = "my_manifest.pp"
  end
end

After a ‘vagrant provision’, your facts will be updated.

$ facter | grep custom
custom_fact1=the value of the fact

And you can now use the $::custom_fact1 variable within your manifests/modules.

Update 16/5: as Dieter De Meyer pointed out, there’s a more elegant solution using the puppet provider itself. The downside is the facts are only available if you use ‘vagrant provision’ to start a Puppet run, if you use Puppet from within the virtual machine, these facts won’t be present (see the Vagrant Helper Scripts for Puppet to speed up your Puppet deployments).

Vagrant::Config.run do |config|
  config.vm.define :test do |vmconfig|
    vmconfig.vm.provision :puppet do |puppet|
      puppet.manifests_path = "manifests"
      puppet.manifest_file = "test.pp"
      puppet.module_path = [ "../", "./modules" ]
      puppet.facter = {
        "custom_fact1" => "value1",
        "custom_fact2" => "value2"
      }
      puppet.options = "--verbose"
    end
  end
end

Thanks!



Want to subscribe to the cron.weekly newsletter?

I write a weekly-ish newsletter on Linux, open source & webdevelopment called cron.weekly.

It features the latest news, guides & tutorials and new open source projects. You can sign up via email below.

No spam. Just some good, practical Linux & open source content.