54

Here is my naive approach:

# puppet/init.pp
$x = 'hello ' + 
     'goodbye'

This does not work. How does one concatenate strings in Puppet?

rlandster
  • 6,310
  • 12
  • 50
  • 76
  • 2
    I did not ask exactly the right question. What I should have asked is, is there a string concatenation operator in the Puppet DSL? It appears there is currently no such thing: http://projects.puppetlabs.com/issues/15330 – rlandster Feb 17 '13 at 16:46

6 Answers6

74

Keyword variable interpolation:

$value = "${one}${two}"

Source: http://docs.puppetlabs.com/puppet/4.3/reference/lang_variables.html#interpolation

Note that although it might work without the curly braces, you should always use them.

Linkid
  • 427
  • 5
  • 17
czervik
  • 2,485
  • 20
  • 15
  • Also not that this will only work in a variable assignment as demonstrated above. If you want to use it in a puppet rule after `=>` first assign it to a variable, then use the variable after `=>`. – Tully Dec 01 '14 at 23:01
  • Should work fine after a `=>`, Tully. What version of Puppet are you using? – Nick Mar 02 '15 at 14:40
  • 2
    This is an alternative to concatenation, but not an answer to the question as posed. If the OP's need is satisfied, that's useful, but there's many cases where this will not do, at least without intermediary steps. E.g. if you are trying to avoid assigning a thousand character long string in puppet code with the whole thing on one line, or if one of the things you are concatenating is the output of a function call. – mc0e Dec 01 '16 at 09:05
24

I use the construct where I put the values into an array an then 'join' them. In this example my input is an array and after those have been joined with the ':2181,' the resulting value is again put into an array that is joined with an empty string as separator.

$zookeeperservers = [ 'node1.example.com', 'node2.example.com', 'node3.example.com' ]
$mesosZK = join([ "zk://" , join($zookeeperservers,':2181,') ,":2181/mesos" ],'')

resulting value of $mesosZK

zk://node1.example.com:2181,node2.example.com:2181,node3.example.com:2181/mesos
Niels Basjes
  • 9,714
  • 8
  • 45
  • 60
  • 3
    This uses the puppetlabs-stdlib module's [join](https://github.com/puppetlabs/puppetlabs-stdlib#join) function, for those wondering. – MrAlias Jun 16 '15 at 22:09
  • Or the internal function (https://puppet.com/docs/puppet/5.5/function.html#join), as of Puppet 5.5. – GargantuChet Aug 28 '18 at 17:05
19

Another option not mentioned in other answers is using Puppet's sprintf() function, which functions identically to the Ruby function behind it. An example:

$x = sprintf('hello user %s', 'CoolUser')

Verified to work perfectly with puppet. As mentioned by chutz, this approach can also help you concatenate the output of functions.

Mifeet
  • 10,908
  • 3
  • 50
  • 92
  • 3
    This way it is possible to concatenate the output of functions - something not so easy with other answers. E.g. `$x = sprintf('%s/%s', dirname($file), $anotherfile)` – chutz Nov 27 '15 at 02:23
2

The following worked for me.

puppet apply -e ' $y = "Hello" $z = "world" $x = "$y $z" notify { "$x": } '
notice: Hello world
notice: /Stage[main]//Notify[Hello world]/message: defined 'message' as 'Hello world'
notice: Finished catalog run in 0.04 seconds

The following works as well:

$abc = "def"

file { "/tmp/$abc":
Albert Turri
  • 351
  • 2
  • 9
  • 3
    Unfortunately, this doesn't work when one of the terms is an expression. *E.g.*, `$foo = regsubst($bar, '/', '-', 'G') + $version` – RoUS Mar 27 '13 at 14:57
  • You can put the output of the expression into another intermediary variable first. i.e. `$temp=regsubst($bar, '/', '-', 'G')` and then `$foo = "${temp}${version}"` – mc0e Mar 27 '15 at 04:35
0

You could use the join() function from puppetlabs-stdlib. I was thinking there should be a string concat function there, but I don't see it. It'd be easy to write one.

mc0e
  • 2,343
  • 23
  • 25
0

As stated in docs, you can just use ${varname} interpolation. And that works with function calls as well:

$mesosZK = "zk://${join($zookeeperservers,':2181,')}:2181/mesos"
$x = "${dirname($file)}/anotherfile"

Could not use {} with function arguments though: got Syntax error at '}'.

Andrey Regentov
  • 3,499
  • 3
  • 27
  • 39