puppet adding array elements in a loop
Asked Answered
B

2

5

I want something like this:

$ssl_domains = ['dev.mydomain.com']

['admin', 'api', 'web'].each |$site| {
  ['tom', 'jeff', 'harry'].each |$developer| {
    $ssl_domains << "$site.$developer.dev.mydomain.com"
  }
}

letsencrypt::certonly { 'dev-cert':
  domains     => $ssl_domains,
  plugin      => 'apache',
  manage_cron => true,
}

now it is impossible because of Puppet's variable scoping. How can I collect some variables in an array through nested loops?

Befoul answered 8/12, 2016 at 14:13 Comment(4)
Your code has a few syntax errors. You may want to address those first.Yonah
Thanks, I deleted the semicolon. Nevertheless the problem - I think - understandable with or without a semicolon. Think this is an abstract code, and the problem is that in the loops the $ssl_domains << "$site.$developer.dev.mydomain.com" line creates and destroys the variable, not modifies the outer one.Befoul
Well also you should really consider doing ${site}.${developer}.dev.mydomain.com. Additionally, that code is going to create a $ssl_domains array with ten elements. Is that what you meant, or did you want the array to be four elements?Yonah
Matt, thanks for the braces suggestion! Yes, I meant ten elements.Befoul
Y
15

You were close with your attempt, but you were using the wrong type of lambda. To avoid the issues resulting from the two facts that Puppet variables are immutable within the same scope and also cannot be used outside of a lambda scope if defined within a lambda, you must use an rvalue lambda https://en.wikipedia.org/wiki/Value_(computer_science)#R-values_and_addresses. I solved your problem using the rvalue lambda map https://docs.puppet.com/puppet/latest/function.html#map.

$site_developer_base = ['admin', 'api', 'web'].map |$site| {
  $developer_base = ['tom', 'jeff', 'harry'].map |$developer| {
    "${site}.${developer}.dev.mydomain.com"
  }
}

If I do a notify { $site_developer_base: } this outputs:

Notice: admin.tom.dev.mydomain.com
Notice: admin.jeff.dev.mydomain.com
Notice: admin.harry.dev.mydomain.com
Notice: api.tom.dev.mydomain.com
Notice: api.jeff.dev.mydomain.com
Notice: api.harry.dev.mydomain.com
Notice: web.tom.dev.mydomain.com
Notice: web.jeff.dev.mydomain.com
Notice: web.harry.dev.mydomain.com

proving that $site_developer_base has the array that you want.

Yonah answered 8/12, 2016 at 19:47 Comment(2)
Nice use of map(). This kind of thing used to be hard in Puppet.Undertrick
Hey, now, this is the first I've seen a .map in a .map. That solves a class of problems I've been having trouble with and I haven't noticed in the Puppet docs. Pay attention people, this is good!Pentose
C
0

Might want to use flatten() with Matts solution when working with hashes instead of strings; e.g.:

$site_developer_base = flatten(
  map(['admin', 'api', 'web']) |$site| {
    $developer_base = map(['tom', 'jeff', 'harry']) |$developer| {
      { hostname => "${site}.${developer}.dev.mydomain.com" }
    }
  }
}
Cockatrice answered 9/11, 2022 at 9:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.