Puppet:Could not find default node or by name with node test2

puppetpuppetmaster

I installed Puppet 3.1.1 on an Ubuntu Server.

My manifests folder looked like this:

├── nodes
│   └── test1.pp
└── site.pp

The content of site.pp was:

# site.pp
import "nodes/*.pp"

Node test1 worked OK.

Then I created a new file named test2.pp. The content was the same as test1.pp except for the node name, and I added it into the nodes folder.

So the manifests folder became this:

├── nodes
│   ├── test1.pp
│   └── test2.pp
└── site.pp

I then ran puppet agent --test on node test2.

The agent could exchange SSL keys with the puppet master, but I got an error message:

Could not find default node or by name with test2

If I don't create a new test2.pp file, and just add the content into the test1.pp file, no error appears.

So I am thinking Puppet will not dynamically import a new pp file after the puppet master has been started.

Is is possible to define nodes in individual pp files and dynamically import them?

Glad for any suggestions.


The content of the two pp files:

node 'test1' {
  include tmp::params
  tmp::gtp { 'node1':
    name            => 'node1',
    version         => '6.0.0.0',
    ip              => '168.1.193.97',
    port            => '1255',
  }
}

node 'test2' {
  include tmp::params
  tmp::gtp { 'node2':
    name            => 'node2',
    version         => '6.0.0.0',
    ip              => '168.1.193.98',
    port            => '1255',
  }
}

Best Answer

I'd recommend moving away from manifest node definitions to Hiera. You'll need to tweak things a bit to move away from having that defined type called directly from your node, but it looks like that isn't being used multiple times in a catalog anyway, so conversion to a class should work fine.

So with a hiera.yaml like this..

---
:backends:
  - yaml

:hierarchy:
  - '%{::clientcert}'
  - 'os-%{::osfamily}'
  - common

:yaml:
   :datadir: /etc/puppet/hieradata

And a site.pp with just:

hiera_include(classes)

..your nodes will be read from YAML files in /etc/puppet/hieradata. For example's sake we'll say that you want tmp::params on every node reporting to Puppet, but maybe you want tmp::gtp just on certain nodes. And you want to centrally define the version parameter, but leave the other parameters to be set per-node. So we'll put tmp::params and the version parameter /etc/puppet/hieradata/common.yaml:

classes:
  - tmp::params

tmp::gtp::version: 6.0.0.0

Then you'll have a file for each node.

/etc/puppet/hieradata/test1.yaml:

classes:
  - tmp::gtp

tmp::gtp::name : node1
tmp::gtp::ip   : 168.1.193.97
tmp::gtp::port : 1255

/etc/puppet/hieradata/test2.yaml:

classes:
  - tmp::gtp

tmp::gtp::name : node2
tmp::gtp::ip   : 168.1.193.98
tmp::gtp::port : 1255

And yes, it'll pick up changes to the Hiera files without a service restart. Seem like about what you need?

Edit: to use Hiera to set up multiple instances of a defined type, you'll want to do something like this:

/etc/puppet/hieradata/test1.yaml:

classes:
  - gtpsetup

gtp_instances:
  - node1_instance1
  - node1_instance2

gtp_instanceconfig:
  node1_instance1:
    ip      : 168.1.193.97
    port    : 1255
    version : 5.3.2.1

  node1_instance2:
    ip      : 168.1.193.97
    port    : 1268
    version : 6.0.0.0

/etc/puppet/modules/gtpsetup/manifests/init.pp:

class gtpsetup {
  gtp_instances = hiera('gtp_instances')
  gtp_instanceconfig = hiera('gtp_instanceconfig')

  define gtp_instance {
    # this is using your existing defined type, but you can just move the stuff it's doing to here.
    tmp::gtp { $title:
      name    => $title,
      version => gtp_instanceconfig[$title]['version'],
      ip      => gtp_instanceconfig[$title]['ip'],
      port    => gtp_instanceconfig[$title]['port'],
    }
  }

  gtp_instance { $gtp_instances: }
}