I have a step in a Puppet module that roughly does the following to set up some application keys:

file { '/root/setup_app_keys.sh':
  ensure => file,
  owner  => 'root',
  group  => 'root',
  mode   => '0700',
  source => 'puppet:///modules/app_module/setup_app_keys.sh',

exec { 'setup_app_keys':
  unless  => '/etc/pki/tls/private/app-foo.key',
  command => '/root/setup_app_keys.sh',
  user    => 'root',
  group   => 'root',

The setup_app_keys.sh script is a little too long to be made into a (readable) one-liner, so I save it to the machine's filesystem and execute it from there. It creates its files in /etc/pki... and it works well enough.

The annoying thing is, the shell script is basically a one-time use thing. It shouldn't ever run again for the lifetime of the machine, and yet it must stay on the filesystem where Puppet stored it. If it is deleted, Puppet helpfully recreates it again.

I'm thinking there must be a way to rewrite this using exec exclusively, which will allow me to download the script from the puppetmaster when needed, execute it once, then discard the script (or not store it in the first place). But everything I've tried has been of the form:

command => 'puppet:///modules/app_module/setup_app_keys.sh',


command => 'curl http://__[various puppetmaster URLs]__ | sh',

and neither approach seems to work. Am I asking too much, or is this approach flawed?

  • 2
    for that i think is better you use ansible or mcollective – c4f4t0r Jan 19 '15 at 15:08
  • @c4f4t0r Please post this as an answer – 030 Feb 13 '15 at 18:06

You can try and put your file in a transitional state of existence prior to execution. The final state would be

ensure => absent

This is cutting age material at the time of writing. Your mileage may vary.

| improve this answer | |

you can add in your 'exec'

require => File["/root/setup_app_keys.sh"],
refreshonly => true,

so it will only run again if you change the script

or you can add in your 'file', after last run

ensure  => purged,
| improve this answer | |

for that i think is better you use ansible or mcollective, for this kind of thing, i use ansible.

For more information about it.

| improve this answer | |

You can run command from template:

exec { 'my-command':
     command     => template('template-for-my-command.erb')
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.