问题
I would like to iterate over an array that is stored as a Facter fact, and for each element of the array create a new system user and a directory, and finally make API calls to AWS.
Example of the fact: my_env => [shared1,shared2,shared3]
How can I iterate over an array in Puppet?
回答1:
This might work, depending on what you are doing
# Assuming fact my_env => [ shared1, shared2, shared3 ]
define my_resource {
file { "/var/tmp/$name":
ensure => directory,
mode => '0600',
}
user { $name:
ensure => present,
}
}
my_resource { $my_env: }
It will work if your requirements are simple, if not, Puppet makes this very hard to do. The Puppet developers have irrational prejudices against iteration based on a misunderstanding about how declarative languages work.
If this kind of resource doesn't work for you, perhaps you could give a better idea of which resource properties you are trying to set from your array?
EDIT:
With Puppet 4, this lamentable flaw was finally fixed. Current state of affairs documented here. As the documentation says, you'll find examples of the above solution in a lot of old code.
回答2:
As of puppet 3.2 this is possible using the "future" parser like so:
$my_env = [ 'shared1', 'shared2', 'shared3', ]
each($my_env) |$value| {
file { "/var/tmp/$value":
ensure => directory,
mode => 0600,
}
user { $value:
ensure -> present,
}
}
See also: http://docs.puppetlabs.com/puppet/3/reference/lang_experimental_3_2.html#background-the-puppet-future-parser
回答3:
Puppet 3.7 released earlier this month have the new DSL, which one feature is the iteration, check the following URL https://docs.puppetlabs.com/puppet/latest/reference/experiments_lambdas.html#enabling-lambdas-and-iteration
these new features can be enabled with the :
Setting parser = future in your puppet.conf file or adding the command line switch --parser=future
hope that helps
回答4:
itsbruce's answer is probably the best for now, but there is an iteration proposal going through puppetlabs' armatures process for possible implementation in future.
回答5:
There is a "create_resources()" function in puppet. that will be very helpful while iterating over the list of itmes
回答6:
As of latest Puppet (6.4.2), and since Puppet 4, iteration over arrays is supported in a few ways:
$my_arr = ['foo', 'bar', 'baz']
Each function:
$my_arr.each |$v| {
notice($v)
}
Each function alternative syntax:
each($my_arr) |$v| {
notice($v)
}
To get the index:
Pass a second argument to each
:
$my_arr.each |$i, $v| {
notice("Index: $i, value: $v")
}
Comparison with Ruby:
Note that this grammar is inspired by Ruby but slightly different, and it's useful to show the two side by side to avoid confusion. Ruby would allow:
my_arr.each do |v|
notice(v)
end
Or:
my_arr.each { |v|
notice(v)
}
Other iteration functions:
Note that Puppet provides a number of other iteration functions:
each - Repeats a block of code a number of times, using a collection of values to provide different parameters each time.
slice - Repeats a block of code a number of times, using groups of values from a collection as parameters.
filter - Uses a block of code to transform a data structure by removing non-matching elements.
map - Uses a block of code to transform every value in a data structure.
reduce - Uses a block of code to create a new value, or data structure, by combining values from a provided data structure.
with - Evaluates a block of code once, isolating it in its own local scope. It doesn’t iterate, but has a family resemblance to the iteration functions.
Puppet 3 and earlier:
If you have inherited old code still using Puppet 3, the accepted answer is still correct:
define my_type {
notice($name)
}
my_type { $my_arr: }
Note however that this is usually considered bad style in modern Puppet.
来源:https://stackoverflow.com/questions/12958114/how-to-iterate-over-an-array-in-puppet