puppet の言語構造

Installation Guide を読めば、とりあえず puppet を動かすことはできるけど、やりたいことをやろうと思ってもすぐにできるわけでもない。というわけで、ドキュメントをちゃんと読んでみることにした。

まずは puppet の設定ファイルで使われている内部言語の理解から、ということで、Language Structures を超意訳してみる。

目次

  1. Types
  2. Assignment
  3. Bringing Config files together
  4. Scope
  5. Components
  6. Server Classes
  7. Classes vs. Components
  8. Subclssing
  9. Using Classes Outside of Puppet
  10. Nodes
  11. Conditionals
  12. Reserved words
  13. Comments

Types

puppet 設定の基本構成単位。管理されるコンピュータ上のオブジェクト(ファイルとかパッケージとか)を表すもので、あらかじめ用意されたビルトインタイプ以外にも、自ら定義することも可能。

file { "/etc/passwd": owner => root, mode => 644 } 
package { apache: install => true }

詳しくは Type Reference を参照。

Assignment

変数が利用できる。

$variable = value
$x = foo
$y = bar
$z = "$x$y"

Bringing Config files together

設定ファイルに、別の設定ファイルをインポートできる。

import "filename"

正規表現も利用可能。

import "classes/*"
import "packages/[a-z]*"

Scope

{ } によってスコープが形成される。

変数は一度割り当てられると、同一スコープ内では変更できないが、サブスコープ内では同一名の変数を割り当てることができる。

$var = value

# override $var
define testing {
    $var = othervalue
}

Components

ここでいう Components とは、自分で定義する Type のことっぽい。Components の定義と利用は以下の様な感じ。

define svnserve($source, $path, $user = false, $password = false) {
    file { $path:
        create => directory,
        owner => root,
        group => root
    }
    $svncmd = $user ? {
        false => "/usr/bin/svn co --non-interactive $source/$name .",
        default => "/usr/bin/svn co --non-interactive --username $user --password '$password' $source/$name ."
    }   
    exec { $svncmd: 
        cwd => $path,
        require => file[$path],
        creates => "$path/.svn"
    }   
}

svnserve { dist:
    source => "https://reductivelabs.com/svn",
    path => "/dist",
    user => "puppet",
    password => "password"
}

svnserve { "dist/config/apps/puppet":
    source => "https://reductivelabs.com/svn",
    path => "/etc/puppet",
    user => "puppet",
    password => "password"
}

利用する時はビルトインタイプと構文上の違いはない。

Server Classes

Class を定義してインクルードすることができる。

class <class_name> [inherits <super_class_name>] { ... }

継承も可能。

# really simple example
class solaris {
    file {
        "/etc/passwd": owner => root, group => root, mode => 644;
        "/etc/shadow": owner => root, group => root, mode => 440
    }
}

class solworkstation inherits solaris {
    file {
        "/etc/sudoers": owner => root, group => root, mode => 440;
        "/bin/sudo": owner => root, group => root, mode => 4111
    }
}

include solworkstation

以下の例だと、$operatingsystem の値と同名の Class と、$hostname に応じた Class がインクルードされる。

include $operatingsystem, $hostname ? {
    myhost => classA, default => classB
}

$operatingsystem とか $hostname とかは、Facterというライブラリを使ってプリセットされているみたい。

Classes vs. Components

Classes と Components の違いは以下の通り。

  • Classes はシングルトンなので、ホスト上でひとつしかないものを定義するのに利用する(OSの種類とか、特定のパッケージとかサービスとか。)
  • Components はホスト上で複数あるオブジェクト(バーチャルホストなど)を定義するのに利用する。

あと、Classes は引数を受け取れない、という違いもある。

Subclssing

Class は継承ができる。

class unix {
    file { "/etc/sudoers":
        owner => root,
        group => root,
        mode => 440
    }
}

class bsd inherits unix {
    File["/etc/sudoers"] {
        group => wheel
    }
}

Using Classes Outside of Puppet

puppet サーバで設定された Class 名が、puppet クライアントの /etc/puppet/classes.txt に保存されるので、それを外部プログラムなどから読み込んで利用したりできるよ、とうことらしい。

FC4 で yum insall した puppet の場合は、/var/lib/puppet/classes.txt に保存されていた。

Nodes

node <hostname> { ... }

特定のホストに適用する設定を割り当てる。

以下の例だと、file type はすべてのホストに割り当てられるけど、webserver class と dbserver class の中に書かれた設定は、それぞれ特定のホストにのみ割り当てられる。

class webserver { ... }
class dbserver { ... }

file { "/etc/sudoers": mode => 440 } # apply to everyone

node host1, host2 {
    include webserver
}
node host3, host4 {
    include dbserver
}

node は継承することも可能。

node base {
    include $operatingsystem
}

node kirby inherits base {
    include webserver
}

FQDN で指定する時は、シングルクォートで囲む。

node 'host.domain.com' {
    ...
}

Conditionals

条件指定が可能。

以下の例は $os が何かによって、 $owner に入る値が変わる。

define testing(os) {
    $owner = $os ? {
        sunos => adm,
        redhat => bin,
        default => root
    }
    file { "/some/file": owner => $owner }
}

以下の例は $operatingsystem が何かによって、適用する class が変わる。

case $operatingsystem {
    sunos:      { solaris {} } # apply the solaris class
    redhat:     { redhat  {} } # apply the redhat class
    default:    { generic {} } # apply the generic class
}

Reserved words

true, define, inherits, class は予約語。

Comments

sh スタイルのコメントが利用可。