Ask Your Question
0

How to create resources from a config file.

asked 2016-02-11 14:09:00 -0500

grist gravatar image

updated 2016-02-11 19:26:54 -0500

Hi, I'm fairly new to puppet and come from a programming background, so please forgive me if I'm just thinking about this wrong.

What I would like to achieve is having a single, simple, editable file that contains information about vendors and their employees. Nothing fancy, just the vendor name and a login name for the employee. Then I want puppet to create the home folder structure which incorporates the vendor name with the username. There is also a shared area per vendor that all users for that vendor have access.

I have a puppet class that will create a group and a single vendor structure (forget the users for now)...

root@puppettest01:/etc/puppet/modules/vendor-setup/manifests# cat vendor.pp
class vendor (
    $vendor_name = 'Unh'
    )  {

    group { $vendor_name:
            ensure => present,
    }

    file { "/home/":
            ensure => directory,
            mode   => 0751,
            owner  => 'root',
            group  => 'root',
    }

    file { "/home/${vendor_name}/":
            ensure => directory,
            mode   => 0750,
            owner  => 'root',
            group  => $vendor_name,
    }

    file { "/home/${vendor_name}/shared/":
            ensure => directory,
            mode   => 0770,
            owner  => 'root',
            group  => $vendor_name,
    }
}

But I haven't been able to get it to make more than one in a single pass. I've seen example of creating multiple resources from one class, but they all seem to rely on either pre-defining all the variables for each instantiation, or don't need to use a variable in the setup part, just the name of the file or directory or whatever.

I tried parametrizing the class, but that still seemed to limit me to one final class to be evaluated. I looked at create_resources which looked promising, but required me to create my own custom resource type, and I can't help but feel it should be simpler than that.

Hiera data also seemed promising, but I still haven't figured out the link to make multiple resources based on my class, that are also aware of the variable I want to pass to them without having to define everything for each instance.

Any help or pointers greatly appreciated. :)

EDIT:

Some clarification. The above class works fine to create a single structure with a supplied vendor name. What I want to do is have something like a yaml file with, say...

---
:Vendor1:
    - Fred
    - Bob
:Vendor2:
    - Kate
    - Alex

And so on. Puppet would then use each vendor definition to create the appropriate structure as mapped out above, ensure the group exists and use it to apply security to the created folders.

It's the step between making a single instance and making multiple instances that will accept my vendor name as a variable that I seem to be missing.

Cheers, grist.

edit retag flag offensive close merge delete

3 Answers

Sort by ยป oldest newest most voted
1

answered 2016-02-14 17:30:20 -0500

Hi, I used this way to create multiples resources in one run:

define create_vendor ($vendor_name) {
  group { $vendor_name:
        ensure => present,
  }

  file { "/home/":
        ensure => directory,
        mode   => 0751,
        owner  => 'root',
        group  => 'root',
  }

  file { "/home/${vendor_name}/":
        ensure => directory,
        mode   => 0750,
        owner  => 'root',
        group  => $vendor_name,
  }

  file { "/home/${vendor_name}/shared/":
        ensure => directory,
        mode   => 0770,
        owner  => 'root',
        group  => $vendor_name,
   }

  $hashDefaults = { some_additonal_variable => $some_additonal_variable
  }
  if $vendor!=undef {
    create_resources(create_vendor, $vendor, $hashDefaults)
  }
}

Then you can use a yaml file with this structure:

vendor:
   vendor1:  { vendor_name : "john Smith" }
   vendor2:  { vendor_name : "Kyle Reese" }

You need to pass the variable "vendor" only, if you add more values like this:

   vendor1:  { vendor_name : "john Smith" , vendor_email : "john.smith@mydomain.com" }

you need to add on the "define" variables:

define create_vendor ($vendor_name, $vendor_email ) {
.
.
.

I hope this help you, regards.

edit flag offensive delete link more

Comments

That looks like exactly what I was looking for. Ta muchly. :D

grist gravatar imagegrist ( 2016-02-15 14:09:49 -0500 )edit

I couldn't get it to work with the '/home/' section in create_vendor.pp, kept getting 'duplicate resource' errors. Moved that bit to init.pp and it's all working. Thanks again.

grist gravatar imagegrist ( 2016-02-15 21:33:33 -0500 )edit
1

answered 2016-02-11 22:47:03 -0500

lavaman gravatar image

If you want to pass all of the data as a hash, turn your class into a defined type and then pass your hiera data to the create_resources function:

http://docs.puppetlabs.com/puppet/lat...

edit flag offensive delete link more

Comments

Aah yup, I had found that. I was hoping there was a simpler way. Thanks for the reply.

grist gravatar imagegrist ( 2016-02-14 14:04:50 -0500 )edit
0

answered 2016-02-11 16:49:43 -0500

UBPClaw gravatar image

updated 2016-02-11 18:45:59 -0500

Ok, first off Puppet has specific naming conventions that you need to follow (I ran in to this to when I was learning). If your class is called vendor, the directory also has to be named vendor, so the path would be /etc/puppetlabs/puppet/modules/vendor/manifests.

Also, your main file should always be named init.pp

I removed the curly braces from your file statement so it says $vendorname instead of ${vendorname}

Lastly, if your on the most recent version you have to encase the mode value in single quotes so that it is interpreted as a string. So it should look like mode => '0750',

I changed your code to just write the directory structure to /tmp without creating the group and it works

pwd /etc/puppetlabs/puppet/modules/vendor/manifests

cat init.pp

class vendor ( $vendor_name = 'Unh' ) {

file { "/tmp/$vendor_name/":
        ensure => directory,
        mode   => '0750',
        owner  => 'root',
}

file { "/tmp/$vendor_name/shared/":
        ensure => directory,
        mode   => '0770',
        owner  => 'root',
}

}

edit flag offensive delete link more

Comments

I'm creating the directories individually as they all have different security requirements (obviously /home should already exist, but I need to make sure the security is as I want it and hasn't been altered). I'm not sure how this solution would address that?

grist gravatar imagegrist ( 2016-02-11 18:27:21 -0500 )edit

Hey, thanks for the reply. Going to have to make multiple comments to answer them all. :) My files are named as you said, with an init.pp and the class file is called vendor.pp I used curly braces because that's what the style guide recommends. Particularly if you're using Hiera (which I will be)

grist gravatar imagegrist ( 2016-02-11 19:16:03 -0500 )edit

I'm also not sure you've picked up what I'm trying to do. My class works fine to create a single structure as you tested and verified. What I want to do is create multiple structures from this class based on (probably) yaml data.

grist gravatar imagegrist ( 2016-02-11 19:21:11 -0500 )edit

Edited original question with other points.

grist gravatar imagegrist ( 2016-02-11 19:33: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

Stats

Asked: 2016-02-11 14:09:00 -0500

Seen: 171 times

Last updated: Feb 11 '16