Search code examples
vagrantpuppet

Error: undefined method 'ref' for nil:NilClass on node vagrant-trusty64


I'm having a problem with my Puppet manifests in my local Vagrant machine. Whenever I try to provision my Vagrant machine, I receive the following output, which I can't seem to find the cause:

Error: undefined method `ref' for nil:NilClass on node vagrant-trusty64.lan
Error: undefined method `ref' for nil:NilClass on node vagrant-trusty64.lan
The following SSH command responded with a non-zero exit status.
Vagrant assumes that this means the command failed!

puppet apply --modulepath '/tmp/vagrant-puppet-1/modules-0:/etc/puppet/modules' --hiera_config=/tmp/vagrant-puppet-1/hiera.yaml --manifestdir /tmp/vagrant-puppet-1/manifests --detailed-exitcodes /tmp/vagrant-puppet-1/manifests/vagrant.pp || [ $? -eq 2 ]

Stdout from the command:



Stderr from the command:

stdin: is not a tty
Error: undefined method `ref' for nil:NilClass on node vagrant-trusty64.lan
Error: undefined method `ref' for nil:NilClass on node vagrant-trusty64.lan

Any ideas on where to start debugging?

Vagrantfile:

# -*- mode: ruby -*-
# vi: set ft=ruby :

# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
    # Use Phusion's Ubuntu 12.04 box with support for Docker
    config.vm.box = "phusion-open-ubuntu-14.04-amd64"
    config.vm.box_url = "https://oss-binaries.phusionpassenger.com/vagrant/boxes/latest/ubuntu-14.04-amd64-vbox.box"
    # Set hostname
    config.vm.hostname = "vagrant-trusty64"

    # Configure the VirtualBox Provider
    config.vm.provider :virtualbox do |vb|
        # Give the VM 1GB of RAM
        # vb.customize ["modifyvm", :id, "--memory", "1024"]
    end

    # Provisioning with Puppet Standalone 
    config.vm.provision :puppet do |puppet|
        puppet.hiera_config_path = "conf/puppet/hiera.yaml"
        puppet.manifests_path = "manifests"
        puppet.manifest_file  = "vagrant.pp"
        puppet.module_path = "modules"
    end
end

Solution

  • First, when trying to debug these issues, as Felix Frank points out in his comment on the question, add Puppet's --trace argument to the Puppet arguments that Vagrant uses:

    Vagrant.configure("2") do |config|
        config.vm.provision :puppet do |puppet|
            # ...
            puppet.options = ["--debug", "--trace"]
        end
    end
    

    An even better solution:

    Vagrant.configure("2") do |config|
        config.vm.provision :puppet do |puppet|
            # ...
            if ENV.key?('PUPPET_OPTS')
                puppet.options = ENV['PUPPET_OPTS'].split(' ')
            end
        end
    end
    

    With the above command, simply define the PUPPET_OPTS environment variable when running:

    PUPPET_OPTS="--trace --debug" vagrant provision
    

    This revealed the general point in the Puppet manifests that things were failing. I commented out some stuff and isolated the problem to the following class:

    class profiles::some::long::path {
        contain a, b, c
    }
    

    ...where a, b, and c were classes inside of profiles::some::long::path. The weird thing is that somehow this exact code ran fine last night at some point. I'm still trying to find out if there's an abridged syntax for including classes in the current class' package.