Search code examples
rubypuppeterb

Iterating over a flexible range in ERB


I've got a Puppet ERB template on version 3.8.1 which is throwing an error and refusing to work.

Here's my original code:

<%= (1..5).select{ |i| "elastic%d" %[i] != @hostname }.map{|x, i| "elastic%d" %[x]} %>

This creates an array of host names excluding the current host's hostname.

I'm trying to parameterize my template so it can scale things nicely depending on the amount of servers I have in my cluster:

<%= (1..@(scope.lookupvar('mymodule::elastic_instances'))).select{ |i| "elastic%d" %[i] != @hostname }.map{|x, i| "elastic%d" %[x]} %>

This throws the following exception:

Error: Could not run: /home/tk/puppet/modules/mymodule/templates/elasticsearch/elasticsearch-template.conf.erb:329: `@(' is not allowed as an instance variable name
/home/tk/puppet/modules/mymodule/templates/elasticsearch/elasticsearch-template.conf.erb:329: syntax error, unexpected end-of-input
; _erbout.concat(( (1..@(scope.lookupvar('mymodule...

I've also tried the following alternatives:

<%= (1..@(scope.lookupvar('mymodule::elastic_instances'))).select{ |i| "elastic%d" %[i] != @hostname }.map{|x, i| "elastic%d" %[x]} %>
<%= (1..(scope.lookupvar('mymodule::elastic_instances'))).select{ |i| "elastic%d" %[i] != @hostname }.map{|x, i| "elastic%d" %[x]} %>
<%= (1..scope.lookupvar('mymodule::elastic_instances')).select{ |i| "elastic%d" %[i] != @hostname }.map{|x, i| "elastic%d" %[x]} %>

Is there a manual method I can call which will work in place of Ruby's syntactic sugar?


Solution

  • It turns out that the variable as being returned by Puppet was a string rather than an int, though I declared it as an int in Puppet.

    With a cast and some manual stuff, I got it working:

    <%= (Range.new(1, Integer(scope.lookupvar('mymodule::elastic_instances'))) ... %>
    

    That got things working as expected.