Linux – Puppet ensure file is directory OR link. Or ensure directory only if absent

linuxpuppet

2 CentOS servers that I'd like to apply the same manifest to. The manifest creates a user with a custom home directory location under /var/username

Problem is on one of the servers /var/username has to be a symlink off to /data/username. So simply running ensure => 'directory', would attempt to overwrite the symlink.

And I can't use ensure => 'present' because that creates a file by default if it doesn't exist. So for new servers that this manifest applies to a blank file will be created when I actually need it to be a directory.

  1. Is there a way of doing ensure directory or link? So that if it's absent a directory is created. And if it's a link, then just leave it alone? By default the Puppet file type creates a file when doing ensure => 'present'.

  2. Or a way of doing if absent ensure directory else leave it alone?

What about exec, doing a simple bash if /var/username not exist then mkdir sort of thing?
Nasty but it would work.

The ideal solution is probably to avoid special cases from the start. Having multiple config variants in a single manifest does seem a bit wrong. So eventually I will either:

  • normalise the VMs (might switch from a symlink to a bind mount for example)
  • give them separate manifests, since the configuration between them is different

But for the purposes of this question I would like to know if there are any options/syntax within Puppet that I currently don't know about.

Best Answer

You could always use $hostname or $certname to handle the exception:

file { "/var/username":
mode    => 440,
ensure  => $hostname ? {
  'oddballserver' => link,
  default  => directory,
  }, 
target => $hostname ? {
  'oddballserver' => '/data/username',
}

That's untested, but based on logic I use for a variety of things in our manifests. YMMV.