Puppet-coding-style

提供:Dev Guides
移動先:案内検索

Puppet-コーディングスタイル

Puppetのコーディングスタイルは、マシン構成のインフラストラクチャをコードに変換する際に従う必要のあるすべての標準を定義します。 Puppetは、リソースを使用して、定義されたすべてのタスクを実行および実行します。

Puppetの言語定義は、管理が必要なターゲットマシンを管理するために必要な、構造化された方法ですべてのリソースを指定するのに役立ちます。 Puppetは、Rubyをエンコード言語として使用します。Rubyには、コード側の単純な構成で物事を非常に簡単に実行できる複数の組み込み機能があります。

基本単位

Puppetは、理解と管理が容易な複数の基本的なコーディングスタイルを使用しています。 以下にいくつかのリストを示します。

リソース

Puppetでは、リソースは基本モデリングユニットとして知られ、ターゲットシステムを管理または変更するために使用されます。 リソースは、ファイル、サービス、パッケージなどのシステムのすべての側面をカバーしています。 Puppetには、ユーザーまたは開発者がマシンの特定のユニットの管理に役立つカスタムリソースを開発できる組み込み機能が付属しています。

Puppetでは、すべてのリソースは "define" または "classes" を使用して集約されます。 これらの集約機能は、モジュールの編成に役立ちます。 以下は、Puppetが複数の属性をサポートできる複数のタイプ、タイトル、および属性のリストで構成されるサンプルリソースです。 Puppetの各リソースには独自のデフォルト値があり、必要に応じてオーバーライドできます。

ファイルのサンプルPuppetリソース

次のコマンドでは、特定のファイルのアクセス許可を指定しようとしています。

file {
   '/etc/passwd':
   owner => superuser,
   group => superuser,
   mode => 644,
}

上記のコマンドがいずれかのマシンで実行されるたびに、システム内のpasswdファイルが説明どおりに構成されていることを確認します。 前のファイル:コロンはリソースのタイトルで、Puppet設定の他の部分でリソースとして参照できます。

タイトルに加えてローカル名を指定する

file { 'sshdconfig':
   name => $operaSystem ? {
      solaris => '/usr/local/etc/ssh/sshd_config',
      default => '/etc/ssh/sshd_config',
   },
   owner => superuser,
   group => superuser,
   mode => 644,
}

常に同じタイトルを使用することで、OS関連のロジックを繰り返すことなく、構成でファイルリソースを参照するのが非常に簡単になります。

別の例として、ファイルに依存するサービスの使用があります。

service { 'sshd':
   subscribe => File[sshdconfig],
}

この依存関係により、 sshdconfig ファイルが変更されると、 sshd サービスは常に再起動します。 ここで覚えておくべきポイントは、 File [sshdconfig] は小文字の場合のFileとしての宣言ですが、これを FILE [sshdconfig] に変更すると、参照になります。

リソースを宣言する際に留意する必要がある基本的なポイントの1つは、構成ファイルごとに1回だけ宣言できることです。 同じリソースの宣言を複数回繰り返すと、エラーが発生します。 この基本概念により、Puppetは構成が適切にモデル化されていることを確認します。

リソースの依存関係を管理する機能もあり、複数の関係を管理するのに役立ちます。

service { 'sshd':
   require => File['sshdconfig', 'sshconfig', 'authorized_keys']
}

メタパラメータ

メタパラメーターは、Puppetではグローバルパラメーターとして知られています。 メタパラメーターの重要な機能の1つは、Puppetのあらゆるタイプのリソースで機能することです。

リソースのデフォルト

デフォルトのリソース属性値を定義する必要がある場合、Puppetは、タイトルのない大文字のリソース仕様を使用して、それをアーカイブするための構文セットを提供します。

たとえば、すべての実行可能ファイルのデフォルトパスを設定する場合は、次のコマンドで実行できます。

Exec { path => '/usr/bin:/bin:/usr/sbin:/sbin' }
exec { 'echo Testing mataparamaters.': }

