标签:linux;puppet
puppet的部分变量由facter提供,是一个单独的软件包,在安装puppet时就已经被依赖安装了facter -p #变量名称及变量值,可直接调用
每个变量都有作用域,即作用范围
puppet的流程控制,如if语句、case语句、selector语句
下面结合示例,分析变量与流程控制的作用
if语句示例: cat if1.pp if $osfamily == 'Debian' { #osfamily是内建变量 $apachename = 'apache2' #apachename是用户自定义变量,都是用来临时存放字符串内容的 }else { $apachename = 'httpd' } #在流程控制中使用if/else条件控制语句,并为满足不同条件的自定义变量赋值 #puppet变量,无论是定义还是调用都要使用$符号 package{"$apachename": #注意调用变量要使用双引号,表示弱引用 ensure => latest, } #如果是Debian系统则安装apache2,其他系统则安装httpd软件包,package资源的title调用变量
case语句的示例: cat case.pp case $osfamily { "RefHat": { $webserver='httpd' } #匹配字符串 /(?i-mx:debian)/: { $webserver='apache2' #匹配正则表达式 default: { $webserver='httpd' } #默认选项 } #首先判断系统类型,红帽和其他系统使用httpd服务,Debian则使用apache2 package{"$webserver": ensure => installed, before => [File['httpd.conf'],Service['httpd']], } file{'httpd.conf': path => '/etc/httpd/conf/httpd.conf', source => '/app/httpd.conf', ensure => file, } service{'httpd': ensure => running, enable => true, restart => 'service httpd restart', subscribe => File['httpd.conf'], } #本示例实现安装httpd服务 在使用case流程控制时,有一项是匹配模式即正则表达式,下面简要说明下 /(?i-mx:debian)/ // 表示使用模式匹配,即满足正则表达式的格式要求 (? ) 正则表达式使用小括号括起来 i 表示忽略大小写 - 不启用某项功能 m 把 . 当作换行符 x 忽略模式中的空白字符
selector语句示例: selector与case很相似,但是case每一个匹配项都拥有独立代码,而selector每一个分支都是一个返回值 dselector用于多变量赋值 cat selector.pp $pkgname = $operatingsystem ? { /(?i-mx:(ubuntu|debian))/ => 'apache2', /(?i-mx:(redhat|fedora|centos))/ => 'httpd', default => 'httpd', } #自定义变量是pkgname,operatingsystem是内建变量其值是本机系统类型 #本段配置可以分两部分理解,第一步使用内建变量与每个分支做比较,如果内建变量自己的值与分支模式的值一致,则执行第二步 #第二步,将匹配的分支定义的内容赋值给自定义变量pkgname package{"$pkgname": ensure => installed, } 下面使用selector再次演示一个例子 cat selector2.pp $webserver = $osfamily ? { "RedHat" => 'httpd', /(?i-mx:debian)/ => 'apache2', default => 'httpd', } #使用selector为自定义变量webserver赋值 package{"$webserver": ensure => present, } file{'httpd.conf': path => '/etc/httpd/conf/httpd.conf', source => '/app/httpd.conf', ensure => file, require => Package["$webserver"], } service{'httpd': ensure => running, enable => true, restart => 'systemctl restart httpd', subscribe => File['httpd.conf'], }
puppet的类:
类是代码块,定义完成后可在全局使用,即在master定义在agent都可调用
定义类的语法格式有两种:
class NAME { ……puppet code…… } 和 class NAME(parameter1,parameter2) { #定义形参 ……puppet code…… }
调用类的方式常见的有两种:
1、使用include明确调用
2、如定义一个资源一样定义类完成调用
下面举例说明
示例1:使用include调用类 cat class1.pp class apache { $webpkg = $operationsystem ? { /(?i-mx:(centos|redhat|fedora))/ => 'httpd', /(?i-mx:(ubuntu|debian))/ => 'apache2', default => 'httpd', } #类中使用流程控制selector,为自定义变量webpkg赋值 package{"$webpkg": ensure => installed, } #类中使用package资源,安装软件包 file{'httpd.conf': ensure => file, path => '/etc/httpd/conf/httpd.conf', source => '/app/httpd.conf', require => Package["$webpkg"], } #类中调用file资源,复制httod的配置文件,而且此资源依赖于package资源 service{'httpd': ensure => running, enable => true, hasrestart => true, restart => 'service httpd restart', subscribe => File['httpd.conf'], } #类中调用service资源,启动httpd服务,并启动订阅功能在配置文件改变时重启服务 } #到此都是class的范围,所谓的类就是将多个资源打包在一起,对外呈现为独立个体 include apache #使用include调用类,否则我们只是定义类,并不会执行 示例2:定义资源一样定义类 cat class2.pp class webserver($pkg,$srv) { package{"$pkg": ensure => latest, } service{"$srv": ensure => running, } } if $operatingsystem == "CentOS" or $operatingsystem == "RedHat" { case $operatingsystemmajrelease { '7': { $pkgname = 'httpd' $srvname = 'httpd' } default: { $pkgname = 'nginx' $srvname = 'nginx' } } } class{'webserver': pkg => "$pkgname", srv => "$srvname", }
类的继承
子类继承父类的功能,同时可以在此基础上增加新的功能
调用子类会自动调用父类,所以没必要单独调用父类
cat redis.pp class redis { package{'redis': ensure => latest, } service{'redis': ensure => running, enable => true, hasrestart => true, restart => 'service redis restart', require => Package['redis'], } } #以上定义父类 class redis::master inherits redis { #子类名为master,完全限定的子类名称即redis::master file{'redis.conf': ensure => file, path => '/etc/redis.conf', source => '/app/module.d/redis-master.conf', owner => redis, group => root, require => Package['redis'] } #子类中可以自定义资源 Service['redis'] { restart => 'systemctl restart redis', subscribe => File['redis.conf'], } #子类调用父类的资源,注意格式 } class redis::slave inherits redis { file{'redis.conf': ensure => file, path => '/etc/redis.conf', source => '/app/module.d/redis-slave.conf', owner => redis, group => root, require => Package['redis'] } Service['redis'] { restart => 'systemctl restart redis', subscribe => File['redis.conf'], } } include redis::master #使用时仅调用子类即可,因为子类会主动调用父类,本处是redis主节点的调用 #本示例实现reids主从的自动化部署,所以用到了master和slave的配置文件, #从节点的调用是include redis::slave
puppet模板
模板语言使用erb
借助content实现文本文件中内嵌变量替换,如
<%= @VARIABLE_NAME %>
下面举例说明
结合上述示例 vim redis-slave.conf.erb slaveof <%= @masterip %> <%= @masterport %> #以redis配置文件为模板,只修改从节点的信息 cat redis.pp class redis { package{'redis': ensure => latest, } service{'redis': ensure => running, enable => true, hasrestart => true, restart => 'service redis restart', require => Package['redis'], } } class redis::master inherits redis { file{'/etc/redis.conf': ensure => file, source => '/app/module.d/redis-master.conf', owner => redis, group => root, require => Package['redis'] } Service['redis'] { restart => 'systemctl restart redis', subscribe => File['/etc/redis.conf'], } } class redis::slave($masterip,$masterport) inherits redis { #子类继承父类同时定义变量 file{'/etc/redis.conf': ensure => file, content => template('/app/module.d/redis-slave.conf.erb'), #这步是关键,定义模板的路径,不用再指定source owner => redis, group => root, require => Package['redis'] } Service['redis'] { restart => 'systemctl restart redis', subscribe => File['/etc/redis.conf'], } } class{'redis::slave': masterip => '192.168.1.106', masterport => '6379', } #定义类的资源,为slave子类变量赋值 #由于是从节点的配置,所有此处只对slave部分进行修改,master暂时不管 puppet apply -v redis.pp #执行资源清单 #然后检查/etc/redis.conf文件中的 slaveof 192.168.1.106 6379,说明模板复制成功
结束
标签:linux;puppet
原文地址:http://blog.51cto.com/panpangao/2044273