puppet资源配置

转自:http://blog.chinaunix.net/uid-23480577-id-3379623.html


puppet资源配置

在puppet中基本的配置宣称叫做资源,像我们在上次学习中写到的那样:
file { "/etc/passwd":
owner => "root",
group => "root",
mode => 644,
}
这是一个简单的puppet的配置资源,资源是你像管理你的计算机的配置条目,资源包括的条目像文件(file),服务(service),定时工作(cron jobs),用户组(users),群组(groups).
你也可以这样写

file { "group":
name => "/etc/group",
owner => "root",
}
我们这次不用字面上的名字做为名字,而是用一个特定的符号名字group,如果这样做的话我们需要指出他的名字属性,名字属性的写法和资源类型写法一样,对于这种方法,文件和服务类型都可以这样写。我们可以用符号使配置更容易理解。
这一点需要记着:一旦你使用了符号名,你必须使用他的名字属性,如:
file { "passwd":
name => "/etc/passwd",
}
file { "/etc/passwd":
}
第一个资源的标题是passwd,第二个资源是/etc/passwd,但是他们管理的都是/etc/passwd
,但对于Puppet来说,他们是不同的资源,因为他们有不同的标题。

Resource Attributes

在标题后面,紧跟的是特定的属性,属性用来告诉Puppet如何去配置资源,我们已经看到了一些属性,每一个资源都可以设置自己的属性,比如说资源的属主,属组,模式就像我们前面写的文件资源那样。
属性和值的结构
attribute => value,
attribute => value,
每一个属性键值对后面都要有一个逗号,最后一个属性键值对后面可以使用逗号也可以使用分号.
Puppet 有一些本地的属性值,比如说设置一些属性为true或false:
force => true,
值也可以是用户提供的,比如文件的属主是root,你就应该写成"root",用户提供的值要用加双引号。如果要在标题或者是值中使用一些像true, false, class,define, inherit等这样的关键字也要加双引号.

Resource Style

如果一个资源只有一个属性,它可以被声明成一行,像这样:
file { "/etc/group": owner => "root" }
你可以看到owner属性后面没加逗号,这种类型的声明虽然短但是有时候很难读,因为这个原因许多人宁愿为每个资源写多行的结构。多个资源可以被配置在一个资源类型里面如:
file {
"/etc/passwd":
ensure => present;
"/etc/group" :
owner => "root",
group => "root";
}
上面我已经说过,我们可以用另外一种Puppet形式的资源,如下:
File["/etc/passwd"]
File["/etc/group"]
最近Puppet支持#注释,如:ensure => running, # this is a comment

Resource Defaults

你可以设置默认的属性值,并且将其这种类型应用到所有的资源中,这就意味着你不用每次都指定一个特定的属性.我们看一个默认的例子,用一个可执行的资源类型允许你执行内部脚本或者编程,如:
Exec { path => "/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin" }
在可执行的资源类型中,path属性被用来指出搜索路径,Puppet用于发现那些内部的脚本,这是一个经常使用的脚本。默认的路径可以被覆盖,比如:
exec { "shell.rb --run": path => "/opt/bin:/opt/sbin" }
这里覆盖了默认的path

Collections of Resources


资 源能在结点上配置在但条目的,但是很多应用和服务都是由许多资源组成的,比如一个web服务器由软件包,执行软件的用户和一些配置,日志和其他文件.资源 集合允许你把资源聚集到一起,把他们添加到集合,并且把它们应用到1个或多个结点上。有两种类型的资源集合:classes和definitions。

1个class 是一个资源的集合,它代表你节点上一个单独的配置项目,SSH服务或者NFS包,Class在一个结点上仅仅形成1次,因为已经完成的配置应该仅仅存在一次,
一个definition类似,但是代表一个配置项的集合,在你的结点上可以有多个,比如配置Xen实例或者在Apache上配置虚拟主机,在一个结点上definition可以生成多次,每一次带有不同的输入参数,


Classes and Subclasses

我们看一个Class

class apache {
package { httpd: ensure => installed }
service { "httpd":
ensure => running,
require => Package["httpd"],
}
}
一个class由一个class语句段定义,后面紧跟的是class的名字,class后的一对大括号是闭合的

Classes Relationships

我们可以在不同的类中指明关系:如下所示
service { "httpd":
ensure => running,
require => Package["httpd"],
}

这里httpd service 资源包括的资源包Package["httpd"]已经存在了,我们也可以引用class以同样的方式.
service { "squid":
ensure => running,
retuire => Class["apache"],
}
这里指明了一个类和一个资源的关系,在这个例子中,squid service 需要那个已经存在的apache class ,你可能会注意到像资源的关系,我们用大写的Class来指明我们把class引用到另一个class当中,在括号里面压缩它们的名字.

Class Inheritance

类也有用基类和子类来实现简单的继承和覆盖的模型,一个子类可以继承基类的值并且能够实现它一个或者多个值对基类的值进行覆盖.看下面这个例子:
class readhat {
service {
"mdmdp":
enable => true,
enable => stopped,    
}
}

class rhel5 inherts redhat {
Service["mdmdp"] { ensure => running }
}

这 里class redhat是基类,定义了一个service 用来控制mdmdp service.它使用service资源类型让mdmdp服务在启动时间指定service必须停止。我们然后创建一个新的class,一个子类叫做 rhel5,它继承了redhat class但是覆盖了ensure属性并且指明mdmdp服务必须在所有的含有rhel5子类的结点上进行执行。

除继承之外,我们还可以在一个class中使用include函数去包含另一个class的内容像这样:
class proxy {
include proxysquidguard
...
}

从Puppet 0.23.1版本开始,一个新的特性也可以使用拉,它允许你在子类中去为属性添加值像这样:
class proxy {
service { "squid": require => Package["squid"]}
class proxysquidguard inherts proxy {
Service["squid"] { require +> Package["squidguard"]}
}
}

类proxysquidguard 等效于
service { "squid":
require => [ Package["squid"], Package["squidguard"] ]
}
我们也可以这样用

class proxysquidguard inherits proxy {
Service["squid"] { require => undef }
}

在子类中我们将require属性的值移去,使用undef这个属性值.

Definitions

第二种资源类型是定义,定义应该被用作单结点有多实例的配置项,比如,虚拟机或者一个web服务有多个实例,定义用定义的关键字和支持的参数但不是继承去创建,最好思想是定义的可复用性.
一个definition通过关键字被创建,为每一个definition指明一个标题,然后在大括号里面列出一些参数,这个definition 它自己被指明在下一个大括号里面,我定义了一个definition 用来执行一个脚本去配置一个新的主机.