上記のコマンドでは、最初のステートメントExecはexecリソースのデフォルト値を設定します。 Execリソースには、完全修飾パスまたは実行可能ファイルのように見えるパスが必要です。 これにより、設定全体に対して単一のデフォルトパスを定義できます。 デフォルトは、Puppetのすべてのリソースタイプで機能します。

デフォルトはグローバル値ではありませんが、定義されているスコープまたはそのすぐ隣の変数にのみ影響します。 完全な構成のために default を定義する場合は、次のセクションで default とクラスを定義します。

リソースコレクション

集約は、物を一緒に収集する方法です。 Puppetは、非常に強力な集約の概念をサポートしています。 Puppetでは、Puppetの基本単位であるリソースをグループ化するために集約が使用されます。 Puppetでのこの集約の概念は、 classes および definition として知られる2つの強力なメソッドを使用して実現されます。

クラスと定義

クラスは、ノードの基本的な側面のモデリングを担当します。 ノードはWebサーバーであり、この特定のノードはそれらの1つであると言うことができます。 Puppetでは、プログラミングクラスはシングルトンであり、ノードごとに1回評価できます。

一方、定義は単一のノードで何度も使用できます。 言語を使用して独自のPuppetタイプを作成した場合と同様に機能します。 それらは、毎回異なる入力で複数回使用されるように作成されます。 これは、変数値を定義に渡すことができることを意味します。

クラスと定義の違い

クラスと定義の唯一の重要な違いは、建物構造の定義とリソースの割り当て中にクラスがノードごとに1回だけ評価されることです。一方、定義は同じ単一ノードで複数回使用されます。

クラス

Puppetのクラスはclassキーワードを使用して導入され、その特定のクラスのコンテンツは、次の例に示すように中括弧で囲まれています。

class unix {
   file {
      '/etc/passwd':
      owner => 'superuser',
      group => 'superuser',
      mode => 644;
      '/etc/shadow':
      owner => 'vipin',
      group => 'vipin',
      mode => 440;
   }
}

次の例では、上記と同様のショートハンドを使用しました。

class unix {
   file {
      '/etc/passwd':
      owner => 'superuser',
      group => 'superuser',
      mode => 644;
   }

   file {'/etc/shadow':
      owner => 'vipin',
      group => 'vipin',
      mode => 440;
   }
}

Puppetクラスの継承

Puppetでは、継承のOOPコンセプトがデフォルトでサポートされており、クラスは新しく作成されたクラスに完全なコードビットをコピーして貼り付けることなく、以前の機能を拡張できます。 継承により、サブクラスは親クラスで定義されたリソース設定をオーバーライドできます。 継承を使用する際に留意すべき重要な点の1つは、クラスは1つ以上の親クラスからのみ機能を継承できないことです。

class superclass inherits testsubclass {
   File['/etc/passwd'] { group => wheel }
   File['/etc/shadow'] { group => wheel }
}

親クラスで指定されたロジックを元に戻す必要がある場合は、* undefコマンド*を使用できます。

class superclass inherits testsubcalss {
   File['/etc/passwd'] { group => undef }
}

継承を使用する別の方法

class tomcat {
   service { 'tomcat': require => Package['httpd'] }
}
class open-ssl inherits tomcat {
   Service[tomcat] { require +> File['tomcat.pem'] }
}

Puppetのネストされたクラス

Puppetは、ネストされたクラスの使用を許可するクラスのネストの概念をサポートします。これは、一方のクラスが他方のクラスの内部にあることを意味します。 これは、モジュール性とスコープの達成に役立ちます。

class testclass {
   class nested {
      file {
         '/etc/passwd':
         owner => 'superuser',
         group => 'superuser',
         mode => 644;
      }
   }
}
class anotherclass {
   include myclass::nested
}

パラメータ化されたクラス

Puppetでは、クラスは機能を拡張して、パラメーターをクラスに渡すことができます。

クラスでパラメータを渡すには、次の構成を使用できます-

