0

I am having a issue of understanding how I could make puppet run a command only if another module/class is installed. I read that Define function could do it, but I did not understand it. Example what I am trying to do:

Lets say I have a module/class SSH and module/class SSH Keys and then I want to run a command in SSH Keys only if SSH module/class is defined in node.

I am doing this for NagiOS, to make sure that NagiOS only monitors those servers that have a module installed that it wants to monitor.

PS: Sorry if I explained it badly.

2 Answers 2

1

One possibility is to use tags. When you include a class, Puppet automatically tags the node with class name. For example:

node myhost {
    include ssh
    # This node is now tagged with 'ssh' tag
    include ssh_keys
}

Note that the order of includes is significant. If ssh_keys is included before ssh class, the tag is not necessarily visible. Also, if you are using node inheritance and including ssh and ssh_keys on different levels, it's not very clear where ssh tag ends up to. If needed, you can tag manually, tag(ssh), but that isn't very maintainable.

You can use tagged function to check if tag is present:

# modules/ssh_keys/manifests/init.pp
class ssh_keys {

    if tagged(ssh) {
        exec {"SSH specific command":
            command => "/usr/bin/run_when_ssh_is_included",
        }
    }
}

This method can also be used in situations like:

  • Specify firewall rules only if firewall class is included
  • Add configuration for monit if monit is included
2
  • Thanks :) This made it clear how it should be used. I tried to use define function multiple times, but there is a issue with it if you have a main location based YAML and then server YAML's. Tagging will help me fix it :)
    – cr0c
    Aug 18, 2014 at 10:33
  • Note that both this and a defined function based approach are evaluation order dependent, as Mikko points out above. This can backfire at you horribly in larger manifests, because the order cannot always be predicted. Use caution. - It is always safer to define this kind of information in a central place, e.g. an array classes in Hiera, which you can check for presence of ssh. Aug 18, 2014 at 16:38
0

You could also have your include ssh_keys within the ssh class itself.

node myhost {
    include ssh
}

class ssh {
    include ssh_keys
}

Using tagged works but its hard to scale up things that rely on parse order. Its better to have all your classes either in the same module or included from within the module that requires it. Also remember that 'includes' do not need to be unique, you can include the same thing multiple times.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .