Search code examples
vagrantpuppetpuphpet

How do I handle dependencies in Puppet?


In my puppet manifect I want to use dirtree function like

#don't know which syntax is right, but seems like both of them have no effect  
include AlexCline/dirtree
include AlexCline_dirtree

class sw_mage_deploy {
    $deploy_folder = '/var/www/html'

    file { dirtree($deploy_folder):
        ensure => directory,
        owner  => 'root',
        group  => 'root',
        mode   => 755,
    } 
} 

And in my Modulefile I have

dependency 'AlexCline/dirtree', '>= 0.2.1'

But I'm getting an error:

==> default: Error: Unknown function dirtree at /tmp/vagrant-puppet/modules-bcfd
1f8b7eed950360c8143b9e421347/sw_mage_deploy/manifests/init.pp:15 on node vagrant
-vm

Tried this article, but it seem to be irrelevant. Because it covers class inclusion and I need method inclusion.

As a side question I would really appreciate a link to puppet tutorial for very beginners, because googling doesn't really help and all docs seem to admit some obvious knowledge minimum which I seem to miss.


Solution

  • NOTE I am certainly not a puppet guru, been learning for few months, so cannot really address a tutorial and might not use the best practise.

    on the first part of the question: how to handle dependencies in Puppet

    I know of 2 ways:

    1. use http://librarian-puppet.com (I do not really use it mylself so I might need to be corrected) which will manage dependencies from a Modulefile, a bit like you seem to describe. Using it with Vagrant, you need to install and configure it (using shell script) - a plugin exists which manages this part so this is surely a good option to look

    2. currently, I am managing dependencies through normal `puppet module install' in shell script. Run a shell script from Vagrant which will install all modules, puppet takes care of all modules dependencies (if any) as they are declared from the individual module. An example of such script is

      #!/bin/bash
      
      mkdir -p /etc/puppet/modules;
      
      if [ ! -d /etc/puppet/modules/example42-perl ]; then
        puppet module install example42-perl --version 2.0.20
      fi
      
      if [ ! -d /etc/puppet/modules/puppetlabs-apache ]; then
        puppet module install puppetlabs-apache --version 1.5.0
      fi
      
      if [ ! -d /etc/puppet/modules/puppetlabs-java ]; then
        puppet module install puppetlabs-java --version 1.4.1
      fi
      

    on the second part of the question: issue with using the dirtier function

    • install the module as any other module puppet module install AlexCline-dirtree (if you do not have puppet on your host, use your VM and copy the /home/vagrant/.puppet/modules to your shared folder /vagrant/modules)
    • declare the following in your Vagrantfile

      config.vm.provision :puppet do |puppet|
        puppet.manifests_path = "puppet/manifests"
        puppet.manifest_file = "base.pp"
        puppet.module_path = "puppet/modules"
        puppet.options = "--verbose --trace"
      end
      

    and make sure you have created the puppet/manifests/base.pp file and the puppet/modules directory with the module you have installed

    • define your puppet file

      class sw_mage_deploy {
      
          $deploy_folder = "/var/www/html"
          $dirtree = dirtree($deploy_folder)
      
      #    file { ["$dirtree"] :
      #        ensure => directory,
      #        owner  => "root",
      #        group  => "root",
      #        mode   => 755;
      #    } 
      
          ensure_resource('file', $dirtree, {
              'ensure' => 'directory',
              owner  => "root",
              group  => "root",
              mode   => 755
          })
      
      
      } 
      
      include sw_mage_deploy
      

    As $dirtree returns an array, you cannot use it directly in your file block (it will try to concatenate all values from your array into a single value) but use the ensure_resource function that can apply this for an array of resource

    It is true that if you do not apply a variable, the following works

    file { [ '/var/www',
             '/var/www/html',]:
               ensure => directory,
               ...
    

    There might be way to bind the variable (which is an array) to be used like this, but I dont know how.