FAQ
Hi all,
With the goal of making my code a little more DRY, I am trying to define
resource parameters in an array of hashes, and then create defined
resources from these array items. I am having trouble figuring out the
syntax for accessing the hash values for the hash currently being worked on
("self?").

Here's the code to make it clear:

##### Configuration arguments

$sites = [{
     sitedomain => 'site1.domain.dev',
     repo => 'git@repo.address/Repo',
     branch => 'develop',
     serveralias => "",
     priority => '010'
   },{
     sitedomain => 'site2.domain.dev',
     repo => 'git@repo.address/Repo',
     branch => 'develop',
     serveralias => "",
     priority => '020'
   },]

#### Deploy configuration

apache::vhost { $sites :
   priority => ${????}[priority],
   sitedomain => ${????}[sitedomain],
   serveralias => ${????}[serveralias],
}
git::clone { $sites :
   repo => ${????}[repo],
   branch => ${????}[branch],
}

How do I access the hash values for the current hash? (trouble spots marked
with "????").

I've experimented a lot while reading documentation and these forums, but
didn't get anywhere. I tried assigning each hash to a variable, but I still
can't get at that variable's name from within resource definition.

Is what i'm trying to do even possible? Or am I stuck copying and pasting
the roughly identical block of code for every site that needs to be present
on the server?

Thank you in advance for any insight.

--
You received this message because you are subscribed to the Google Groups "Puppet Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscribe@googlegroups.com.
To post to this group, send email to puppet-users@googlegroups.com.
Visit this group at http://groups.google.com/group/puppet-users?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.

