Modules
Getting Started
Concept
Modules in Puppet are self-contained bundle of puppet code and the required file, template & data, which manage to solve some dedicate configurations, services and resource management, Modules allow you to organize you Puppet code into units which is much more easier to test and reuse.
Naming Convention
All modules are suppose to save in the module path for better puppet scope, modules are little more than a structure of directories and files that follow Puppet's naming conventions. The module file structure gives Puppet a consistent way to locate whatever classes, files, templates, plugins, and binaries are required to fulfill the function of the module.
Modules and the module directory structure also provide an important way to manage scope within Puppet. Keeping everything nicely tucked away in its own module means you have to worry much less about name collisions and confusion.
Forge
The concept of modules in Puppet is much similar with gems in Ruby and npm modules in nodejs, and Puppet Labs hosts a free service called Forge where you can find many well-written modules by others.
You can use puppet module tool to search any module you're interested in,
puppet module search mysql
Besides this, you can also search directly on Forge
Install the module from Forge:
puppet module install mysql
And you can also list all the modules installed locally:
puppet module list
For more details, check the help page;
puppet module -h
Module Path
We're talked about module-path a little bite in the previous section, such as execute below code to print out you module-path:
puppet master --configprint modulepath
Which would result:
/etc/puppetlabs/code/environments/production/modules:/etc/puppetlabs/code/modules:/opt/puppetlabs/puppet/modules
And the differences between these three path:
/etc/puppetlabs/code/environments/production/modules are used to save user defined modules, or keep modules for your prod environment.
/etc/puppetlabs/code/modules is for site specific modules.
/opt/puppetlabs/puppet/modules is for modules required by puppet itself.
If you have 'tree' installed on your system, you can directly see the directory via:
tree /etc/puppetlabs/code/environments/production/modules
Which would modules in the module-path:
├── home_index
│ ├── examples
│ │ └── test.pp
│ ├── files
│ └── manifests
│ └── init.pp
└── user_creation
├── examples
│ └── user.pp
├── files
└── manifests
└── init.pp
Directory manifests is the folder for all you main module code, which is the other folder is expect to keep all the files or templates your module code may use.
To keep all the puppet code organized and well-structured in module way would let your puppet code much more easier to maintain and use, puppet would know where to find you modules without specify the exact path of you puppet code.
Puppet URL
In Puppet, it has a special URLs started with below format, with this URL, you can refer any files or template on you puppet node or puppet master more easier.
puppet://{server hostname (optional)}/{mount point}/{remaining of path}
Server Hostname is optional, it defaults to the Puppet master and current Puppet node, as it has default values, normally the Puppet URL would start like this:
puppet:///
Mount Point Puppet have two kinds of mount point, the first one is modules and plugins, puppet treats modules this key word as a special mount point which is the Puppet master's module-path, and normally all the file serving in Puppet is done through modules. So if we want to locate a file from home_index module then we should compose the Puppet URL like this:
puppet:///modules/home_index/<Path>
Remaining Path is the remaining path of your file, such as you need the index.html from home_index module in folder file, then you should compose the Puppet URL like this:
puppet:///modules/home_index/file/index.html
In Puppet, you can user Puppet URL to refer a resource file, and of cause you can directly specify the resource's absolute path.
source => '/etc/puppet/modules/yourmodulename/files/fakefile'
But it's not a good practice to hard coding the resource that way as it make you module much harder to reuse.
Learning by Doing
Execute Puppet outside the puppet module path
Modify previously created home_index module via vim /etc/puppetlabs/code/environments/production/modules/home_index/manifests/init.pp:
class home_index{
notice 'home_index module was called!'
file { '/root/index.html':
ensure => file,
content => 'Hello, There',
}
}
notice 'home_index module was called!' was added to the Puppet code, notice is kind of a tool like print function in some other languages.
Go to any folder you'd like, and create a puppet manifest out_side_module_path.pp with below content
include home_index
And use puppet parser validate to validate your code, and then:
puppet apply out_side_module_path.pp
And you will see the output like this:
Notice: Scope(Class[Home_index]): home_index module was called!
Notice: Compiled catalog for cent0s6-64bit.apache.qa in environment production in 0.10 seconds
Notice: Applied catalog in 0.04 seconds
Use Puppet URL to compose user index page
Go to the module path
cd /etc/puppetlabs/code/environments/production/modules
Create a new module
mkdir compose_user_index/{manifests,files,examples} -p
Compose the new module pp via vim compose_user_index/manifests/init.pp with below content:
class compose_user_index {
file {'/root/index.html':
ensure => file,
source => "puppet:///modules/compose_user_index/index.html",
}
exec {'python -m SimpleHTTPServer 7777' :
cwd => '/root',
path => ['/usr/bin', '/usr/sbin',],
}
}
Create the user index.html in file folder via vim compose_user_index/files/index.html with below content:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<style>
p {
#background: green;
margin: 50% 0 50% 30%;
}
body {
background: #D5EBF2;
}
</style>
<title>JS Bin</title>
</head>
<body>
<p>Welcome to my home page</p>
</body>
</html>
Create the test.pp via vim compose_user_index/examples/test.pp with below content:
include compose_user_index
Validate and run:
puppet apply compose_user_index/examples/test.pp
And then visit http://<host>:7777/ you will see the user home page.