How to Properly Set PATH Environment When Applying a Single Puppet Module in Isolation


2 views

When executing Puppet in a full agent run, the environment typically inherits system PATH settings. However, running individual modules through puppet apply often reveals PATH-related issues because:

  • The execution context changes to a more restricted environment
  • Module resources may assume standard PATH locations
  • Command dependencies aren't automatically resolved

The error Parameter unless failed: '[ -e \"${logfile}\" ]' is not qualified and no path was specified indicates Puppet cannot locate shell commands because:

1. The shell binary path isn't set
2. The execution environment lacks standard PATH variables
3. Resource declarations didn't specify absolute paths

1. Set PATH in Puppet Code

Modify your manifest to explicitly set PATH:

Exec {
  path => [
    '/usr/local/bin',
    '/usr/bin',
    '/bin',
    '/sbin',
    '/usr/sbin'
  ],
  environment => ["PATH=/usr/local/bin:/usr/bin:/bin"]
}

include myclass

2. Pass Environment Variables to puppet apply

Include PATH in your execution command:

PATH=/usr/local/bin:/usr/bin:/bin \
puppet apply --verbose --modulepath=moduleshere \
  --environment=production \
  --environmentpath=envpath \
  -e 'include myclass'

3. Configure Environment in Hiera

For more complex cases, configure through Hiera:

# common.yaml
exec_paths:
  - '/usr/local/bin'
  - '/usr/bin'
  - '/bin'

# manifest.pp
$exec_paths = lookup('exec_paths', Array[String], 'unique')
Exec { path => $exec_paths }
  • Always test modules with --noop first
  • Use absolute paths in resource declarations
  • Consider using the which function to verify command availability
  • For complex modules, create a dedicated test environment

Here's a production-ready command that handles PATH issues:

FACTER_environment=test PATH=/usr/bin:/bin \
puppet apply --modulepath=$(pwd)/modules:$(pwd)/site \
  --hiera_config=$(pwd)/hiera.yaml \
  --detailed-exitcodes \
  --environment=ci \
  --trace \
  -e 'include myclass::test'

When running Puppet in apply mode with a single module, you might encounter PATH-related errors like:

Parameter unless failed: '[ -e \"${logfile}\" ]' is not qualified and no path was specified.
Please qualify the command or specify a path.

This occurs because the Puppet agent normally inherits the system PATH during full runs, but this context is missing when applying individual modules.

1. Set PATH in the Puppet Manifest

Modify your module's init.pp to explicitly set the PATH:

class myclass {
  Exec {
    path => ['/usr/local/bin', '/usr/bin', '/bin'],
  }
  
  # Your resources here
}

2. Environment Variable Injection

Pass PATH through the command line:

PATH=/usr/local/bin:/usr/bin:/bin puppet apply \
--modulepath=moduleshere \
-e 'include myclass'

3. Wrapper Script Approach

Create a wrapper script that sets the environment:

#!/bin/bash
export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
puppet apply --modulepath=moduleshere -e "include $1"

To verify PATH resolution, add debug output:

exec { 'debug-path':
  command => 'echo $PATH > /tmp/puppet_path.log',
  path    => ['/bin', '/usr/bin'],
}
  • Always qualify commands in Exec resources
  • Set default PATH at the node or class level
  • Consider using absolute paths for critical operations

Here's a full module example with proper PATH handling:

class sample_module {
  Exec {
    path => ['/usr/local/bin', '/usr/bin', '/bin'],
  }
  
  file { '/tmp/sample_file':
    ensure  => present,
    content => "PATH was: ${::path}\n",
  }
  
  exec { 'sample_command':
    command => 'touch /tmp/puppet_test_file',
    unless  => 'test -e /tmp/puppet_test_file',
  }
}

Apply it with:

puppet apply --modulepath=modules -e 'include sample_module'