define newip ( $ip ) {
exec { "/sbin/ifconfig" $title $ip ":
}
}
new ip { eth0:
ip => "11.11.11.11"
}

我们创建了一个definition叫做newip并且有一个参数叫做$ip,内部定义了我们用来执行资源类型内部二进制代码,这里是ifconfig 命令,我们已经指出变量$ip和使用的另一个变量$title
下一行我们真有一个叫做newip的definition,他被上一个definition调用了。
我们使用这个definition时,我们将看到下面的日志:
notice://newip[eth0]/Exec[/sbin/ifconfig eth0 11.11.11.11]/returns: executed ➥
successfully


我们也可以为每一个参数指定一个默认的值
define config_file(owner = root, group = root, mode = 0644,
source, backup = false, recurse = false, ensure = file ) {
file{ $name:
mode => $mode,
owner => $owner,
group => $group,
backup => $backup,
recurse => $recurse,
ensure => $ensure,
source => "puppet:///$source"
}
}

config_file { "/etc/vnc.conf":
source => "vnc/vnc.conf",
mode => "0640"
}

我们创建了config_file定义, 然后对其应用,这跟函数调用差不多.

Qualifying Definitions

Qualified definitions允许你执行很多有用的方法,首先你可以在class中这样定义

class virtuals {
define newip ( $ip ) {
exec { "/sbin/ifconfig $title $ip": 
}

}

virtuals::newip { eth0:
ip => "11.11.11.11",
}

这里我们定义了一个class叫做virtuals并且里面放了一个 newip的define,当我们调用的时候使用::
我们也可以用这种方式为一个definition设置默认值
virtuals::newip { noop => true }
最后我们用definition qualitication去指明独立性
file { "/etc/hosts.conf":
notify => network::checkhosts[$hostname]
}
前面的一行我们定义了一个文件资源使用了nofify的元参数,这个notify是一个触发器
如果文件/etc/hosts.con改变,network::checkhosts definition将会被调用
并且将hostname变量传递给它

Variables

在前面的你遇到的一些例子中,你遇到一个新概念:变量。变量前缀是$.如
$variable = "string"
你应该把变量值放到双引号里面,你可以在你的字符串中对定义过的变量进行引用,如
$variable = "string ${anothervariable} string ${thirdvariable}"

Variable Scoping

你必须知道变量的范围,首先Puppet是一门弱类型语言,变量的范围不同于其他语言,在一个范围之内你不能重新定义一个变量,所以你不能重新定义packagelist
class apache {
$packagelist = ["httpd", "openssl", "mod_ssl"]
package { $packagelist: ensure => installed }
$packagelist = "httpd"
service { "httpd":
ensure => running,
require => Package[$packagelist],
}
}
我们试着定义packagelist两次,但是如果对其进行编译,就会产生如下错误:
err: Cannot reassign variable packagelist at /etc/puppet/manifests/classes.pp:6
那么什么是范围呢,每个class,每个definition或者结点的介绍都是一个范围,如class A是一个范围,Class B是一个范围,Class C又是一个范围

class apache {
$apachever = 1
}
class apache2 {
$apachever = 2
}

这样写就不会有错

Variables and Class Inheritance

变量的范围在类继承中非常重要,如果我们已经有了一个相同名字的变量在一个类和子类中,它的行为将不像你希望的那样,如
class master {
$server = "primary"
file { "/etc/server.conf":
content => "$server",
ensure => present,
}
}
class slave inherits master {
$server = "secondary"
}
在 第一个类中 master 我定义$servers的值为"primary",第二个类slave中继承第一个类,我们试着去重定义$server这个变量成 “secondary”,这里$server重定义将不起作用,因为在继承的时候$server还在变量范围当中,你可以这样写:

$server = "primary"
class master {
file { "/etc/server.conf":
content => "$server",
ensure => present,
}
}
class slave {
$server = "secondary"
include master
}
这样$server的值就为"secondary"了.

Qualified Variables

我们也可以从一个class到另一个class引用变量或者赋值
class master {
$server = "primary"
}
class slave {
$ms = $master::server
}
我们也可以用下面的这种方式代表最高的范围
$ms = $::server

Variables and Metaparameters

使用变量句法,你也可以为一个类中的所有资源设置一个默认的元参数
class start_vhost {
$noop = true
exec { "/usr/sbin/start_ws": }
exec { “/usr.sbin/start_vhost”: }
}
在start_vhost class中,我们指定了空操作的元参数作为一个变量,并且把它设为true,在这个类中所有的资源两个exec资源,这个noop元参数将被添加,并且设为true。

Arrays

Puppet 也允许你定义数组,像下面那样,我们为$packagelist定义了数组,包含了3个包名字:httpd,openssl,mod_ssl
$packagelist = ["httpd",“openssl”,"mod_ssl"]
package { $packagelist: ensure => installed }

Conditionals

Puppet在资源、类、definition和结点中也支持条件,他们用一个默认的观点以一种选择的形式
service { "apache":
name => $operatingsystem ? {
debian => "apache2",
redhat => "httpd",
default => "apache",
},
ensure => running,
}
在apache service资源中有一个条件选择.它的结构是用一个?,然后跟了一个选择值的列表,也是key => value 这种形式的
注意:如果你不设置默认值,而其他的值都无法匹配时,Puppet将会产生一个错误
这还有2种其他的条件语句方法我们可以在mainfrests中应用:case和if。如:
case $operatingsystem {
redhat: { service { "httpd": ensure => running }}
debian: { service { "apache": ensure => running }}
default: { service { "apache2": ensure => running }}
}
case里面也可以使用变量
case $definedvariable {
"true" => { include class }
default => {}

最后一种条件语句:if,一种非常简单的if/else语句,只支持bool型的值,如
if $server {
file { "/etc/server.conf": ensure => present }
} else {
file { "/etc/client.conf": ensure => present }
}
如果$server定义了形成第一个文件资源

Creating Nodes
我们用这种方法去做到,让一些客户端去执行一些操作让另一些客户端去执行另一些操作
一旦一个client连接上了master,那么他的主机名将会用来匹配结点定义,hostname用来创建客户端证书。如果匹配不成功显示
err: Could not retrieve configuration: Could not find node1.testing.com with ➥
names node1.testing.com, node1

结点是如何定义的呢,我们看几个例子
node 'webserver.testing.com' {
include apache
}
node 'webserver2.testing.com' inherits 'webserver.testing.com' {
include mysql, rails
virtuals::new_vhost { vhost1:
ip => "11.11.11.11",
domainname => "vhost2.testing.com"
}
}
node default {
include $operatingsystem
package { "perl": ensure => present }
}
我们添加一些结点,每个结点和其他结点都以关键字进行区分

Facts
Facter 和Puppet有很紧密的联系,Puppet允许你为你的结点定义指定配置文件,Facter允许你从你的结点向Puppet的配置文件中添加信息:比如 知道被配置结点的操作系统,并且为这个结点定制配置信息,我们这个时候使用的就是Facter根据结点的操作系统平台选择为一个服务选择一个合适的名字.
Facts在变量定义在你的mainfests范围内是有效的,你可以看到对于一个特殊系统的facts有用是通过执行二进制的facter来获得可用性的。一个全列表的facts和他们的值将会被返回,下面列出了在不同平台中facts的常见返回值.
Fact                      Description
architecture              The architecture opuppet资源配置参考
在puppet中基本的配置宣称叫做资源,像我们在上次学习中写到的那样:
file { "/etc/passwd":
owner => "root",
group => "root",
mode => 644,
}
这是一个简单的puppet的配置资源,资源是你像管理你的计算机的配置条目,资源包括的条目像文件(file),服务(service),定时工作(cron jobs),用户组(users),群组(groups).
你也可以这样写

file { "group":
name => "/etc/group",
owner => "root",
}
我们这次不用字面上的名字做为名字,而是用一个特定的符号名字group,如果这样做的话我们需要指出他的名字属性,名字属性的写法和资源类型写法一样,对于这种方法,文件和服务类型都可以这样写。我们可以用符号使配置更容易理解。
这一点需要记着:一旦你使用了符号名,你必须使用他的名字属性,如:
file { "passwd":
name => "/etc/passwd",
}
file { "/etc/passwd":
}
第一个资源的标题是passwd,第二个资源是/etc/passwd,但是他们管理的都是/etc/passwd
,但对于Puppet来说,他们是不同的资源,因为他们有不同的标题。

Resource Attributes

在标题后面,紧跟的是特定的属性,属性用来告诉Puppet如何去配置资源,我们已经看到了一些属性,每一个资源都可以设置自己的属性,比如说资源的属主,属组,模式就像我们前面写的文件资源那样。
属性和值的结构
attribute => value,
attribute => value,
每一个属性键值对后面都要有一个逗号,最后一个属性键值对后面可以使用逗号也可以使用分号.
Puppet 有一些本地的属性值,比如说设置一些属性为true或false:
force => true,
值也可以是用户提供的,比如文件的属主是root,你就应该写成"root",用户提供的值要用加双引号。如果要在标题或者是值中使用一些像true, false, class,define, inherit等这样的关键字也要加双引号.

Resource Style

如果一个资源只有一个属性,它可以被声明成一行,像这样:
file { "/etc/group": owner => "root" }
你可以看到owner属性后面没加逗号,这种类型的声明虽然短但是有时候很难读,因为这个原因许多人宁愿为每个资源写多行的结构。多个资源可以被配置在一个资源类型里面如:
file {
"/etc/passwd":
ensure => present;
"/etc/group" :
owner => "root",
group => "root";
}
上面我已经说过,我们可以用另外一种Puppet形式的资源,如下:
File["/etc/passwd"]
File["/etc/group"]
最近Puppet支持#注释,如:ensure => running, # this is a comment

Resource Defaults

你可以设置默认的属性值,并且将其这种类型应用到所有的资源中,这就意味着你不用每次都指定一个特定的属性.我们看一个默认的例子,用一个可执行的资源类型允许你执行内部脚本或者编程,如:
Exec { path => "/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin" }
在可执行的资源类型中,path属性被用来指出搜索路径,Puppet用于发现那些内部的脚本,这是一个经常使用的脚本。默认的路径可以被覆盖,比如:
exec { "shell.rb --run": path => "/opt/bin:/opt/sbin" }
这里覆盖了默认的path

Collections of Resources


资 源能在结点上配置在但条目的,但是很多应用和服务都是由许多资源组成的,比如一个web服务器由软件包,执行软件的用户和一些配置,日志和其他文件.资源 集合允许你把资源聚集到一起,把他们添加到集合,并且把它们应用到1个或多个结点上。有两种类型的资源集合:classes和definitions。

1个class 是一个资源的集合,它代表你节点上一个单独的配置项目,SSH服务或者NFS包,Class在一个结点上仅仅形成1次,因为已经完成的配置应该仅仅存在一次,
一个definition类似,但是代表一个配置项的集合,在你的结点上可以有多个,比如配置Xen实例或者在Apache上配置虚拟主机,在一个结点上definition可以生成多次,每一次带有不同的输入参数,


Classes and Subclasses

我们看一个Class

class apache {
package { httpd: ensure => installed }
service { "httpd":
ensure => running,
require => Package["httpd"],
}
}
一个class由一个class语句段定义,后面紧跟的是class的名字,class后的一对大括号是闭合的

Classes Relationships

我们可以在不同的类中指明关系:如下所示
service { "httpd":
ensure => running,
require => Package["httpd"],
}

这里httpd service 资源包括的资源包Package["httpd"]已经存在了,我们也可以引用class以同样的方式.
service { "squid":
ensure => running,
retuire => Class["apache"],
}
这里指明了一个类和一个资源的关系,在这个例子中,squid service 需要那个已经存在的apache class ,你可能会注意到像资源的关系,我们用大写的Class来指明我们把class引用到另一个class当中,在括号里面压缩它们的名字.

Class Inheritance

类也有用基类和子类来实现简单的继承和覆盖的模型,一个子类可以继承基类的值并且能够实现它一个或者多个值对基类的值进行覆盖.看下面这个例子:
class readhat {
service {
"mdmdp":
enable => true,
enable => stopped,    
}
}

class rhel5 inherts redhat {
Service["mdmdp"] { ensure => running }
}

这 里class redhat是基类,定义了一个service 用来控制mdmdp service.它使用service资源类型让mdmdp服务在启动时间指定service必须停止。我们然后创建一个新的class,一个子类叫做 rhel5,它继承了redhat class但是覆盖了ensure属性并且指明mdmdp服务必须在所有的含有rhel5子类的结点上进行执行。

除继承之外,我们还可以在一个class中使用include函数去包含另一个class的内容像这样:
class proxy {
include proxysquidguard
...
}

从Puppet 0.23.1版本开始,一个新的特性也可以使用拉,它允许你在子类中去为属性添加值像这样:
class proxy {
service { "squid": require => Package["squid"]}
class proxysquidguard inherts proxy {
Service["squid"] { require +> Package["squidguard"]}
}
}

类proxysquidguard 等效于
service { "squid":
require => [ Package["squid"], Package["squidguard"] ]
}
我们也可以这样用

class proxysquidguard inherits proxy {
Service["squid"] { require => undef }
}

在子类中我们将require属性的值移去,使用undef这个属性值.

Definitions

第二种资源类型是定义,定义应该被用作单结点有多实例的配置项,比如,虚拟机或者一个web服务有多个实例,定义用定义的关键字和支持的参数但不是继承去创建,最好思想是定义的可复用性.
一个definition通过关键字被创建,为每一个definition指明一个标题,然后在大括号里面列出一些参数,这个definition 它自己被指明在下一个大括号里面,我定义了一个definition 用来执行一个脚本去配置一个新的主机.

define newip ( $ip ) {
exec { "/sbin/ifconfig" $title $ip ":
}
}
new ip { eth0:
ip => "11.11.11.11"
}

我们创建了一个definition叫做newip并且有一个参数叫做$ip,内部定义了我们用来执行资源类型内部二进制代码,这里是ifconfig 命令,我们已经指出变量$ip和使用的另一个变量$title
下一行我们真有一个叫做newip的definition,他被上一个definition调用了。
我们使用这个definition时,我们将看到下面的日志:
notice://newip[eth0]/Exec[/sbin/ifconfig eth0 11.11.11.11]/returns: executed ➥
successfully


我们也可以为每一个参数指定一个默认的值
define config_file(owner = root, group = root, mode = 0644,
source, backup = false, recurse = false, ensure = file ) {
file{ $name:
mode => $mode,
owner => $owner,
group => $group,
backup => $backup,
recurse => $recurse,
ensure => $ensure,
source => "puppet:///$source"
}
}

config_file { "/etc/vnc.conf":
source => "vnc/vnc.conf",
mode => "0640"
}

我们创建了config_file定义, 然后对其应用,这跟函数调用差不多.

Qualifying Definitions

Qualified definitions允许你执行很多有用的方法,首先你可以在class中这样定义

class virtuals {
define newip ( $ip ) {
exec { "/sbin/ifconfig $title $ip": 
}

}

virtuals::newip { eth0:
ip => "11.11.11.11",
}

这里我们定义了一个class叫做virtuals并且里面放了一个 newip的define,当我们调用的时候使用::
我们也可以用这种方式为一个definition设置默认值
virtuals::newip { noop => true }
最后我们用definition qualitication去指明独立性
file { "/etc/hosts.conf":
notify => network::checkhosts[$hostname]
}
前面的一行我们定义了一个文件资源使用了nofify的元参数,这个notify是一个触发器
如果文件/etc/hosts.con改变,network::checkhosts definition将会被调用
并且将hostname变量传递给它

Variables

在前面的你遇到的一些例子中,你遇到一个新概念:变量。变量前缀是$.如
$variable = "string"
你应该把变量值放到双引号里面,你可以在你的字符串中对定义过的变量进行引用,如
$variable = "string ${anothervariable} string ${thirdvariable}"

Variable Scoping

你必须知道变量的范围,首先Puppet是一门弱类型语言,变量的范围不同于其他语言,在一个范围之内你不能重新定义一个变量,所以你不能重新定义packagelist
class apache {
$packagelist = ["httpd", "openssl", "mod_ssl"]
package { $packagelist: ensure => installed }
$packagelist = "httpd"
service { "httpd":
ensure => running,
require => Package[$packagelist],
}
}
我们试着定义packagelist两次,但是如果对其进行编译,就会产生如下错误:
err: Cannot reassign variable packagelist at /etc/puppet/manifests/classes.pp:6
那么什么是范围呢,每个class,每个definition或者结点的介绍都是一个范围,如class A是一个范围,Class B是一个范围,Class C又是一个范围

class apache {
$apachever = 1
}
class apache2 {
$apachever = 2
}

这样写就不会有错

Variables and Class Inheritance

变量的范围在类继承中非常重要,如果我们已经有了一个相同名字的变量在一个类和子类中,它的行为将不像你希望的那样,如
class master {
$server = "primary"
file { "/etc/server.conf":
content => "$server",
ensure => present,
}
}
class slave inherits master {
$server = "secondary"
}
在 第一个类中 master 我定义$servers的值为"primary",第二个类slave中继承第一个类,我们试着去重定义$server这个变量成 “secondary”,这里$server重定义将不起作用,因为在继承的时候$server还在变量范围当中,你可以这样写:

$server = "primary"
class master {
file { "/etc/server.conf":
content => "$server",
ensure => present,
}
}
class slave {
$server = "secondary"
include master
}
这样$server的值就为"secondary"了.

Qualified Variables

我们也可以从一个class到另一个class引用变量或者赋值
class master {
$server = "primary"
}
class slave {
$ms = $master::server
}
我们也可以用下面的这种方式代表最高的范围
$ms = $::server

Variables and Metaparameters

使用变量句法,你也可以为一个类中的所有资源设置一个默认的元参数
class start_vhost {
$noop = true
exec { "/usr/sbin/start_ws": }
exec { “/usr.sbin/start_vhost”: }
}
在start_vhost class中,我们指定了空操作的元参数作为一个变量,并且把它设为true,在这个类中所有的资源两个exec资源,这个noop元参数将被添加,并且设为true。

Arrays

Puppet 也允许你定义数组,像下面那样,我们为$packagelist定义了数组,包含了3个包名字:httpd,openssl,mod_ssl
$packagelist = ["httpd",“openssl”,"mod_ssl"]
package { $packagelist: ensure => installed }

Conditionals

Puppet在资源、类、definition和结点中也支持条件,他们用一个默认的观点以一种选择的形式
service { "apache":
name => $operatingsystem ? {
debian => "apache2",
redhat => "httpd",
default => "apache",
},
ensure => running,
}
在apache service资源中有一个条件选择.它的结构是用一个?,然后跟了一个选择值的列表,也是key => value 这种形式的
注意:如果你不设置默认值,而其他的值都无法匹配时,Puppet将会产生一个错误
这还有2种其他的条件语句方法我们可以在mainfrests中应用:case和if。如:
case $operatingsystem {
redhat: { service { "httpd": ensure => running }}
debian: { service { "apache": ensure => running }}
default: { service { "apache2": ensure => running }}
}
case里面也可以使用变量
case $definedvariable {
"true" => { include class }
default => {}

最后一种条件语句:if,一种非常简单的if/else语句,只支持bool型的值,如
if $server {
file { "/etc/server.conf": ensure => present }
} else {
file { "/etc/client.conf": ensure => present }
}
如果$server定义了形成第一个文件资源

Creating Nodes
我们用这种方法去做到,让一些客户端去执行一些操作让另一些客户端去执行另一些操作
一旦一个client连接上了master,那么他的主机名将会用来匹配结点定义,hostname用来创建客户端证书。如果匹配不成功显示
err: Could not retrieve configuration: Could not find node1.testing.com with ➥
names node1.testing.com, node1

结点是如何定义的呢,我们看几个例子
node 'webserver.testing.com' {
include apache
}
node 'webserver2.testing.com' inherits 'webserver.testing.com' {
include mysql, rails
virtuals::new_vhost { vhost1:
ip => "11.11.11.11",
domainname => "vhost2.testing.com"
}
}
node default {
include $operatingsystem
package { "perl": ensure => present }
}
我们添加一些结点,每个结点和其他结点都以关键字进行区分

Facts
Facter 和Puppet有很紧密的联系,Puppet允许你为你的结点定义指定配置文件,Facter允许你从你的结点向Puppet的配置文件中添加信息:比如 知道被配置结点的操作系统,并且为这个结点定制配置信息,我们这个时候使用的就是Facter根据结点的操作系统平台选择为一个服务选择一个合适的名字.
Facts在变量定义在你的mainfests范围内是有效的,你可以看到对于一个特殊系统的facts有用是通过执行二进制的facter来获得可用性的。一个全列表的facts和他们的值将会被返回,下面列出了在不同平台中facts的常见返回值.
Fact                      Description
architecture              The architecture of the node, x86_64, for example
domain                    The domain name of the node
facterversion             The version of Facter running on the node
fqdn                      The fully qualified domain name of the node
hardwaremodel             The model of the hardware, for example, x86_64
hostname                  The hostname of the node
id                        The user running Facter
ipaddress                 The IP address
kernel                    The kernel type on the node
kernelrelease             Description
The kernel release of the kernel running on node
lsbdistcodename           The LSB codename of the distribution running on the node
lsbdistdescription        The LSB description of the distribution running on the node
lsbdistid                 The LSB release ID of the distribution running on the node
lsbdistrelease            The LSB release number of the distribution running on node
macaddress                The MAC address of the node
memoryfree                The available memory
memorysize                The total memory size
operatingsystem           The node’s operating system, for example, Fedora
operatingsystemrelease    The release of the node’s operating system
processorx                The make of each processor, includes an entry for each processor,
incremented from 0
processorcount            The total processor count
puppetversion             The version of Puppet on the node
rubyversion               The version of Ruby on the node
sshdsakey                 The node’s public DSA key
sshrsakey                 The node’s public RSA key
swapfree                  The available swap space
swapsize                  The total swap size
在Puppet master上,你可以去访问其他facts,servername和serverip facts时间哦最重要的,这些返回值返回完整的domain name 和 ip 地址
Facter也可以作为facts返回环境变量,Facters 假定任意的环境变量都以FACTER_为前缀,所以建立这些环境变量facts,我们只需要简单的配置环境变量就可以拉,就像这样:
export FACTER_statevar="primary"
这样在Puppet的mainifest里面就能引用环境变量这个值了用一个变量$statevar就代表了"primary"这个值。
因为有些环境变量是动态的,因此在默认情况下,这些变量是被Client乎略的
• memorysize
• memoryfree
• swapsize
• swapfree
列表中的facts被乎略要在Puppet配置中对其进行控制.在[puppet]这个名空间中通过dynamicfacts这个配置项
dynamicfacts = memorysize,memoryfree,swapfree,swapsize

Resource Types

我 们已经看到一些关于变量资源类型的例子被用来管理我们结点的资源,我们看到file类型的资源能够管理文件和目录,service类型的资源能管理服务和 守护进程,group类型的管理组,package类型的为我们的结点管理包.我们能利用的不仅仅是这些,那有我们可以在我们结点上配置资源的一个大的关 于资源类型的集合。集合也在社区成员的推动下迅速的发展,下面是我们目前能利用的资源类型:

Resource               Type Description
cron                   Manages cron jobs
exec                   Executes external scripts
file                   Manages files
filebucket             A repository for backing up files
group                  Manages groups
host                   Manages host entries
interface              Configures interfaces (currently only works on Red Hat and Solaris)
mailalias              Manages mail aliases
maillist               Manages mailing lists
mount                  Manages mount entries
notify                 Sends a message to the puppetd log file
package                Manages packages
schedule               Defines Puppet scheduling
service                Manages services
sshkey                 Manages SSH host keys
tidy                   Removes unwanted files
user                   Manages users
yumrepo                Manages YUM repositories
zones                  Manages Solaris zones

先看一下Cron的一个例子
cron { "syscheck":
command => "/usr/bin/syscheck",
user
=> "root",
hour
=> "18",
minute => "0"
}
这 里定义一个cron类型管理资源,command是cron要执行的命令,user属性是cron job作为那个用户去执行的,hour和minute属性是cron job执行时间,cron 也支持标准的minutes,hours,days,months attributes cron jobs用来调度

Using a Filebucket

filebucket { main: server => "puppetmaster.testing.com" }

Managing Host Files

host资源用来管理你结点中的host文件,通常指/etc/hosts,但是这种类型也支持使用网络添加host,你可以看下面这个例子
host { "router":
ensure => present,
ip => "10.0.0.1",
alias => ["router.testing.com", "firewall"]
}
这 种类型有一些属性,像我们上面用到的那样,ensure属性指明是否host信息添加或删除,当前设置的是添加,设置成absent用来删除host信 息,使用ip属性你可以指明是ipv4还是ipv6,最后我们有alias属性,它允许我们列出主机名,多个主机名要以数组的形式给出。执行完以后在 /etc/hosts多了一行
10.0.0.1 router router.testing.com firewall

Managing SSH Host Keys

sshkey资源类型去管理SSH host的keys,当前资源类型可以被用来在熟悉的hosts文件中为你的sshserver安装keys,/etc/ssh/ssh_known_hosts.看一个例子
sshkey { $hostname:
type => dsa,
key => $sshdsakey
}
这 里我们用了2个facts,我们指明了资源标题是$hostname,key的值为$sshdsakey fact,上面例子是做什么的呢?为每一个结点应用,他将把结点DSA的host key 放在/etc/ssh/ssh_know_hosts文件中,我们也可以传一个知道的host keys列表,或者使用ensure熟悉去指明key应该被添加还是被丢弃

Tidy Unwanted Files

titdy资源类型被用于基于特定的尺度移出不想要的文件,你可以指明一个特定文件的大小创建文件的时间,下面看一个移出的例子:
tidy { "outputs":
path => "/tmp/dboutput.sql",
age => '15m',
before => Service[mysql]
}
上 面的例子是一个tidy资源将删除文件/tmp/dboutput.sql如果他在15分钟前建立的,我们给了资源一个象征性的名字outputs并且使 用path熟悉精确指明了文件的路径,age属性用来设置文件在建立多长时间后进行删除。时间可以是 seconds,minutes,hours,days 和 weeks,age的值使用的都是这几个词的第一个字母。1s代表一秒,2d代表2天,默认情况下,tidy资源用的是访问时间。为了确定一个文件的 age,你可以覆盖它使用ctime和mtime,如 type => "ctime",我们还可以控制文件大小,使用
size => "10m"

Functions
Functions有两种形式,statements不返回值,rvalues 返回值
Function      Type              Description
include       Statement         Evaluates one or more classes
realize       Statement         Makes a virtual object real
alert         Statement         Logs a message on the server at level alert
crit          Statement         Logs a message on the server at level crit
debug         Statement         Logs a message on the server at level debug
emerg         Statement         Logs a message on the server at level emerg
err           Statement         Logs a message on the server at level err
info          Statement         Logs a message on the server at level info
notice        Statement         Logs a message on the server at level notice
warning       Statement         Logs a message on the server at level warning
defined       Rvalue            Determines whether a resource or class is defined
fail          Statement         Fails with a parse error
file          Rvalue            Returns the contents of a file or files
generate      Rvalue            Calls an external command and returns the results of the command
search        Statement         Adds another namespace for this class to search
tag           Statement         Adds tags to a class, node, or definition
tagged        Rvalue            A Boolean function that tells you whether the current container is tagged with the specified tags
template      Rvalue            Evaluates templates and returns their values

Logging Functions
alert,crit,debug,emerg,error,notice and warning 允许你向Puppet master发送信息,每个日志级别都是一个独立的函数,所以向服务器发送一条notice级别的信息,你可以用notice函数,像这 样:notice("This is log message sent at notice log level")

Checking for Existence with defined

defined 判断一个给出的资源或者class 是否被定义,在你include一个class时,你能够使用这个函数判断class是否存在,类似这样:

if defined(webservices) {
include apache
} else {
include lighttpd
}
如果webservices class 被定义了,apache class 应该被包含,否则lighttpd class被包含
你还可以去用defined 函数去验证是否一个资源被定义:
if defined(Service[sshd]) {...} 
如果sshd 服务被定义了,将执行一个action

Generating Errors with fail

fail函数在强迫一个解析错误,并且向服务器返回一个错误信息,你可以这样写:
fail("This function will result in a parse error")
这将在服务器上产生一个相似的错误
err: This function will result in a parse error at ➥
/etc/puppet/manifests/classes.pp:32

Adding External Data with file

file函数返回一个指定文件的内容,用法如下:
file { "resolv.conf":
name => "/etc/resolv.conf",
owner => "root",
group => "root",
content => file("/var/puppet/file/resolv.conf")
}
这 里我们创建一个新文件资源,然后为它设置自己的属主和属组,我们用file资源的content属性为我们新文件提供内容,content属性内部,我们 调用file函数形成/var/puppet/file/resolv.conf的内容,这个文件必须放在master主机上,我们也可以指定多个文件像 这样:
file(["/var/puppet/file/hosts", "/var/puppet/file/secondary_hosts"])

Using generate

generate 函数调用外部命令并且返回结果给Puppet,用法如下:
$interfaces = generate("/sbin/ifconfig", "eth0")
这里我们定义了一个变量叫做$interfaces,它调用了generate 函数,所有的generate 函数必须有一个指明的命令,然后填入若干参数,这两个直接用逗号分割,返回的结果就是执行命令
# /sbin/ifconfig eth0
将返回结果返回给$interface,命令执行完必须返回状态码为0,返回其他的状态码就会造成解释错误

Qualifying Definitions Using search

search 函数允许你引用定义包含在其他classes中,但是不需要限定它
class rails {
define site { ... }
}
class webserver {
search("rails")
site { mysite: ... }
}
这 里我们定义了2个class,rails 和 webserver,然后又在rails的class中建立一个definition叫做site。我们想在第二个类中引用这个定义,因此,我们加入了 search函数,并且这个class的名字写成我们要引用的,在这个例子中是rails,我们现在调用site definition,rails::site

Using tag and tagged

tag和tagged这两个函数能被添加倒结点、类、定义中提供另外的为他们分类的方法。
node 'node.testing.com' {
tag(devel)
if tagged(devel) {
include dev_test
}
include basics
}
第一行我们指定了一个结点定义,并且使用了tag函数用来增加devel tag,我们然后使用一个条件判断if 和 tagged 函数,如果devel tag被应用到了那个结点,dev_test class就被包含进来了。
一 些tags是自动创建的,比如,在一个class或node或definition结构中声明的所有资源将会使用结构的名字被tag,比如如果我们在一个 叫做basic的class中定义了一个file资源,/etc/passwd.这个资源将自动有一个basic的tag添加了进去,另一个例子是当一个 class被一个node包含时,一个和class名字相同的tag被加到那个node里面,你可以看到他是多么的有用.

node 'node1.testing.com' {
include webserver
include basics
}
node 'node2.testing.com' {
include databaseserver
include basics
}
class basics {
if tagged(webserver) {
notice("This is a web server")
}
if tagged(databaseserver) {
notice("This is a database server")
}
}
我们创建了两个node,包含webserver和basic class的node1和包含databaseserber和basic class的node2.
然 后我们定义了basic class。在这个class里面我们接合使用了if 条件和tagged 函数,在这个例子中,如果结点包含basics class作为webserver被tagged 一条notice被发送,如果一个结点带有databaseserver被tagged一个前者的notice被发送。

我们还可以选择那个配置基于tags被实现了,我们在Puppet配置文件中做这些事情通过设置tags的值,配置项像这样:
[puppetd]
tags = devel
或者pippet执行时,我们这样做
# puppetd --tags devel
如果多个tags用逗号分割

Using Templating

最后一个函数,tmplate 也是一个最有用的并且允许你去充分利用Ruby ERB的模板,这允许我们创建模板文件,像配置文件,比如能够从Puppet中迁移配置数据

class resolv {
$searchpath = "testing.com"
$nameservers = ["192.168.0.1", "192.168.0.2"]
file { "resolv.conf":
name => "/etc/resolv.conf",
content => template("resolv-template.erb")
}
}
我 们创建了一个叫做resolv的class,并且指明两个变量,$searchpath和$nameservers,一个file资源的配置/etc /resolv.conf,我们指出content属性调用了template函数,我们指明了一个模板文件叫做resolv-template.erb 的文件。
模板文件需要放在master机器上,默认情况下,如果你不指明全路径,Puppet将会在指明templatedir的配置的值中去搜 索你的配置文件,通常templatedir设置为/var/puppet/templates.在模板内部,你可以指出任意变量,下面的例子你可以使 用$searchpath和$nameservers在特定的模板中,我们看一下模板文件
search <%= searchpath %>
<% nameservers.each do |ns| %>nameserver <%= ns %>
<% end %>
这个ERB模板将收到$searchpath和$nameservers变量,我们已经指出一便Ruby code将遍历$nameservers数组,如果我们按上面的配置,最终的结果看上去像这样:

search testing.com
nameserver 192.168.0.1
nameserver 192.168.0.2
f the node, x86_64, for example
domain                    The domain name of the node
facterversion             The version of Facter running on the node
fqdn                      The fully qualified domain name of the node
hardwaremodel             The model of the hardware, for example, x86_64
hostname                  The hostname of the node
id                        The user running Facter
ipaddress                 The IP address
kernel                    The kernel type on the node
kernelrelease             Description
The kernel release of the kernel running on node
lsbdistcodename           The LSB codename of the distribution running on the node
lsbdistdescription        The LSB description of the distribution running on the node
lsbdistid                 The LSB release ID of the distribution running on the node
lsbdistrelease            The LSB release number of the distribution running on node
macaddress                The MAC address of the node
memoryfree                The available memory
memorysize                The total memory size
operatingsystem           The node’s operating system, for example, Fedora
operatingsystemrelease    The release of the node’s operating system
processorx                The make of each processor, includes an entry for each processor,
incremented from 0
processorcount            The total processor count
puppetversion             The version of Puppet on the node
rubyversion               The version of Ruby on the node
sshdsakey                 The node’s public DSA key
sshrsakey                 The node’s public RSA key
swapfree                  The available swap space
swapsize                  The total swap size
在Puppet master上,你可以去访问其他facts,servername和serverip facts时间哦最重要的,这些返回值返回完整的domain name 和 ip 地址
Facter也可以作为facts返回环境变量,Facters 假定任意的环境变量都以FACTER_为前缀,所以建立这些环境变量facts,我们只需要简单的配置环境变量就可以拉,就像这样:
export FACTER_statevar="primary"
这样在Puppet的mainifest里面就能引用环境变量这个值了用一个变量$statevar就代表了"primary"这个值。
因为有些环境变量是动态的,因此在默认情况下,这些变量是被Client乎略的
• memorysize
• memoryfree
• swapsize
• swapfree
列表中的facts被乎略要在Puppet配置中对其进行控制.在[puppet]这个名空间中通过dynamicfacts这个配置项
dynamicfacts = memorysize,memoryfree,swapfree,swapsize

Resource Types

我 们已经看到一些关于变量资源类型的例子被用来管理我们结点的资源,我们看到file类型的资源能够管理文件和目录,service类型的资源能管理服务和 守护进程,group类型的管理组,package类型的为我们的结点管理包.我们能利用的不仅仅是这些,那有我们可以在我们结点上配置资源的一个大的关 于资源类型的集合。集合也在社区成员的推动下迅速的发展,下面是我们目前能利用的资源类型:

Resource               Type Description
cron                   Manages cron jobs
exec                   Executes external scripts
file                   Manages files
filebucket             A repository for backing up files
group                  Manages groups
host                   Manages host entries
interface              Configures interfaces (currently only works on Red Hat and Solaris)
mailalias              Manages mail aliases
maillist               Manages mailing lists
mount                  Manages mount entries
notify                 Sends a message to the puppetd log file
package                Manages packages
schedule               Defines Puppet scheduling
service                Manages services
sshkey                 Manages SSH host keys
tidy                   Removes unwanted files
user                   Manages users
yumrepo                Manages YUM repositories
zones                  Manages Solaris zones

先看一下Cron的一个例子
cron { "syscheck":
command => "/usr/bin/syscheck",
user
=> "root",
hour
=> "18",
minute => "0"
}
这 里定义一个cron类型管理资源,command是cron要执行的命令,user属性是cron job作为那个用户去执行的,hour和minute属性是cron job执行时间,cron 也支持标准的minutes,hours,days,months attributes cron jobs用来调度

Using a Filebucket

filebucket { main: server => "puppetmaster.testing.com" }

Managing Host Files

host资源用来管理你结点中的host文件,通常指/etc/hosts,但是这种类型也支持使用网络添加host,你可以看下面这个例子
host { "router":
ensure => present,
ip => "10.0.0.1",
alias => ["router.testing.com", "firewall"]
}
这 种类型有一些属性,像我们上面用到的那样,ensure属性指明是否host信息添加或删除,当前设置的是添加,设置成absent用来删除host信 息,使用ip属性你可以指明是ipv4还是ipv6,最后我们有alias属性,它允许我们列出主机名,多个主机名要以数组的形式给出。执行完以后在 /etc/hosts多了一行
10.0.0.1 router router.testing.com firewall

Managing SSH Host Keys

sshkey资源类型去管理SSH host的keys,当前资源类型可以被用来在熟悉的hosts文件中为你的sshserver安装keys,/etc/ssh/ssh_known_hosts.看一个例子
sshkey { $hostname:
type => dsa,
key => $sshdsakey
}
这 里我们用了2个facts,我们指明了资源标题是$hostname,key的值为$sshdsakey fact,上面例子是做什么的呢?为每一个结点应用,他将把结点DSA的host key 放在/etc/ssh/ssh_know_hosts文件中,我们也可以传一个知道的host keys列表,或者使用ensure熟悉去指明key应该被添加还是被丢弃

Tidy Unwanted Files

titdy资源类型被用于基于特定的尺度移出不想要的文件,你可以指明一个特定文件的大小创建文件的时间,下面看一个移出的例子:
tidy { "outputs":
path => "/tmp/dboutput.sql",
age => '15m',
before => Service[mysql]
}
上 面的例子是一个tidy资源将删除文件/tmp/dboutput.sql如果他在15分钟前建立的,我们给了资源一个象征性的名字outputs并且使 用path熟悉精确指明了文件的路径,age属性用来设置文件在建立多长时间后进行删除。时间可以是 seconds,minutes,hours,days 和 weeks,age的值使用的都是这几个词的第一个字母。1s代表一秒,2d代表2天,默认情况下,tidy资源用的是访问时间。为了确定一个文件的 age,你可以覆盖它使用ctime和mtime,如 type => "ctime",我们还可以控制文件大小,使用
size => "10m"

Functions
Functions有两种形式,statements不返回值,rvalues 返回值
Function      Type              Description
include       Statement         Evaluates one or more classes
realize       Statement         Makes a virtual object real
alert         Statement         Logs a message on the server at level alert
crit          Statement         Logs a message on the server at level crit
debug         Statement         Logs a message on the server at level debug
emerg         Statement         Logs a message on the server at level emerg
err           Statement         Logs a message on the server at level err
info          Statement         Logs a message on the server at level info
notice        Statement         Logs a message on the server at level notice
warning       Statement         Logs a message on the server at level warning
defined       Rvalue            Determines whether a resource or class is defined
fail          Statement         Fails with a parse error
file          Rvalue            Returns the contents of a file or files
generate      Rvalue            Calls an external command and returns the results of the command
search        Statement         Adds another namespace for this class to search
tag           Statement         Adds tags to a class, node, or definition
tagged        Rvalue            A Boolean function that tells you whether the current container is tagged with the specified tags
template      Rvalue            Evaluates templates and returns their values

Logging Functions
alert,crit,debug,emerg,error,notice and warning 允许你向Puppet master发送信息,每个日志级别都是一个独立的函数,所以向服务器发送一条notice级别的信息,你可以用notice函数,像这 样:notice("This is log message sent at notice log level")

Checking for Existence with defined

defined 判断一个给出的资源或者class 是否被定义,在你include一个class时,你能够使用这个函数判断class是否存在,类似这样:

if defined(webservices) {
include apache
} else {
include lighttpd
}
如果webservices class 被定义了,apache class 应该被包含,否则lighttpd class被包含
你还可以去用defined 函数去验证是否一个资源被定义:
if defined(Service[sshd]) {...} 
如果sshd 服务被定义了,将执行一个action

Generating Errors with fail

fail函数在强迫一个解析错误,并且向服务器返回一个错误信息,你可以这样写:
fail("This function will result in a parse error")
这将在服务器上产生一个相似的错误
err: This function will result in a parse error at ➥
/etc/puppet/manifests/classes.pp:32

Adding External Data with file

file函数返回一个指定文件的内容,用法如下:
file { "resolv.conf":
name => "/etc/resolv.conf",
owner => "root",
group => "root",
content => file("/var/puppet/file/resolv.conf")
}
这 里我们创建一个新文件资源,然后为它设置自己的属主和属组,我们用file资源的content属性为我们新文件提供内容,content属性内部,我们 调用file函数形成/var/puppet/file/resolv.conf的内容,这个文件必须放在master主机上,我们也可以指定多个文件像 这样:
file(["/var/puppet/file/hosts", "/var/puppet/file/secondary_hosts"])

Using generate

generate 函数调用外部命令并且返回结果给Puppet,用法如下:
$interfaces = generate("/sbin/ifconfig", "eth0")
这里我们定义了一个变量叫做$interfaces,它调用了generate 函数,所有的generate 函数必须有一个指明的命令,然后填入若干参数,这两个直接用逗号分割,返回的结果就是执行命令
# /sbin/ifconfig eth0
将返回结果返回给$interface,命令执行完必须返回状态码为0,返回其他的状态码就会造成解释错误

Qualifying Definitions Using search

search 函数允许你引用定义包含在其他classes中,但是不需要限定它
class rails {
define site { ... }
}
class webserver {
search("rails")
site { mysite: ... }
}
这 里我们定义了2个class,rails 和 webserver,然后又在rails的class中建立一个definition叫做site。我们想在第二个类中引用这个定义,因此,我们加入了 search函数,并且这个class的名字写成我们要引用的,在这个例子中是rails,我们现在调用site definition,rails::site

Using tag and tagged

tag和tagged这两个函数能被添加倒结点、类、定义中提供另外的为他们分类的方法。
node 'node.testing.com' {
tag(devel)
if tagged(devel) {
include dev_test
}
include basics
}
第一行我们指定了一个结点定义,并且使用了tag函数用来增加devel tag,我们然后使用一个条件判断if 和 tagged 函数,如果devel tag被应用到了那个结点,dev_test class就被包含进来了。
一 些tags是自动创建的,比如,在一个class或node或definition结构中声明的所有资源将会使用结构的名字被tag,比如如果我们在一个 叫做basic的class中定义了一个file资源,/etc/passwd.这个资源将自动有一个basic的tag添加了进去,另一个例子是当一个 class被一个node包含时,一个和class名字相同的tag被加到那个node里面,你可以看到他是多么的有用.

node 'node1.testing.com' {
include webserver
include basics
}
node 'node2.testing.com' {
include databaseserver
include basics
}
class basics {
if tagged(webserver) {
notice("This is a web server")
}
if tagged(databaseserver) {
notice("This is a database server")
}
}
我们创建了两个node,包含webserver和basic class的node1和包含databaseserber和basic class的node2.
然 后我们定义了basic class。在这个class里面我们接合使用了if 条件和tagged 函数,在这个例子中,如果结点包含basics class作为webserver被tagged 一条notice被发送,如果一个结点带有databaseserver被tagged一个前者的notice被发送。

我们还可以选择那个配置基于tags被实现了,我们在Puppet配置文件中做这些事情通过设置tags的值,配置项像这样:
[puppetd]
tags = devel
或者pippet执行时,我们这样做
# puppetd --tags devel
如果多个tags用逗号分割

Using Templating

最后一个函数,tmplate 也是一个最有用的并且允许你去充分利用Ruby ERB的模板,这允许我们创建模板文件,像配置文件,比如能够从Puppet中迁移配置数据

class resolv {
$searchpath = "testing.com"
$nameservers = ["192.168.0.1", "192.168.0.2"]
file { "resolv.conf":
name => "/etc/resolv.conf",
content => template("resolv-template.erb")
}
}
我 们创建了一个叫做resolv的class,并且指明两个变量,$searchpath和$nameservers,一个file资源的配置/etc /resolv.conf,我们指出content属性调用了template函数,我们指明了一个模板文件叫做resolv-template.erb 的文件。
模板文件需要放在master机器上,默认情况下,如果你不指明全路径,Puppet将会在指明templatedir的配置的值中去搜 索你的配置文件,通常templatedir设置为/var/puppet/templates.在模板内部,你可以指出任意变量,下面的例子你可以使 用$searchpath和$nameservers在特定的模板中,我们看一下模板文件
search <%= searchpath %>
<% nameservers.each do |ns| %>nameserver <%= ns %>
<% end %>
这个ERB模板将收到$searchpath和$nameservers变量,我们已经指出一便Ruby code将遍历$nameservers数组,如果我们按上面的配置,最终的结果看上去像这样:

search testing.com
nameserver 192.168.0.1
nameserver 192.168.0.2
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值