Ask Your Question

How to set a default value for a defined type where the variable is an array of hashes?

asked 2016-12-19 14:04:24 -0500

bschonecker gravatar image

updated 2016-12-19 14:59:09 -0500

I have about 50 apache::vhost defines that need some 'refactoring'. I'm trying to set the resource to some default values but I'm having trouble because 'directories' is an array of hashes.

For example:

# set the apache::vhost define type defaults here
Apache::Vhost {
  # What's the correct way to set this since it's an array of hashes?
  directories => { 'options'  => ["Indexes","Symlinks","Somethingelse",],},

I'm trying to set apache::vhost::directories OPTIONS section to a default so that I don't have to type it out 50 times in my YAML file:

    servername: "cache.%{::fqdn}"
      - path: '/web/cache'
        allow_override: 'None'
        order: 'deny,allow'
        deny: 'from ALL'
        allow: "from"

Unfortunately, I'm at a loss as to the syntax to ensure that directories=>options is set to the (3 element) array I need.

I'm thinking that the "full path" to options is:


but that is even more confusing...

edit retag flag offensive close merge delete

2 Answers

Sort by » oldest newest most voted

answered 2016-12-19 18:57:15 -0500

If you write, directories is an array of hashes, why don't you specify an array to the directories parameter?

Apache::Vhost {
  directories => [
      'options' => ['Indexes', 'Symlinks', 'Somethingelse'],

However, this won't work. The whole point of default values is, that they are taken, if you haven't specified any value for the particular parameter at all. You'd like to specify

apache::vhost { 'foobar':
  directories => [
      'path' => '/web/cache',

and get the options automatically filled in (because it wasn't specified next to /web/cache). That won't work, since the default parameter value is ignored, since the directories parameter was specified.

For this writing a wrapper defined type might be an approach:

define myvhost (
  Hash[Any, Any] $attrs = undef,
) {
  $_adjusted_attrs = Hash($ |$key, $value| {
    if $key == 'directories' {
      $v = $ |$x| { # take each hash in the array
        # right hand "options" value takes precedence
        { 'options' => ['Indexes', 'Symlinks'] } + $x
      [$key, $v]
    } else {
      [$key, $value]

  apache::vhost { $title:
    * => $_adjusted_attrs,

No claim that that's correct. I haven't tested it. about merging; about splat; about iteration at all

edit flag offensive delete link more


I would recommend either a merge/deep merge type of behavior as well.

DarylW gravatar imageDarylW ( 2016-12-20 09:52:54 -0500 )edit

answered 2016-12-19 14:54:48 -0500

lupin gravatar image
     - Indexes
     - Symlinks
     - SomethingElse

Is that what you're after?

edit flag offensive delete link more


No, I'm trying to set the defined type default for ..directories=>options via a manifest.

bschonecker gravatar imagebschonecker ( 2016-12-19 14:58:17 -0500 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower


Asked: 2016-12-19 14:04:24 -0500

Seen: 42 times

Last updated: Dec 19 '16