Interpolate and concatenate Puppet variable inside nested string quotes

I am creating a Puppet configuration file for a service. I would like to add the hostname as a variable in the line. However, it got an error because of nested quotation marks (") in the line.

$hostlocal = "${hostname}"

file {'puppet_facts_example':
  ensure  => file,
  path    => '/tmp/test.txt',
  content => "modparam("topology_hiding", "th_callid_prefix", "$hostlocal_")"
}

If I just print $hostlocal, it shows the hostname correctly. Is there any way to use a Puppet variable inside nested string quotes (")?

I also tried to use template. In the template,

modparam("topology_hiding", "th_callid_prefix", "<$= @hostlocal %>_")"

But the result was no value.

modparam("topology_hiding", "th_callid_prefix", "_")"

2 answers

  • answered 2017-01-11 14:24 k0chan

    In my opinion hostname is a variable so you don't need double quotation mark because you want to get value of variable.

    Try

    $hostlocal = $hostname
    

  • answered 2017-01-11 14:24 Matt Schuchard

    The basic problem here is that you need to escape nested string quotes when you are doing string interpolation/escape style quotes ("). Also, you are attempting to concatenate _ onto $hostlocal, but Puppet is interpreting that as a variable $hostlocal_, so you need curly braces to establish concatenation. You can fix your problem with:

    $hostlocal = "${hostname}"
    
    file {'puppet_facts_example':
      ensure  => file,
      path    => '/tmp/test.txt',
      content => "modparam(\"topology_hiding\", \"th_callid_prefix\", \"${hostlocal}_\")"
    }
    

    However, we can improve on this further. The first couple of things we can do here is remove the quotes around ${hostname} since it is not being interpolated. The same goes for topology_hiding and th_callid_prefix, except we must change them to single literal string quotes since nothing is being interpolated or escaped. Also, if you are doing Facter 2 style lookups on facts, then it is better style to establish the fact as a global variable with $::.

    $hostlocal = $::hostname
    
    file {'puppet_facts_example':
      ensure  => file,
      path    => '/tmp/test.txt',
      content => "modparam('topology_hiding', 'th_callid_prefix', \"${hostlocal}_\")"
    }
    

    Finally, note that the use of the $hostlocal variable is redundant with the fact, so it can be safely removed for clarity and efficiency. This yields the optimal solution below.

    file {'puppet_facts_example':
      ensure  => file,
      path    => '/tmp/test.txt',
      content => "modparam('topology_hiding', 'th_callid_prefix', \"${::hostname}_\")"
    }