1

I want to inject some values from facter <prop> into a file content.

It works with $fqdn since facter fqdn returns string.

node default {
  file {'/tmp/README.md':
    ensure  => file,
    content => $fqdn, # $(facter fqdn)
    owner   => 'root',
  }

}

However, it does not work with hash object (facter os):

   node default {
      file {'/tmp/README.md':
        ensure  => file,
        content => $os, # $(facter os) !! DOES NOT WORK
        owner   => 'root',
      }

   }

And getting this error message when running puppet agent -t:

Error: Failed to apply catalog: Parameter content failed on File[/tmp/README.md]: Munging failed for value {"architecture"=>"x86_64", "family"=>"RedHat", "hardware"=>"x86_64", "name"=>"CentOS", "release"=>{"full"=>"7.4.1708", "major"=>"7", "minor"=>"4"}, "selinux"=>{"config_mode"=>"enforcing", "config_policy"=>"targeted", "current_mode"=>"enforcing", "enabled"=>true, "enforced"=>true, "policy_version"=>"28"}} in class content: no implicit conversion of Hash into String (file: /etc/puppetlabs/code/environments/production/manifests/site.pp, line: 2)

How to convert the hash to string inside the pp file?

Abdennour TOUMI
  • 87,526
  • 38
  • 249
  • 254
  • Possible duplicate of [How do I turn a hash to a string in Puppet DSL?](https://stackoverflow.com/questions/28729033/how-do-i-turn-a-hash-to-a-string-in-puppet-dsl) – l0b0 Jun 13 '18 at 04:10
  • 1
    It's not a duplicate of the linked issue. I will provide an answer shortly. – Alex Harvey Jun 13 '18 at 05:17

1 Answers1

2

If you have Puppet >= 4.5.0, it is now possible to natively convert various data types to strings in the manifests (i.e. in the pp files). The conversion functions are documented here.

This would do what you want:

file { '/tmp/README.md':
  ensure  => file,
  content => String($os),
}

or better:

file { '/tmp/README.md':
  ensure  => file,
  content => String($facts['os']),
}

On my Mac OS X, that leads to a file with:

{'name' => 'Darwin', 'family' => 'Darwin', 'release' => {'major' => '14', 'minor' => '5', 'full' => '14.5.0'}}

Have a look at all that documentation, because there are quite a lot of options that might be useful to you.

Of course, if you wanted the keys inside the $os fact,

file { '/tmp/README.md':
  ensure  => file,
  content => $facts['os']['family'],
}

Now, if you don't have the latest Puppet, and you don't have the string conversion functions, the old way of doing this would be via templates and embedded Ruby (ERB), e.g.

$os_str = inline_template("<%= @os.to_s %>")
file { '/tmp/README.md':
  ensure => file,
  content => $os_str,
}

This actually leads to a slightly differently-formatted Hash since Ruby, not Puppet does the formatting:

{"name"=>"Darwin", "family"=>"Darwin", "release"=>{"major"=>"14", "minor"=>"5", "full"=>"14.5.0"}}
Alex Harvey
  • 14,494
  • 5
  • 61
  • 97