Search code examples
puppet

Check Puppet module files source exists before copy


I'm using Puppet for certificates transfer from Puppet Server to Windows node. Puppet Server has a folder where new certificates are being copied from my CA (another server). So, sometimes Puppet may not find a certificate (it wasn't transferred from CA to source directory) for node and that's why I need an additional check for certificate presence in source folder. The code must check hostname, find an appropriate certificate and transfer it to node. How can I make it check certificate presence in module files directory (puppet:///modules/modulename/) before I try to copy it?

file { "D:\$hostname.pfx":
    ensure => present,
    source => all,   
exec { 'Import certificate':
    command  => "if((Get-ChildItem -Path Cert:\LocalMachine\My\ | ? {$_.Issuer -like "*CN=example*"}).HasPrivateKey | select-string -pattern "True") -or ()\
                {\$pwd = ConvertTo-SecureString -String "Password" -Force –AsPlainText; Import-PfxCertificate –FilePath ${cert_path}\$hostname.pfx cert:\localMachine\my -Password \$pwd}",
    path     => $::path,
    onlyif   => "Test-Path ${cert_path}\${hostname}.pfx",
    provider => 'powershell',
  }

Solution

  • How can I make it check certificate presence in module files directory (puppet:///modules/modulename/) before I try to copy it?

    You could write a custom function that checks for a file in the module directory, and use it to enable or suppress the declarations of the File and Exec resources. The manifest using that function might look something like this:

    if module_file_exists("${hostname}.pfx") {
      file { "D:\$hostname.pfx":
        # ...
      }
      -->
      exec { 'Import certificate':
        # ...
      }
    }
    

    Or a quick and dirty way of doing the same thing would be to implement it via Ruby scriptlet code in an ERB template, which you run via inline_template() (or template()).

    Or a somewhat more esoteric way of approaching the problem would be to write a custom Hiera back-end that provides information about the local (to the catalog compiler) filesystem, and to access it via the hiera() function.

    BUT, have you considered not making anything conditional, and instead simply letting application of the resource fail in the event that the certificate file is not available? If in fact you care whether the certificate is installed, then a resource-application failure provides important information to you. I presume that you do care, for if you didn't then it would be easier all around simply to not bother with the certificate at all.