Search code examples
puppet

Using a counter while iterate via each block in puppet manifest


I have a array named $applist. The values are used to generate cron entries like this

$minute = 0
$applist.each |$application| {

    $minute = $minute + 2
    # notify{"Setting clear_logs for ${application}":}
    # generate clear log entries
    cron {"clear-logs_${application}":
        command => "mk-job clear-logs_${application} /root/scripts/clear_logs.py -l 60 -d ${application}/logs -v -n >/dev/null 2>&1",
        user    => root,
        hour    => "3",
        minute  => "${minute}",
    }
}

Minute is not increased by 2 in my iteration steps. I am pretty sure it is related to lamdas but I have no Idea how to solve this dilemma


Solution

  • It's a good question and the above is the correct solution.

    I would add that the problem here is that variables in Puppet cannot be reassigned: ref.

    Ordinarily, if you had code like the following -

    $c = 0
    $c = $c + 1
    

    You would receive an Evaluation Error:

    Error: Evaluation Error: Cannot reassign variable '$c' (file: /tmp/foo.pp, line: 2, column: 4) on node alexs-macbook-pro.local
    

    It is often noted that Puppet's variables therefore aren't "variable" ; they are immutable.

    Even more confusingly, this behaviour changes inside an iterator block. Consider this code more similar to the sample from the question:

    $c = 0
    [1, 2, 3].each |$x| {
      $c = $c + 1
      notice($c)
    }
    

    Now the code compiles fine, but Puppet still can't reassign the variable $c:

    $ puppet apply /tmp/foo.pp
    Notice: Scope(Class[main]): 1
    Notice: Scope(Class[main]): 1
    Notice: Scope(Class[main]): 1
    

    The best thing to do here is as is shown in the OP's answer to their question, and use each with an index (analogous to Ruby's each_with_index but with a slightly different grammar): ref.

    Consider:

    $c = 0
    [1, 2, 3].each |$i, $x| {
      notice("Index is $i, x is $x")
    }
    

    Now we get:

    Notice: Scope(Class[main]): Index is 0, x is 1
    Notice: Scope(Class[main]): Index is 1, x is 2
    Notice: Scope(Class[main]): Index is 2, x is 3