puppeterbfacter

How to use Facter values in Ruby template with Puppet


I am trying to figure out how I can use Facter facts inside a Ruby template erb file configured with Puppet.

Sample Ruby template variable

zk.l.conn=

Expected config file output from Puppet

zk.l.conn=ip-xx-31-xx-xxx.ec2.internal:2181,ip-xxx-31-xx- xxx.ec2.internal:2181,ip-172-xxx-xxx-xx.ec2.internal:2181

Facter fact data:

"zk-internal": [
  {
    "host": "ip-xx-31-xx-xxx.ec2.internal",
    "port": 2181,
    "priority": 2,
    "weight": 10
  },
  {
    "host": "ip-xxx-31-xx-xxx.ec2.internal",
    "port": 2181,
    "priority": 3,
    "weight": 10
  },
  {
    "host": "ip-172-xxx-xxx-xx.ec2.internal",
    "port": 2181,
    "priority": 1,
    "weight": 10
  }
],

Solution

  • In short:

    zk.1.conn=<%= @facts['zk-internal'].map { |h| "#{h['host']}:#{h['port']}" }.join(',') %>
    

    @facts['zk-internal'] lets you access the structured fact value, used because @zk-internal wouldn't be a valid variable name due to the hyphen.

    .map { |h| "#{h['host']}:#{h['port']}" } iterates over every element and returns new strings containing "host:port" from each element, so you have an array of hosts/ports returned.

    .join(',') returns a string from the array with each element comma-separated.

    This outputs:

    zk.1.conn=ip-xx-31-xx-xxx.ec2.internal:2181,ip-xxx-31-xx-xxx.ec2.internal:2181,ip-172-xxx-xxx-xx.ec2.internal:2181
    

    (Tested on Puppet 4.7)