We Need To Go Deeper.
Inception.Here I want to describe programming examples / techniques. The reason is the same: there should be more docks on the Internet. In
my last article I talked about installing and configuring Puppet version 3.8 using the example of Centos 6.5. There would be the simplest example to test the client-server bundle. Now let's see how this can be complicated and why it is necessary.
Example â„–1: Using parameters in module manifests
')
class test1 {
Chain of transmission of our text in the parameters:
class ($ text1 $ text2) -> file (content ($ {text1} - $ {text2})Example 2: Uniform storage of parameters in the module manifest
So the next level: we have many classes and we want to make an analogue of the library of variables. Parameters can be stored in one recipe and then used throughout the module. For example, we want to collect some system variables and add something of our own.
A little bit of the basics:
We go to the Master server in / etc / puppet / modules and generate the skeleton:
puppet module generate myname-test1
We press 8 times the input, because all this can then be redone. Get the directory myname-test1, which we will rename to test1. You need the full name if you want to knock out and upload your module to the public
Puppet forge .
Create the file
/etc/puppet/modules/test1/manifests/init.pp class test1 ( $envname = $test1::params::env,
Create the file
/etc/puppet/modules/test1/manifests/params.pp class test1::params { $env = $settings::environment
Explanations:
test1 - Module name - The root name of the project in the puppet value system.
init.pp, params.pp - manifests - One manifest stores one class. File name and class must match.
class test1 - the initial class, the code of which works by default with a simple call after the class via the simple
include test1If desired, you can leave empty and create separate noun classes (see below).
class test1 :: params is a name class. The name params is chosen for convenience and can be any.
You can check the syntax in advance in 2 ways:
- Initially available via type command:
puppet parser validate /etc/puppet/modules/test1/manifests/*
- Put a more advanced spell checker
ppuppet-lint through
gem install puppet-lint and then check the files (at the same time you can slightly brush the syntax with the key --fix):
puppet-lint --fix /etc/puppet/modules/test1/manifests/*
But do not rely on them, you can easily miss an error like the wrong name of the manifest that will generate an error already when running on the client like:
Error: Could not retrieve catalog from remote server: Error 400 on SERVER: Could not find parent resource type 'test::params' of type hostclass in production at /etc/puppet/modules/test1/manifests/init.pp:1 on node stage.test.net
Again, I want to warn you that I noticed that in the 3.8.4 branch now having changed the module code, I have to restart the puppetmaster or httpd service so that the changes in the modules are applied immediately, before it did not ignore it. Perhaps in other versions it will not appear. I suspect that the module cache is stuck somewhere.
Add a call to our test1 module in the
/etc/puppet/manifests/site.pp file for the test
stage.test.net node.
node default { } node 'stage.test.net' { include test1 }
Check on client:
You can configure the service and wait for XX (usually 30) minutes until it works and then look at the logs. And you can start everything manually:
[root@stage ~]
As you can see the file was successfully created. If anyone wants to see how parameters can be reached, here is an example of a module for apache.
The chain of transmission of our text ptestint:
manifests / site.pp -> modules / test1 / init.pp ($ test1 :: params :: text1) -> file (content ($ {text1})Now, how can you change the default variables in /etc/puppet/manifests/site.pp, since they have higher priority.
node 'stage.test.net' {
Check on client:
...
-production - test: ptestint
\ No newline at end of file
+ production - test: newparam
\ No newline at end of file
...
As you can see the update was successful.
The chain of transmission of our text newparam:
manifests / site.pp ($ text1) -> modules / test1 / init.pp (text1) -> file (content ($ {text1})Such storage of parameters is also convenient if we do not create all manifests in one directory, but have made another level in the form
/test1/manifests/check/time.ppAnd then use this class anywhere through the form call:
class { '::test1::check::time': }
Example 3: Add a template.
The minus variation from the last example is that there is only one line in
content Therefore, it is better to use templates for generating large files.
Add to the test:
- File
/etc/puppet/modules/test1/manifests/usetmpl.pp - new class for working with the template
class test1::usetmpl ( $envname = $test1::params::env,
Changes in the replacement of the content of the text to the call of the template puppetenv.erb plus we brought everything into a separate class, although we could add the creation of the second file in init.pp.
- The file
/etc/puppet/modules/test1/templates/puppetenv.erb - Our generator template.
The variables
$ {text1} are here passed in Ruby format as
<% = @ text1%> . $ envname is taken from params.pp, $ text1 I again redefined in site.pp and at the same time added a “system” variable (they are called facts in puppet) <% =
hostname %>
Check on client:
[root@stage ~]
Total:
[root@stage ~]
The chain of our text param_tmpl:
manifests / site.pp ($ text1) -> modules / test1 / init.pp :: usetmpl ($ text1) -> file (content (puppetenv.erb (<% = @ text1%>)))Example number 4: Hiera or even more centralization
If you need to work with 1-10 servers, then the usual modules will be enough, but if there are more plus, the separation into subclusters went, where each module is configured in its own way, then you can get lost in the swollen parameters of the site.pp modules, or in modules of the same name and their versions. We go deeper and tune Hiera.
Hiera is a Ruby library; it is included by default in Puppet and helps organize data for all modules in a single directory.
To work our storage you need:
- Create a file
/etc/puppet/hiera.yaml of the following form:
:hierarchy: - "%{::clientcert}" - "%{::custom_location}" - "nodes/%{::fqdn}" - "nodes/%{::environment}" - "virtual/%{::virtual}" - common - "%{::environment}" :backends: - yaml :yaml: :datadir: "/etc/puppet/hieradata"
Here, we are waiting for a backdoor from the system as a priority of the native file /etc/hiera.yaml
T. h. You need to replace it with the symlink /etc/hiera.yaml -> /etc/puppet/hiera.yaml
- Create a folder
/ etc / puppet / hieradata (you can give your name and specify it in: datadir)
Files in this folder must have the extension .yaml and data format YAML.
- Create file
/etc/puppet/hiera/common.yamlFor example, here we can write the second test parameter available to all nodes
test::text2: common-hiera
Since we set the directory as the storage point for the node parameters
, “nodes /% {:: fqdn}” , then for our test node we create the file
/etc/puppet/hiera/nodes/stage.test.net.yaml . In it, we can now set our third test parameter and a small array in which there will be a parameter and one more array
testparam::text3: 'node stage hiera' arrexmpl::colors: bw: "B&W" rgb: - red - blue - green
Checking the availability of parameters from the command line in debug and simple mode:
[root@pmaster /etc]
Now we need to save them in the parameters and use in the template.
/etc/puppet/modules/test1/manifests/params.pp class test1::params {
/etc/puppet/modules/test1/manifests/usetmpl.pp class test1::usetmpl ( $envname = $test1::params::env, $text1 = $test1::params::text1, $text2 = $test1::params::text2,
/etc/puppet/modules/test1/templates/hieratst.erb
Check on client:
[root@stage ~]
Example number 5: R10K or even more centralization
Actually if the account of the servers went to tens of hundreds, then it becomes safer to divide them into environments. You can do this with handles, but it is better to use R10K, which allows you to run a separate configuration using modules, which is stored in its personal settings. That is. In essence, it replaces a single giant site.pp with its configs tree.
I will not do the test, just give the conditional algorithm for such a setting on the example of my working configuration.
- Servers are divided into settings groups that are stored in separate directories in
/ etc / puppet / environmentsFor example, we will test our recipe on the server group
test_devopsHyer's tree- stored on the gita / beatback
- tends to update the application of changes to the Master server
- in
hiera.yaml added to: hierarchy:
- %{environment}/%{role}/%{calling_module} - %{environment}/%{role} - %{role} - %{environment}/%{environment}
- Our parameters will be conditionally stored in files
/ etc / puppet / hieradata / test_devops /
test_devops.yaml - for all nodes via additional tag for R10K
classes: - roles::base
/ etc / puppet / hieradata / test_devops /
stage.test.net.yaml for server plus need label for R10K
classes: - roles::stagesrv::test
Configuring module startup for test_devops via R10K- On the stage.test.net site, add the line to the / etc / puppet /
puppet.conf file
environment = stage_nbc210
-
/ etc / puppet / environments / test_devops / Puppetfile - all used modules are stored here.
Recording examples
mod 'saz/sudo', '3.0.1' mod 'stdlib', :git => 'git://github.com/puppetlabs/puppetlabs-stdlib.git', :ref => '4.1.0' mod 'test1', :git => 'git://github.com/fake_link/test1.git', :ref => 'master'
They are then downloaded / updated in the console via a command like
sudo r10k deploy module test1 -e test_devops
/ etc / puppet / environments / test_devops / modules /
test1 - Where our module went down
-
/ etc / puppet / environments / test_devops / dist / profiles / manifests / - module launch manifest tree. File names must
not be the same as module names.
Create a file of type
runtest1.pp here class profiles::runtest1{ class { 'test1': text1 => 'newparam', }
As you can see the nodes are no longer indicated. If other nodes need other parameters, you can create runtest2.pp, etc. Additional levels are supported. For example, you can create the file / etc / puppet / environments / test_devops / dist / profiles / manifests / ver2 /
runtest3.pp class profiles::ver2::runtest3 class { 'test1': text1 => 'newparam v2', } }
- Now you need to bind the launch manifest modules to the nodes:
/etc/puppet/environments/test_devops/dist/roles/manifests/init.pp class roles { } class roles::base inherits roles { include profiles::base } class roles::private inherits roles { include profiles::private } class roles::public inherits roles { include profiles::public } class roles::stagesrv::test {
- Actually there was a dump of the totals of the settings
sudo r10k deploy environment test_devops
And then it will be applied on the node by autorun or you can test it manually via puppet agent --test
This is actually all. Thank you for reading to here.
Additions or options for other versions of those who wish can be included in this article.
I will not compare it with the experience of using chef client-server / chef + berkshelf / chef + AWS Opswork, since there is a completely different algorithm for organizing kukbok- “modules” and cleaner Ruby in recipes- “manifestos”.
Additional docks:
1. According to
micro samples of Puppet code.
2. By introduction to
Hiera3. A bit on
R10K