一、puppet概念
- 1、puppet是一种Linux、Unix、windows平台的集中配置管理系统,使用自有的puppet描述语言,可管理配置文件、用户、cron任务、软件包、系统服务等。puppet把这些系统实体称之为资源,puppet的设计目标是简化对这些资源的管理以及妥善处理资源间的依赖关系。
- 2、puppet采用C/S星状的结构,所有的客户端和一个或几个服务器交互。每个客户端周期的(默认半个小时)向服务器发送请求,获得其最新的配置信息,保证和该配置信息同步。每个puppet客户端每半小时(可以设置)连接一次服务器端, 下载最新的配置文件,并且严格按照配置文件来配置客户端. 配置完成以后,puppet客户端可以反馈给服务器端一个消息. 如果出错,也会给服务器端反馈一个消息.
3、puppet既可以在单机上使用,也可以以c/s结构使用.在大规模使用puppet的情况下,通常使用c/s结构.在这种结构中puppet客户端只是指运行puppet的客户端,puppet服务器端是只运行puppetmaster的服务器.
4、puppet客户端首先会连接到puppet服务器端,并且通过facter工具把客户端的基本配置信息发送给服务器端. 服务器端通过分析客户端的主机名,通过node 定义,找到该主机的配置代码,然后编译配置代码,把编译好的配置代码发回客户端,客户端执行代码完成配置.并且把代码执行情况反馈给puppet服务器端.
- 4、官方网站:https://puppet.com/
二、puppet的安装
1、puppet的工作模型:
- 单机模型:手动应用清单,本地编辑清单,在本机跑清单;
-
master/agent模型:master编辑清单,由agent周期性地向Master请求清单并自动应用于本地;
2、puppet程序的安装
- 可以用epel仓库安装版本较旧,也可以到官网下载较新版本rpm包安装。
使用epel源安装
[root@node-60 ~]# yum install facter puppet.noarch puppet-server.noarch -y
Installed:
facter.x86_64 0:2.4.1-1.el7
puppet.noarch 0:3.6.2-3.el7
puppet-server.noarch 0:3.6.2-3.el7
三、puppet程序
单机模型:
1、程序环境:
配置文件:/etc/puppet/puppet.conf
主程序:/usr/bin/puppet
2、puppet程序
- 命令格式: puppet <subcommand> [options] <action> [options]
help 显示帮助
apply 在本地资源清单
describe 显示帮助清单类型
agent 代理域
master 主域
module 管理模块
report 报告
status 服务端信息
……
- 命令帮助
'puppet help <subcommand>' for help on a specific subcommand.
'puppet help <subcommand> <action>' for help on a specific subcommand action.
3、子命令:puppet apply:在本机应用
格式:puppet apply [-d|--debug] [-v|--verbose] [-e|--execute] [--noop] <file>
四、puppet资源:
1、资源概念
资源抽象的纬度,RAL资源层如何抽象资源:
- 类型:具有类似属性的组件,例如package、service、file;
- 将资源的属性或状态与其实现方式分离;
- 仅描述资源的目标状态,也即期望其实现的结果状态,而不是具体过程;
- RAL由“类型”和提供者(provider)组成;
2、资源的子命令puppet describe:
- 查询有多少资源的子命令puppet describe:
puppet describe [-h|--help] [-s|--short] [-p|--providers] [-l|--list] [-m|--meta] [type]
-l:列出所有资源类型;
-s:显示指定类型的简要帮助信息;
-m:显示指定类型的元参数,一般与-s一同使用;
3、资源的定义
- 资源定义:向资源类型的属性赋值来实现,可称为资源类型实例化;
- 定义了资源实例的文件即清单,manifest;
定义资源的语法:
type {'title':
attribute1 => value1,
atrribute2 => value2,
……
}
- 注意:type必须使用小写字符;title是一个字符串,在同一类型中必须惟一;
4、资源的属性
资源属性中的三个特殊属性:
Namevar, 可简称为name;
ensure:资源的目标状态;
Provider:指明资源的管理接口;
五、puppet资源类型
- puppet资源核心类型:
- group: 组
- user:用户
- packge:程序包
- service:服务
- file:文件
- exec:执行自定义命令,要求幂等
- cron:周期性任务计划
- notify:通知
- puppet describe了解资源类型细节命令
1、group:管理组
属性:
name:组名;
gid:GID;
system:是否为系统组,true OR false;
ensure:目标状态,present/absent;
members:成员用户;
示例:
[root@node-60 ~]# mkdir manifests
[root@node-60 ~]# cd manifests/
[root@node-60 manifests]# vim first.pp
group{'nginx':
ensure => present, #定义目标状态必须存在,如果没有则创建
name => 'nginx', #名字
system =>true,
}
#测试预运行一次
[root@node-60 manifests]# puppet apply --verbose --noop first.pp
Notice: Compiled catalog for node-60 in environment production in 0.11 seconds #编译时间
Info: Applying configuration version '1542707136'
Info: Creating state file /var/lib/puppet/state/state.yaml #生成yaml文件地址
Notice: Finished catalog run in 0.05 seconds
2、user用户管理
属性:
name:用户名;
uid: UID;
gid:基本组ID;
groups:附加组,不能包含基本组;
comment:注释;
expiry:过期时间 ;
home:家目录;
shell:默认shell类型;
system:是否为系统用户 ;
ensure:present/absent;
password:加密后的密码串;
示例:
[root@node-60 manifests]# vim user1.pp
group{'nginx':
system => true,
ensure => present, #定义目标状态必须存在,如果没有则创建
}
user{'nginx':
uid => 444,
gid => 'nginx',
system => true,
ensure => present,
}
[root@node-60 manifests]# puppet apply --verbose user1.pp #执行清单
Notice: Compiled catalog for node-60 in environment production in 0.20 seconds
Info: Applying configuration version '1542724757'
Notice: /Stage[main]/Main/Group[nginx]/ensure: created #创建nginx组
Notice: /Stage[main]/Main/User[nginx]/ensure: created #创建nginx用户
Notice: Finished catalog run in 0.12 seconds
#查询组和用户已创建
[root@node-60 manifests]# tail /etc/passwd
nginx:x:444:996::/home/nginx:/bin/bash
3、关系元参数:before/require依赖关系,用于管理次序
A before B: B依赖于A,定义在A资源中;
{
...
before => Type['B'],
...
}
B require A: B依赖于A,定义在B资源中;
{
...
require => Type['A'],
...
}
示例:
[root@node-60 manifests]# vim user1.pp
group{'nginx':
system => true,
ensure => present, #定义目标状态必须存在,如果没有则创建
before => User['nginx'], #前资源依赖
}
user{'nginx':
uid => 444,
gid => 'nginx',
system => true,
ensure => present,
#require => Group['redis'], #后资源依赖
}
~
4、package管理程序包
属性:
ensure:installed安装最新版本, present安装, latest装上, absent不安装
name:包名;
source:程序包来源,仅对不会自动下载相关程序包的provider有用,例如rpm或dpkg;
示例1:
[root@node-60 manifests]# vim package.pp
package{'nginx':
ensure => latest,
}
[root@node-60 manifests]# puppet apply --verbose package.pp
#安装完成
[root@node-60 manifests]# rpm -q nginx
nginx-1.12.2-2.el7.x86_64
示例2:
[root@node-60 manifests]# vim package1.pp
package{'jdk':
ensure => installed, #源安装
soure => '/root/jdk-7u79-linux-x64.rpm', #安装源路径
provider => rpm, #安装方式
}
5、service管理运行中的服务
属性:
ensure:一个服务是否应该运行
enable:开机自动启动. true启动, false不启动, manual手动启动.
name:
path:The search path for finding init scripts. Multiple values should be separated by colons or provided as an array. 脚本的搜索路径,默认为/etc/init.d/;
hasrestart:是否有restart方法
hasstatus:是否有status探测方法
start:手动定义启动命令;
stop:手动定义停止命令;
status:手动定义运行信息命令;
restart:Specify a restart command manually. If left unspecified, the service will be stopped and then started. 通常用于定义reload操作;
示例:
[root@node-60 manifests]# vim service.pp
#定义程序包
package{'nginx':
ensure => present, #定义目标状态必须存在,如果没有则创建
}
#定义服务
service{'nginx':
ensure => running, #启动nginx
enable => true, #开机启动
require => Package['nginx'], #依赖于是否安装了nginx
}
[root@node-60 manifests]# puppet apply --verbose service.pp
[root@node-60 manifests]# ss -tnl
#查询是否启动
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:80 *:*
6、资源引用:
Type['title']类型的首字母必须大写;
资源有特殊属性:
名称变量(namevar):
name可省略,此时将由title表示;
ensure:
定义资源的目标状态;
元参数:metaparameters
依赖关系:before或require
通知关系:通知相关的其它资源进行“刷新”操作;
notify通知事件
- A notify B:B依赖于A,且A发生改变后会通知B;
{
...
notify => Type['B'],
...
}
subscribe订阅事件
- B subscribe A:B依赖于A,且B监控A资源的变化产生的事件;
{
...
subscribe => Type['A'],
...
}
7、文件资源管理file:
管理文件相关配置,属主属组等
ensure属性:present,absent, file, directory ,link
- file:类型为普通文件,其内容由content属性生成或复制由source属性指向的文件路径来创建;
- link:类型为符号链接文件,必须由target属性指明其链接的目标文件;
- directory:类型为目录,可通过source指向的路径复制生成,recurse属性指明是否递归复制;
path:文件路径;
source:源文件;
content:生成文件内容;
target:符号链接的目标文件;
owner:属主
group:属组
mode:权限;
atime/ctime/mtime:时间戳;
- 通知元参数:
A notify B:B依赖于A,接受由A触发refresh;
B subscribe A:B依赖于A,接受由A触发refresh;
示例1:
#文件类型
file{'test.txt':
path => '/tmp/test.txt',
ensure => file, #文件类型
source => '/etc/fstab',
}
#生成文件内容
file{'test.txt':
ensure => file, #文件类型
content => 'Hello world‘, #生成文件内容
}
#符号连接
file{'test.symlink':
path => '/tmp/test.symlink', #文件路径
ensure => link, #符号连接类型
target => '/tmp/test.txt', #符号链接的目标文件
require => File['test.txt'],
}
#目录
file{'test.dir':
path => '/tmp/test.dir', #目录
ensure => directory, #目录类型
source => '/etc/yum.repos.d/', #目标目录
recurse => true, #是否使用递归
}
示例2:
[root@node-60 manifests]# vim service.pp
package{'redis':
ensure => present,
}
file{'/etc/redis.conf':
ensure => file,
source => '/root/manifests/redis.conf',
require => Panckage['redis'], #依赖于redis是否安装
owner => 'redis',
group => 'root',
}
service{'nginx':
ensure => running,
enable => true,
subscribe => File['/ect/redis.conf'], #依赖于配置文件改变
}
示例3
[root@node-60 manifests]# vim service.pp
package{'redis':
ensure => present,
}
file{'/etc/redis.conf':
ensure => file,
source => '/root/manifests/redis.conf',
owner => 'redis',
group => 'root',
}
service{'nginx':
ensure => running,
enable => true,
}
#链式引用
Package['redis'] -> File['/etc/redis.conf'] ~> Service['redis']
7、exec:
任何写在exec中的命令,必须重复执行多次而不产生危害后果,有幂等性.
command (namevar):要运行的命令;
cwd:运行命令时候切换到那个目录
creates:文件路径,仅此路径表示的文件不存在时,command方才执行;
user/group:运行命令的用户身份;
path:寻找command相对路劲
onlyif:此属性指定一个命令,此命令正常(退出码为0)运行时,当前command才会运行;
unless:此属性指定一个命令,此命令非正常(退出码为非0)运行时,当前command才会运行;
refresh:重新执行当前command的替代命令;
refreshonly:仅接收到订阅的资源的通知时方才运行;
示例1:
[root@node-60 manifests]# vim test1.pp
exec{'mkdir':
command => 'mkdir /tmp/testdir',
path=> '/bin:/sbin:/usr/sbin',
creates => 'tmp/testdir', #判断目录不存在才执行command
}
示例2:
[root@node-60 manifests]# vim test2.pp
package{'mogilefs'
ensure => latest,
}
exec{'adduser':
command => 'useradd -r mogilefs',
path => '/bin:/sbin:/usr/bin:/usr/sbin',
unless => 'id mogilefs',#此命令执行失败,command才执行
refreshonly => true,
subscribe => Package['mogilefs'], #订阅mogilefs包安装失效
}
8、cron计划任务:
实现及管理计划任务,只是有一个命令和周期时间属性
command:要执行的任务;
ensure:'present'定义/'absent'删除;
hour:小时
minute:分钟
monthday:日
month:月
weekday:周
user:以哪个用户的身份运行命令
target:添加为哪个用户的任务
name:cron job的名称;
示例:
- 每隔3分钟向时间服务器同步时间
cron{'timesync':
command => '/usr/sbin/ntpdate 10.1.0.1 &> /dev/null', #同步时间
ensure => present,
minute => '*/3', #每隔3分钟
user => 'root',
}
9、notify显示输出:
属性:
message:信息内容
name:信息名称;
示例:
notify{ 'sayhi':
message => 'How old are you?',
name => 'sayhi',
}
六、puppet variable变量
$variable_name=value:以$开头变量名=值
1、数据类型:
- 字符型:引号可有可无;但单引号为强引用,双引号为弱引用;
- 数值型:默认均识别为字符串,仅在数值上下文才以数值对待;
- 数组:[]中以逗号分隔元素列表;
- 布尔型值:true, false,不能加引号;
- hash哈希:{}中以逗号分隔k/v数据列表; 键为*
字符型,值为任意puppet支持的类型;{ 'mon' => 'Monday', 'tue' => 'Tuesday', }; - undef:未定义 ;
2、表示格式
-
正则表达式:
- 格式
(?<ENABLED OPTION>:<PATTERN>)
(?-<DISABLED OPTION>:<PATTERN>)
- 格式
操作字符OPTIONS:
i:忽略字符大小写;
m:把.当换行符;
x:忽略<PATTERN>中的空白字符
(?i-mx:PATTERN)
- 注意:不能赋值给变量 ,仅能用在接受=~或 !~操作符的位置;
3、puppet的变量类型:
facts:由facter提供;top scope;
内建变量:
master端变量
agent端变量
parser变量
用户自定义变量:
变量有作用域,称为Scope;
top scope: $::var_name
node scope
class scope
4、puppet流程控制语句:
(1)、if语句:
if CONDITION {
... #条件满足执行
} else {
... #否则执行另一个
}
- CONDITION的给定方式:
(1) 变量
(2) 比较表达式
(3) 有返回值的函数
示例:
if $osfamily =~ /(?i-mx:debian)/ { #如果模式匹配不区分大小写操作系统是debian
$webserver = 'apache2' #定义一个变量为apache2
} else {
$webserver = 'httpd' #否则定义一个变量为httpd
}
package{"$webserver": #定义一个包
ensure => installed, #安装
before => [ File['httpd.conf'], Service['httpd'] ], #后面两个资源都依赖于这个资源
}
file{'httpd.conf': #定义一个配置文件
path => '/etc/httpd/conf/httpd.conf', #文件路径
source => '/root/manifests/httpd.conf', #源配置文件
ensure => file,
}
service{'httpd': #定义一个服务
ensure => running, #启动服务
enable => true, #开机启动
restart => 'systemctl restart httpd.service', #输出字符
subscribe => File['httpd.conf'],
}
(2)case语句:
多分支语句格式:
case CONTROL_EXPRESSION {
case1: { ... } #满足1分支,执行后跳出,否则执行下一个分支
case2: { ... } #满足2分支,执行跳出,否则执行下一个分支
case3: { ... } #满足3分支,执行跳出,否则执行下一个分支
...
default: { ... } #所有分支都不满足,执行default跳出
}
CONTROL_EXPRESSION:
(1) 变量
(2) 表达式
(3) 有返回值的函数各case的给定方式:
(1) 直接字串;
(2) 变量
(3) 有返回值的函数
(4) 正则表达式模式;
(5) default
示例:
case $osfamily { #判断系统类型
"RedHat": { $webserver='httpd' } #如果系统为Redhat,则变量值为httpd
/(?i-mx:debian)/: { $webserver='apache2' } #如果不区分大小写匹配是debian系统,变量值为apache2
default: { $webserver='httpd' } #如果都不是,则变量值为httpd
}
package{"$webserver": #定义安装包,值为case判断变量$webserver的结果
ensure => installed, #安装
before => [ File['httpd.conf'], Service['httpd'] ],
}
file{'httpd.conf': #定义配置文件
path => '/etc/httpd/conf/httpd.conf',
source => '/root/manifests/httpd.conf',
ensure => file,
}
service{'httpd': #定义服务
ensure => running, #启动
enable => true,
restart => 'systemctl restart httpd.service',
subscribe => File['httpd.conf'],
}
(3)、selector语句:
CONTROL_VARIABLE ? {
case1 => value1,
case2 => value2,
...
default => valueN,
}
CONTROL_VARIABLE的给定方法:
(1) 变量
(2) 有返回值的函数各case的给定方式:
(1) 直接字串;
(2) 变量
(3) 有返回值的函数
(4) 正则表达式模式;
(5) default
注意:不能使用列表格式;但可以是其它的selecor;
示例1:
$pkgname = $operatingsystem ? {
/(?i-mx:(ubuntu|debian))/ => 'apache2',
/(?i-mx:(redhat|fedora|centos))/ => 'httpd',
default => 'httpd',
}
package{"$pkgname":
ensure => installed,
}
示例2:
$webserver = $osfamily ? {
"Redhat" => 'httpd',
/(?i-mx:debian)/ => 'apache2',
default => 'httpd',
}
package{"$webserver":
ensure => installed,
before => [ File['httpd.conf'], Service['httpd'] ],
}
file{'httpd.conf':
path => '/etc/httpd/conf/httpd.conf',
source => '/root/manifests/httpd.conf',
ensure => file,
}
service{'httpd':
ensure => running,
enable => true,
restart => 'systemctl restart httpd.service',
subscribe => File['httpd.conf'],
}
七、puppet的类
1、类的概念
- puppet中命名的代码模块,常用于定义一组通用目标的资源,可在puppet全局调用;
类可以被继承,也可以包含子类;
2、语法格式:
class NAME {
...puppet code...
}
class NAME(parameter1, parameter2) {
...puppet code...
}
类代码只有声明后才会执行,调用方式:
- (1) include CLASS_NAME1, CLASS_NAME2, ...
- (2) class{'CLASS_NAME':
attribute => value,
}
示例1:
#声明一个类
class apache2 {
$webpkg = $operatingsystem ? {
/(?i-mx:(centos|redhat|fedora))/ => 'httpd',
/(?i-mx:(ubuntu|debian))/ => 'apache2',
default => 'httpd',
}
package{"$webpkg":
ensure => installed,
}
file{'/etc/httpd/conf/httpd.conf':
ensure => file,
owner => root,
group => root,
source => '/tmp/httpd.conf',
require => Package["$webpkg"],
notify => Service['httpd'],
}
service{'httpd':
ensure => running,
enable => true,
}
}
#调用apache2类,此句必须的
include apache2
示例2:
#定义类
class dbserver{$pkgname){
package{"$pkgname":
ensuer => latest,
}
service{"$pkgname":
ensuer => running,
enable=> true,
}
}
#判断系统类型
if $operatingsystem == "CentOS" {
$dbpkg = $operantingsystemmajrelease ? {
7 => 'mariadb-server',
default => 'mysqld-server',
}
#调用类
class {'dbserver':
pkgname=> $dbpkg,
}
3、类的继承
类继承的方式:
格式:class SUB_CLASS_NAME inherits PARENT_CLASS_NAME {
...puppet code...
}
nginx分段配置反向代理示例:
class nginx { #定义nginx父类
package{'nginx':
ensure => installed,
}
service{'nginx':
ensure => running,
enable => true,
restart => '/usr/sbin/nginx -s reload',
}
}
class nginx::web inherits nginx { #定义nginx的web子类,继承于nginx父类
Service['nginx'] {
subscribe => File['ngx-web.conf'],
}
file{'ngx-web.conf':
path => '/etc/nginx/conf.d/ngx-web.conf',
ensure => file,
source => '/root/manifests/ngx-web.conf',
}
}
class nginx::proxy inherits nginx { #定义nginx的proxy子类,继承于nginx父类
Service['nginx'] {
subscribe => File['ngx-proxy.conf'],
}
file{'ngx-proxy.conf':
path => '/etc/nginx/conf.d/ngx-proxy.conf',
ensure => file,
source => '/root/manifests/ngx-proxy.conf',
}
}
include nginx::proxy #执行nginx的proxy子类
- 在子类中为父类的资源新增属性或覆盖指定的属性的值:
Type['title'] {
attribute1 => value,
...
}
- 在子类中为父类的资源的某属性增加新值:
Type['title'] {
attribute1 +> value,
...
}
八、puppet模板:
- erb:模板语言,embedded ruby;ruby内嵌模板语言
puppet兼容的erb语法:
https://docs.puppet.com/puppet/latest/reference/lang_template_erb.html
- 格式:
file{'title':
ensure => file,
content => template('/PATH/TO/ERB_FILE'),
}
文本文件中内嵌变量替换机制:
<%= @VARIABLE_NAME %>
示例1:
[root@node-60 manifests]# vim nginx2.pp
package{'nginx':
ensure => latest,
}
file{ 'nginx.conf':
path => '/etc/nginx/nginx.conf',
content => template('/root/manifests/nginx.conf.erb'), #模板文件
}
#编辑模板文件
[root@node-60 manifests]# cp /etc/nginx/nginx.conf nginx.conf.erb
[root@node-60 manifests]# vim nginx.conf.erb
..........
user nginx;
worker_processes <%=@processorcount %>; #把模板生成的代码替换到此处,代表有几个物理cpu内核
...........
#执行
[root@node-60 manifests]# puppet apply --verbose nginx2.pp
[root@node-60 manifests]# cat /etc/nginx/nginx.conf
..........
user nginx;
worker_processes 1; #此处已经变成1
..........
示例2:
class nginx {
package{'nginx':
ensure => installed,
}
service{'nginx':
ensure => running,
enable => true,
require => Package['nginx'],
}
}
class nginx::web inherits nginx {
file{'ngx-web.conf':
path => '/etc/nginx/conf.d/ngx-web.conf',
ensure => file,
require => Package['nginx'],
source => '/root/manifests/nginx/ngx-web.conf',
}
file{'nginx.conf':
path => '/etc/nginx/nginx.conf',
ensure => file,
content => template('/root/manifests/nginx.conf.erb'), #配置文件使用模板
require => Package['nginx'],
}
Service['nginx'] {
subscribe => [ File['ngx-web.conf'], File['nginx.conf'] ],
}
}
include nginx::web
九、puppet模块:
- 模块就是一个按约定的、预定义的结构存放了多个文件或子目录的目录,目录里的这些文件或子目录必须遵循一定格式的命名规范;
1、模块路径
- puppet会在配置的路径下查找所需要的模块;
MODULES_NAME:模块名称
manifests/ 清单文件目录
init.pp 资源文件
files/ 配置文件目录
templates/ 所依赖的模板目录
lib/插件目录
spec/
tests/
模块名只能以小写字母开头,可以包含小写字母、数字和下划线;但不能使用”main"和"settings“;
manifests/
* init.pp:必须一个类定义,类名称必须与模块名称相同;
* files/:静态文件;
puppet URL:
puppet:///modules/MODULE_NAME/FILE_NAME
* templates/:模板目录
* tempate('MOD_NAME/TEMPLATE_FILE_NAME')
lib/:插件目录,常用于存储自定义的facts以及自定义类型;
* spec/:类似于tests目录,存储lib/目录下插件的使用帮助和范例;
* tests/:当前模块的使用帮助或使用范例文件;
注意:
(1)、puppet 3.8及以后的版本中,资源清单文件的文件名要与文件听类名保持一致,例如某子类名为“base_class::child_class”,其文件名应该为child_class.pp;
(2)、无需再资源清单文件中使用import语句;
(3)、manifests目录下可存在多个清单文件,每个清单文件包含一个类,其文件名同类名;
2、puppet config命令:
- 获取或设定puppet配置参数;
格式:puppet config print [argument]
- puppet查找模块文件的路径:modulepath
查询可用模块
[root@node-60 ]# puppet module serch nginx
安装模块
[root@node-60 ]# puppet module install oris-nginx
创建自定义chrony模块示例:
#创建模块目录
[root@node-60 ~]# mkdir moudules
[root@node-60 ~]# cd moudules/
#创建固定格式目录
[root@node-60 moudules]# mkdir chrony/{manifest,files,templates,lib,spec,tests} -pv
[root@node-60 moudules]# cd chrony/manifest/
#创建资源清单文件
[root@node-60 manifest]# vim init.pp
class chrony {
package{'chrony':
} ->
file{'chrony.conf':
path => '/etc/chrony.conf',
source => 'puppet:///modules/chrony/chrony.conf',
} ~>
service{'chronyd':
ensure => running,
enable => true,
}
}
#把配置文件拷贝到files目录下
[root@node-60 manifest]# cp /etc/chrony.conf ../files/
#修改配置文件相关项
[root@node-60 manifest]# vim ../files/chrony.conf
.........
server time1.aliyun.com iburst
........
#把自定义chrony模块目录拷贝到etc
[root@node-60 moudules]# cp -a chrony/ /etc/puppet/modules/
[root@node-60 moudules]# puppet module list
/etc/puppet/modules
└── chrony (???)
[root@node-60 moudules]# puppet apply -v -d -e 'include chrony'
mariadb模块中的清单文件示例:
class mariadb($datadir='/var/lib/mysql') {
package{'mariadb-server':
ensure => installed,
}
file{"$datadir":
ensure => directory,
owner => mysql,
group => mysql,
require => [ Package['mariadb-server'], Exec['createdir'], ],
}
exec{'createdir':
command => "mkdir -pv $datadir",
require => Package['mariadb-server'],
path => '/bin:/sbin:/usr/bin:/usr/sbin',
creates => “$datadir",
}
file{'my.cnf':
path => '/etc/my.cnf',
content => template('mariadb/my.cnf.erb'),
require => Package['mariadb-server'],
notify => Service['mariadb'],
}
service{'mariadb':
ensure => running,
enable => true,
require => [ Exec['createdir'], File["$datadir"], ],
}
}