Ask Your Question

How to execute a linux command and assign the value to a variable in Puppet?

asked 2014-08-08 03:08:25 -0600

Vinod gravatar image

I have a specific requirement to download the latest object from an AWS S3 bucket to the puppet master fileserver.

I want to find the name of the latest object in a particular s3 bucket and assign it to a variable. How can I use generate function in puppet to assign the value to a variable.

Eg: filename=s3cmd ls s3://bucketname | grep s3://bucketname/objectname* | sort -r | head -1 | awk '{print $4}'

edit retag flag offensive close merge delete


I tried it like this $filename = generate(s3cmd ls s3://bucketname | grep s3://bucketname/objectname* | sort -r | head -1 | awk '{print $4}') . But I am getting a syntax error saying that } is expected at this line number.

Vinod gravatar imageVinod ( 2014-08-08 03:10:30 -0600 )edit

Where can I find enough documentations about generate function in puppet.

Vinod gravatar imageVinod ( 2014-08-08 03:10:50 -0600 )edit

As mentioned, you cannot use pipes or redirection. You must put your commands in a script and run generate on that instead.

lavaman gravatar imagelavaman ( 2014-08-08 16:20:56 -0600 )edit

3 Answers

Sort by ยป oldest newest most voted

answered 2014-08-12 11:38:43 -0600

timelord gravatar image

Just an idea ... create a custom facter in your module, for example:

require 'facter'

# Default for non-Linux nodes
Facter.add(:my_script_value) do
    setcode do

# Linux
Facter.add(:my_script_value) do
    confine :kernel  => :linux
    setcode do
        Facter::Util::Resolution.exec("s3cmd ls s3://bucketname | grep s3://bucketname/objectname* | sort -r | head -1 | awk '{print $4}'")

Then in your Puppet manifest you can use the facter like in this example:

$filename = $::my_script_value

Or, you can also test a return value for nil

if $::my_script_value != nil {
   $filename = $::my_script_value
edit flag offensive delete link more

answered 2014-08-08 16:21:12 -0600

spuder gravatar image

updated 2014-08-08 16:25:43 -0600

Several Ways to do this:

Environment Variables

If you create an environment variable that starts with a capital FACTER_ it will be available to the child shell processes

$ export FACTER_HERP='derp'

Then inside the puppet manifest, you could call the fact


Here is an example

$ export FACTER_HERP='derp'
$ puppet apply  -e "class foo { fail(\"herp is \'${::herp}\'\") } include foo" --debug
Info: Loading facts in /etc/puppet/modules/gitlab/lib/facter/hostname_aliases.rb
Info: Loading facts in /etc/puppet/modules/gitlab/lib/facter/operatingsystem_lowercase.rb
Error: herp is 'derp' at line 1 on node
Error: herp is 'derp' at line 1 on node

Or the same example again, but more human friendly

    class foo { 
       fail( "herp is ${::herp}") 
    include foo

Custom Facts

You can write your own fact in ruby then put it in the lib directory

Here is an example:

edit flag offensive delete link more

answered 2014-08-08 15:49:22 -0600

Stefan gravatar image

The generate function executes a command and will return the output. As all functions the generate function runs on the master, so your program will also execute on the puppet master.

You have to provide a full qualified executable to the function (as a string; so use quotes) and possible arguments. You cannot run shell specifics (like pipes, output redirectons, etc)


generate("/bin/echo", "-n", "Hallo Welt")

so if your command is more complicated, you either have to write a custom function or write a small shell script to execute the desired command and then call that shell script with generate. But be also aware that the puppet master (where the command will be executed) most likely runs as user puppet and not as root.

edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower


Asked: 2014-08-08 03:08:25 -0600

Seen: 17,176 times

Last updated: Aug 12 '14