2
votes

I am experimenting with Puppet using Vagrant. I'm new to Puppet.

I'm installing modules in my Puppet manifest using the approach suggested at: Can I install puppet modules through puppet manifest?

My default.pp contains something like:

$dsesterojava = 'dsestero-java'
exec { 'dsestero-java':
   command => "puppet module install ${dsesterojava}",
   unless  => "puppet module list | grep ${dsesterojava}",
   path    => ['/usr/bin', '/bin']
}

include java::java_7 

I'm trying to import a module and then immediately use the classes defined in it.

Currently, I get:

Error: Could not find class java::java_7

If I comment out the include line and re-run it. The module installs. If I then removed the comment and run the provisioning again then it works.

There is some kind of "chicken and egg" situation here. Can I use a module in the same Puppet manifest that installs it?

How should I solve it?

1
No, you cannot do this. When your catalog is compiled, Puppet will search for all of the required code and data. Since the java module does not exist until catalog application, the compilation of a catalog depending upon it will fail. You are absolutely dealing with a "chicken and egg" situation here. I highly recommend against using Puppet code to install Puppet code. - Matt Schuchard
Additionally, the link you provided does not suggest this approach, but rather to use librarian-puppet. That (or its successors r10k and code-manager) are highly recommended over this approach. - Matt Schuchard
Thanks @MattSchuchard. I'm just learning Puppet but we have Puppet Enterprise locally, which I have just discovered uses r10k - so I shall give that a go. - Mark McLaren
Installing Puppet modules for use within Vagrant is also kind of a different beast entirely when you are using them with the internal Puppet provisioner for Vagrant. I expect sooner or later Frederic Henri will arrive and explain the best way to do this, as whenever I Puppet+Vagrant I am doing it for testing purposes and therefore never have to deal with this. Also, if you have Puppet Enterprise you can use "r10k++" (Code Manager), but this would be for the agent provisioner and not the apply provisioner. - Matt Schuchard
Well then, upon request I have converted and expanded the comments into an answer. - Matt Schuchard

1 Answers

3
votes

No, you cannot do this. When your catalog is compiled, Puppet will search in the appropriate directories for all of the required code and data. Since the java module does not exist until catalog application, the compilation of a catalog (occurs prior to application) depending upon it will fail. You are absolutely dealing with a "chicken and egg" situation here. I highly recommend against using Puppet code to install Puppet code.

Alternatively, the recommended approach to install and manage your Puppet modules is to use one of these solutions:

These will also solve the problem for you within the Vagrant if you are using the agent provisioner and subscribing the Vagrant instance to a Puppet Master.

If you are using the apply provisioner inside of Vagrant, then you will need to go a different route. The simplest solution is to use the shell provisioner to install Puppet modules via module install after the Puppet installation (unless you are using a Vagrant box with Puppet baked in, in which case you are probably not installing Puppet on it). Alternatively, you could share a directory with the host where your modules are installed, or install the librarian-puppet or r10k gems onto the Vagrant box and then use them to install into the appropriate path. I can go into more detail on these upon request.