Search Discussions

  • Jcbollinger at May 13, 2013 at 8:42 pm

    On Monday, May 13, 2013 11:26:21 AM UTC-5, Eugene Brodsky wrote:
    Hi all,
    With the goal of making my code a little more DRY, I am trying to define
    resource parameters in an array of hashes, and then create defined
    resources from these array items. I am having trouble figuring out the
    syntax for accessing the hash values for the hash currently being worked on
    ("self?").

    Here's the code to make it clear:

    ##### Configuration arguments

    $sites = [{
    sitedomain => 'site1.domain.dev',
    repo => 'git@repo.address/Repo',
    branch => 'develop',
    serveralias => "",
    priority => '010'
    },{
    sitedomain => 'site2.domain.dev',
    repo => 'git@repo.address/Repo',
    branch => 'develop',
    serveralias => "",
    priority => '020'
    },]

    #### Deploy configuration

    apache::vhost { $sites :
    priority => ${????}[priority],
    sitedomain => ${????}[sitedomain],
    serveralias => ${????}[serveralias],
    }
    git::clone { $sites :
    repo => ${????}[repo],
    branch => ${????}[branch],
    }

    How do I access the hash values for the current hash? (trouble spots
    marked with "????").

    I've experimented a lot while reading documentation and these forums, but
    didn't get anywhere. I tried assigning each hash to a variable, but I still
    can't get at that variable's name from within resource definition.

    Is what i'm trying to do even possible? Or am I stuck copying and pasting
    the roughly identical block of code for every site that needs to be present
    on the server?

    Thank you in advance for any insight.

    The specific approach you are attempting will not work, but there are
    variations that will.

    First off, the title of a resource is always a string. Not a hash, not an
    array, but a string. Puppet DSL provides a shortcut for declaring multiple
    resources (native or defined-type) having the same parameters, by writing a
    single resource declaration where the (string) titles are given as an array
    literal or an array-valued variable. The result is exactly equivalent to
    multiple resource declarations, one for each given title, each with the
    specified parameters. That shortcut does not generalize. It never makes
    sense to specify a hash as a resource title, nor an array containing any
    non-string values.

    Moreover, all elements of a resource declaration itself are evaluated in
    the context in which the declaration appears. That applies here in that
    inside your resource *declarations*, there cannot be a sense of a 'current'
    element of a composite title. That sort of thing has to go into the *
    implementation* of the resource type (where the 'current' element is just
    the plain resource title of one of several similar resources). Again:
    titles are always strings.

    Back to the question of how you achieve what you're after. There are at
    least two relatively straightforward ways, both requiring a slightly
    different form for your data. Instead of an array of hashes, you need a
    hash of hashes, with the keys of the outer hash being identifying strings
    suitable for use as resource titles or parts of them. The inner hashes can
    be similar or perhaps the same as the parameter hashes you have now. For
    example:

    $sites = {
       'site1' => {
         sitedomain => 'site1.domain.dev',
         repo => 'git@repo.address/Repo',
         branch => 'develop',
         serveralias => "",
         priority => '010'
       },
       ...
    }


    Having your data in that general form, you have two basic alternatives:

        1. Use the built-in create_resources() function
        2. Create a defined type that performs a similar function

    If, as in your case, your inner hashes combine parameters for resources of
    different types, option (1) would require a defined-type wrapper to use as
    the resource type passed to create_resources(), so that doesn't end up
    being any simpler. You should read docs for that function, but there isn't
    really much more to say. I will illustrate the alternative, however.

    The defined type you need for option (2) is a bit different from the one
    you would need for option (1). In this case, the defined type needs only
    one parameter, that being the hash of hashes:

    define mymodule::site($sites) {
       include 'apache' # if necessary
       include 'git' # if necessary

       # Select the inner hash for this site from
       # the hash of hashes, using this resource's
       # title as the key:
       $site_data = $sites[$title]

       # Declare resources

       apache::vhost { "${title}-vhost" :
         priority => $site_data['priority'],
         sitedomain => $site_data['sitedomain'],
         serveralias => $site_data['serveralias'],
       }

       git::clone { "${title}-git" :
         repo => $site_data['repo'],
         branch => $site_data['branch'],
       }
    }

    You use then that defined type like so:

    class somemodule::someclass {
       $site_names = <see below>
       mymodule::sites { $keys: sites => $sites }
    }

    The last bit is how to get the site names. It may be the case that which
    sites to declare is a separate question from which sites' parameters are
    recorded in the $sites hash, in which case you'll have to determine for
    yourself how to get a suitable array of site names (each being one of the
    keys of the $sites hash).

    If you just want to declare them all, however, then PuppetLabs's add-in
    'stdlib' module provides a keys() function that will return an array of the
    keys of a hash, which is just what you want for this purpose. Or you can
    roll your own; by itself, a keys() function is not very hard.

    $site_names = keys(sites)


    John

    --
    You received this message because you are subscribed to the Google Groups "Puppet Users" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscribe@googlegroups.com.
    To post to this group, send email to puppet-users@googlegroups.com.
    Visit this group at http://groups.google.com/group/puppet-users?hl=en.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Eugene Brodsky at May 14, 2013 at 6:08 pm
    John, thank you so much for such a detailed and thoughtful response!! I was
    definitely confused about resource titles' data type, and I think variable
    scope too. Also I made an incorrect assumption that providing a hash as a
    resource title will somehow expand its values for use within the
    declaration. Thanks for making these concepts clear.

    I was already using defined types for my apache::vhost and git::clone., so
    your approach worked perfectly. This is what I ended up doing:

    ##### in site.pp:

    $sitenames = ['foo', 'bar']
    $sitedata = {
       'foo' => {
         sitedomain => 'foo.dev',
         repo => 'git@host/Foo.git',
         branch => 'develop',
         serveralias => "",
         priority => '010'
       },
       'bar' => {
         .........
       }
    }

    deployed_sites { $sitenames : sitedata => $sitedata }


    ##### in a module:

    define baz::deployed_sites ($sitedata) {

       $settings = $sitedata[$title]

       apache::vhost { $title :
         priority => $settings[priority],
         sitedomain => $settings[sitedomain],
         serveralias => $settings[serveralias],
       }
       git::clone { $title :
         repo => $settings[repo],
         branch => $settings[branch],
         sitedomain => $settings[sitedomain],
       }
    }

    Once again, thank you very much for this, and hope it helps someone else
    down the road.

    Eugene

    On Monday, May 13, 2013 4:42:42 PM UTC-4, jcbollinger wrote:


    The specific approach you are attempting will not work, but there are
    variations that will.

    First off, the title of a resource is always a string. Not a hash, not an
    array, but a string. Puppet DSL provides a shortcut for declaring multiple
    resources (native or defined-type) having the same parameters, by writing a
    single resource declaration where the (string) titles are given as an array
    literal or an array-valued variable. The result is exactly equivalent to
    multiple resource declarations, one for each given title, each with the
    specified parameters. That shortcut does not generalize. It never makes
    sense to specify a hash as a resource title, nor an array containing any
    non-string values.

    Moreover, all elements of a resource declaration itself are evaluated in
    the context in which the declaration appears. That applies here in that
    inside your resource *declarations*, there cannot be a sense of a
    'current' element of a composite title. That sort of thing has to go into
    the *implementation* of the resource type (where the 'current' element is
    just the plain resource title of one of several similar resources). Again:
    titles are always strings.

    Back to the question of how you achieve what you're after. There are at
    least two relatively straightforward ways, both requiring a slightly
    different form for your data. Instead of an array of hashes, you need a
    hash of hashes, with the keys of the outer hash being identifying strings
    suitable for use as resource titles or parts of them. The inner hashes can
    be similar or perhaps the same as the parameter hashes you have now. For
    example:

    $sites = {
    'site1' => {
    sitedomain => 'site1.domain.dev',
    repo => 'git@repo.address/Repo',
    branch => 'develop',
    serveralias => "",
    priority => '010'
    },
    ...
    }


    Having your data in that general form, you have two basic alternatives:

    1. Use the built-in create_resources() function
    2. Create a defined type that performs a similar function

    If, as in your case, your inner hashes combine parameters for resources of
    different types, option (1) would require a defined-type wrapper to use as
    the resource type passed to create_resources(), so that doesn't end up
    being any simpler. You should read docs for that function, but there isn't
    really much more to say. I will illustrate the alternative, however.

    The defined type you need for option (2) is a bit different from the one
    you would need for option (1). In this case, the defined type needs only
    one parameter, that being the hash of hashes:

    define mymodule::site($sites) {
    include 'apache' # if necessary
    include 'git' # if necessary

    # Select the inner hash for this site from
    # the hash of hashes, using this resource's
    # title as the key:
    $site_data = $sites[$title]

    # Declare resources

    apache::vhost { "${title}-vhost" :
    priority => $site_data['priority'],
    sitedomain => $site_data['sitedomain'],
    serveralias => $site_data['serveralias'],
    }

    git::clone { "${title}-git" :
    repo => $site_data['repo'],
    branch => $site_data['branch'],
    }
    }

    You use then that defined type like so:

    class somemodule::someclass {
    $site_names = <see below>
    mymodule::sites { $keys: sites => $sites }
    }

    The last bit is how to get the site names. It may be the case that which
    sites to declare is a separate question from which sites' parameters are
    recorded in the $sites hash, in which case you'll have to determine for
    yourself how to get a suitable array of site names (each being one of the
    keys of the $sites hash).

    If you just want to declare them all, however, then PuppetLabs's add-in
    'stdlib' module provides a keys() function that will return an array of the
    keys of a hash, which is just what you want for this purpose. Or you can
    roll your own; by itself, a keys() function is not very hard.

    $site_names = keys(sites)


    John
    --
    You received this message because you are subscribed to the Google Groups "Puppet Users" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscribe@googlegroups.com.
    To post to this group, send email to puppet-users@googlegroups.com.
    Visit this group at http://groups.google.com/group/puppet-users?hl=en.
    For more options, visit https://groups.google.com/groups/opt_out.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouppuppet-users @
categoriespuppet
postedMay 13, '13 at 4:26p
activeMay 14, '13 at 6:08p
posts3
users2
websitepuppetlabs.com

2 users in discussion

Eugene Brodsky: 2 posts Jcbollinger: 1 post

People

Translate

site design / logo © 2022 Grokbase