class tomcat($version) {
   ... class contents ...
}

Puppetで覚えておくべき重要な点の1つは、include関数を使用してパラメーターを持つクラスを追加するのではなく、結果のクラスを定義として追加できることです。

node webserver {
   class { tomcat: version => "1.2.12" }
}

クラスのパラメーターとしてのデフォルト値

class tomcat($version = "1.2.12",$home = "/var/www") {
   ... class contents ...
}

実行ステージ

Puppetは実行ステージの概念をサポートします。これは、特定のリソースまたは複数のリソースを管理するために、ユーザーが要件に従って複数のステージを追加できることを意味します。 この機能は、ユーザーが複雑なカタログを開発する場合に非常に役立ちます。 複雑なカタログには、定義するリソース間の依存関係に影響を与えないように注意しながら、コンパイルする必要のあるリソースが多数あります。

実行ステージは、リソースの依存関係の管理に非常に役立ちます。 これは、特定のクラスにリソースのコレクションが含まれる定義済みの段階でクラスを追加することで実行できます。 実行ステージでは、Puppetは、カタログが実行され、Puppetノードに適用されるたびに、定義されたステージが指定された予測可能な順序で実行されることを保証します。

これを使用するには、既存のステージを超えて追加のステージを宣言する必要があります。Puppetは、必要な "→" および* "+>の前に同じリソース関係構文を使用して、指定された順序で各ステージを管理するように構成できます」*。 この関係により、各ステージに関連付けられたクラスの順序が保証されます。

Puppet宣言構文を使用した追加ステージの宣言

stage { "first": before => Stage[main] }
stage { "last": require => Stage[main] }

ステージが宣言されると、ステージを使用するメイン以外のステージにクラスを関連付けることができます。

class {
   "apt-keys": stage => first;
   "sendmail": stage => main;
   "apache": stage => last;
}

クラスapt-keyに関連付けられているすべてのリソースが最初に実行されます。 Sendmailのすべてのリソースがメインクラスになり、Apacheに関連付けられたリソースが最終段階になります。

定義

Puppetでは、マニフェストファイル内のリソースの収集は、クラスまたは定義によって行われます。 定義はPuppetのクラスに非常に似ていますが、* defineキーワード(クラスではない)*で導入され、継承ではなく引数をサポートします。 異なるパラメーターを使用して、同じシステムで複数回実行できます。

たとえば、同じシステム上で複数のリポジトリを作成しようとしているソースコードリポジトリを制御する定義を作成する場合、クラスではなく定義を使用できます。

define perforce_repo($path) {
   exec {
      "/usr/bin/svnadmin create $path/$title":
      unless => "/bin/test -d $path",
   }
}
svn_repo { puppet_repo: path => '/var/svn_puppet' }
svn_repo { other_repo: path => '/var/svn_other' }

ここで注意すべき重要な点は、変数を定義で使用する方法です。 ( $ )ドル記号変数を使用します。 上記では、$ titleを使用しました。 定義には、名前とタイトルを表すことができる$ titleと$ nameの両方を含めることができます。 デフォルトでは、$ titleと$ nameは同じ値に設定されますが、タイトル属性を設定して、異なる名前をパラメーターとして渡すことができます。 $ titleと$ nameは定義でのみ機能し、クラスや他のリソースでは機能しません。

モジュール

モジュールは、特定のPuppetノード(エージェント)に構成変更を適用するためにPuppetマスターが使用するすべての構成のコレクションとして定義できます。 これらは、特定のタスクを実行するために必要なさまざまな種類の構成のポータブルコレクションとしても知られています。 たとえば、モジュールには、PostfixとApacheの構成に必要なすべてのリソースが含まれている場合があります。

ノード

ノードは非常に単純な残りのステップであり、定義したもの(「これはWebサーバーの外観」)を、それらの命令を実行するために選択されたマシンと一致させる方法です。

ノード定義は、継承を含むクラスとまったく同じように見えますが、ノード(Puppetクライアントを実行する管理対象コンピューター)がPuppetマスターデーモンに接続すると、定義されたノードのリストでその名前が検索されます。 定義された情報はノードに対して評価され、ノードはその構成を送信します。

ノード名には、短いホスト名または完全修飾ドメイン名(FQDN)を使用できます。

node 'www.vipin.com' {
   include common
   include apache, squid
}

上記の定義は、www.vipin.comというノードを作成し、一般的なApacheクラスとSquidクラスを含みます

同じ構成を異なるノードに送信するには、各ノードをコンマで区切ります。

node 'www.testing.com', 'www.testing2.com', 'www3.testing.com' {
   include testing
   include tomcat, squid
}

一致するノードの正規表現

node/^www\d+$/{
   include testing
}

ノードの継承

ノードは限定された継承モデルをサポートします。 クラスと同様に、ノードは他の1つのノードからのみ継承できます。

node 'www.testing2.com' inherits 'www.testing.com' {
   include loadbalancer
}

上記のコードでは、www.testing2.comは、追加のロードバランサークラスに加えて、www.testing.comからすべての機能を継承しています。

高度なサポート機能

引用-ほとんどの場合、Puppetで文字列を引用する必要はありません。 文字で始まる英数字の文字列は、引用符なしで残されます。 ただし、負でない値の文字列を引用符で囲むことは常にベストプラクティスです。

引用付き変数補間

これまでのところ、定義に関して変数について述べてきました。 これらの変数を文字列で使用する必要がある場合は、一重引用符ではなく二重引用符を使用してください。 一重引用符の文字列は変数の補間を行いませんが、二重引用符の文字列は行います。 変数を \ {} で囲むと、一緒に使いやすくなり、理解しやすくなります。

$value = "${one}${two}"

ベストプラクティスとして、文字列の補間を必要としないすべての文字列に一重引用符を使用する必要があります。

大文字

大文字化は、特定のリソースのデフォルト属性の参照、継承、および設定に使用されるプロセスです。 基本的には、2つの基本的な使用方法があります。

  • 参照-すでに作成されたリソースを参照する方法です。 主に依存関係の目的で使用され、リソースの名前を大文字にする必要があります。 例、require ⇒ file [sshdconfig]
  • 継承-サブクラスから親クラスの設定をオーバーライドする場合、リソース名の大文字バージョンを使用します。 小文字バージョンを使用すると、エラーが発生します。
  • デフォルト属性値の設定-タイトルなしで大文字のリソースを使用すると、リソースのデフォルトが設定されます。

配列

Puppetでは、複数の領域で配列を使用できます[1、2、3]。

ホスト定義のエイリアスなど、いくつかの型メンバーは、値に配列を受け入れます。 複数のエイリアスを持つホストリソースは、次のようになります。

host { 'one.vipin.com':
   alias => [ 'satu', 'dua', 'tiga' ],
   ip => '192.168.100.1',
   ensure => present,
}

上記のコードは、3つのエイリアス*「satu」、「dua」、「tiga」を含むホスト *'one.brcletest.com' をホストリストに追加します。 1つのリソースに複数のリソースを追加する場合は、次の例に示すように実行できます。

resource { 'baz':
   require => [ Package['rpm'], File['testfile'] ],
}

変数

Puppetは、他のほとんどのプログラミング言語と同様に複数の変数をサポートしています。 Puppet変数は $ で示されます。

$content = 'some content\n'
file { '/tmp/testing': content => $content }

前述のように、Puppetは宣言型言語です。つまり、その範囲と割り当て規則は命令型言語とは異なります。 主な違いは、変数の値を決定するためにファイル内の順序に依存するため、1つのスコープ内で変数を変更できないことです。 宣言言語では順序は関係ありません。

$user = root
file {
   '/etc/passwd':
   owner => $user,
}

$user = bin
   file {
      '/bin':
      owner => $user,
      recurse => true,
   }

可変スコープ

変数スコープは、定義されているすべての変数が有効かどうかを定義します。 最新の機能と同様に、Puppetは現在動的にスコープされています。これは、Puppetの用語では、定義されたすべての変数が、定義された場所ではなくスコープで評価されることを意味します。

$test = 'top'
class Testclass {
   exec { "/bin/echo $test": logoutput => true }
}

class Secondtestclass {
   $test = 'other'
   include myclass
}

include Secondtestclass

修飾変数

Puppetは、クラスまたは定義内での修飾変数の使用をサポートしています。 これは、ユーザーが定義した、または定義しようとしている他のクラスで同じ変数を使用する場合に非常に役立ちます。

class testclass {
   $test = 'content'
}

class secondtestclass {
   $other = $myclass::test
}

上記のコードでは、$ other変数の値がコンテンツを評価します。

条件付き

条件は、定義された条件または必要な条件が満たされたときに、ユーザーがステートメントまたはコードのセットを実行したい状況です。 Puppetは2種類の条件をサポートしています。

マシンの正しい値を選択するために定義されたリソース内でのみ使用できるセレクター条件。

ステートメント条件は、マニフェストでより広く使用される条件であり、ユーザーが同じマニフェストファイルに含めたい追加のクラスを含めるのに役立ちます。 クラス内でリソースの異なるセットを定義するか、他の構造的な決定を下します。

セレクター

セレクターは、ユーザーがファクトまたは他の変数に基づいてデフォルト値とは異なるリソース属性と変数を指定したい場合に役立ちます。 Puppetでは、セレクターインデックスは複数値の三元演算子のように機能します。 セレクターは、マニフェストで定義され、条件に一致する値なしでカスタムのデフォルト値を定義することもできます。

$owner = $Sysoperenv ? {
   sunos => 'adm',
   redhat => 'bin',
   default => undef,
}

Puppet 0.25.0以降のバージョンでは、セレクターを正規表現として使用できます。

$owner = $Sysoperenv ? {
  /(Linux|Ubuntu)/=> 'bin',
   default => undef,
}

上記の例では、セレクターの $ Sysoperenv 値はLinuxまたはUbuntuのいずれかに一致し、ビンは選択された結果になります。そうでない場合、ユーザーは未定義として設定されます。

ステートメント条件

ステートメント条件は、Puppetの他のタイプの条件ステートメントであり、シェルスクリプトのswitch case条件に非常によく似ています。 これでは、caseステートメントの複数のセットが定義され、指定された入力値が各条件と照合されます。

指定された入力条件に一致するcaseステートメントが実行されます。 このcaseステートメント条件には戻り値がありません。 Puppetでは、条件ステートメントの非常に一般的なユースケースは、基盤となるオペレーティングシステムに基づいて一連のコードビットを実行することです。

case $ Sysoperenv {
   sunos: { include solaris }
   redhat: { include redhat }
   default: { include generic}
}

Caseステートメントでは、複数の条件をコンマで区切って指定することもできます。

case $Sysoperenv {
   development,testing: { include development } testing,production: { include production }
   default: { include generic }
}

If-Elseステートメント

Puppetは、条件ベースの操作の概念をサポートしています。 それを実現するために、If/elseステートメントは、条件の戻り値に基づいて分岐オプションを提供します。 次の例に示すように-

if $Filename {
   file { '/some/file': ensure => present }
} else {
   file { '/some/other/file': ensure => present }
}

最新バージョンのPuppetは、式の値に基づいてifステートメントも分岐できる変数式をサポートしています。

if $machine == 'production' {
   include ssl
} else {
   include nginx
}

コードの多様性を高め、複雑な条件付き操作を実行するために、Puppetは次のコードに示すようにネストされたif/elseステートメントをサポートしています。

if $ machine == 'production' {
   include ssl
} elsif $ machine == 'testing' {
   include nginx
} else {
   include openssl
}

仮想リソース

仮想リソースは、実現しない限りクライアントに送信されないリソースです。

以下は、Puppetで仮想リソースを使用する構文です。

@user { vipin: ensure => present }

上記の例では、コレクションで使用できる定義を実現するために、ユーザーvipinが仮想的に定義されています。

User <| title == vipin |>

コメント

コード行のセットとその機能について追加のノードを作成するために、任意のコードビットでコメントが使用されます。 Puppetには、現在2種類のコメントがサポートされています。

  • Unixシェルスタイルのコメント。 彼らは、独自の行または次の行にすることができます。
  • 複数行のCスタイルのコメント。

次に、シェルスタイルのコメントの例を示します。

# this is a comment

以下は複数行コメントの例です。

/*
This is a comment
*/

演算子の優先順位

Puppetオペレーターの優先順位は、ほとんどのシステムの標準的な優先順位(最高から最低まで)に準拠しています。

以下は式のリストです

  • ! =しない */=回と除算
  • -+ =マイナス、プラス
  • << >> =左シフトと右シフト
  • ==!= =等しくない、等しい *> = <⇒ ⇐より大きい、より小さいまたは等しい、より大きい、より小さい

比較式

比較式は、指定された条件が満たされたときにユーザーが一連のステートメントを実行する場合に使用されます。 比較式には、==式を使用した等価性のテストが含まれます。

if $environment == 'development' {
   include openssl
} else {
   include ssl
}

等しくない例

if $environment != 'development' {
   $otherenvironment = 'testing'
} else {
   $otherenvironment = 'production'
}

算術式

$one = 1
$one_thirty = 1.30
$two = 2.034e-2 $result = ((( $two + 2)/$one_thirty) + 4* 5.45) -
   (6 << ($two + 4)) + (0×800 + -9)

ブール式

ブール式は、or、and、&notを使用して可能です。

$one = 1
$two = 2
$var = ( $one < $two ) and ( $one + 1 == $two )

正規表現

Puppetは、=〜(一致)および!〜(非一致)を使用した正規表現一致をサポートしています。

if $website =~/^www(\d+)\./{
   notice('Welcome web server #$1')
}

大文字小文字の区別とセレクターの正規表現の一致は、各正規表現の限定スコープ変数を作成します。

exec { "Test":
   command => "/bin/echo now we don’t have openssl installed on machine >/tmp/test.txt",
   unless => "/bin/which php"
}

同様に、正常に終了しない限り、下のコマンドを除き、常にコマンドを実行しない限り、使用できます。

exec { "Test":
   command => "/bin/echo now we don’t have openssl installed on machine >/tmp/test.txt",
   unless => "/bin/which php"
}

テンプレートの使用

テンプレートは、Puppetの複数のモジュール間で使用される定義済みの構造を希望し、それらのモジュールが複数のマシンに配布される場合に使用されます。 テンプレートを使用するための最初のステップは、テンプレートメソッドを使用してテンプレートコンテンツをレンダリングするテンプレートを作成することです。

file { "/etc/tomcat/sites-available/default.conf":
   ensure => "present",
   content => template("tomcat/vhost.erb")
}

Puppetは、組織とモジュール性を強化するために、ローカルファイルを扱う際にほとんど仮定を行いません。 Puppetは、モジュールディレクトリ内のapache/templatesフォルダー内でvhost.erbテンプレートを探します。

サービスの定義とトリガー

Puppetには、特定のマシンまたは環境で実行されているすべてのサービスのライフサイクルを管理できるserviceというリソースがあります。 サービスリソースは、サービスが初期化および有効化されていることを確認するために使用されます。 また、サービスの再起動にも使用されます。

たとえば、以前のTomcatのテンプレートでは、apache仮想ホストを設定する場所があります。 仮想ホストの変更後にapacheを確実に再起動したい場合は、次のコマンドを使用してapacheサービスのサービスリソースを作成する必要があります。

service { 'tomcat':
   ensure => running,
   enable => true
}

リソースを定義するとき、再起動をトリガーするために通知オプションを含める必要があります。

file { "/etc/tomcat/sites-available/default.conf":
   ensure => "present",
   content => template("vhost.erb"),
   notify => Service['tomcat']
}