LoginSignup
0
0

More than 5 years have passed since last update.

Puppet4.xではじめるサーバ設定自動化 7(ファイル変更)

Last updated at Posted at 2016-05-05

Puppet4.xではじめるサーバ設定自動化の、ファイル変更編です。
全体的な目次は、ここを参照してください。
主にCentOS 7を例に紹介しているので、その他OSについては読み替えてください。

※記載されている例は、その内容に関わる部分のみ記載しています。なので実際試す場合、親ディレクトリ作成、httpdインストールを別途行う必要があります。

ファイル変更

基本

ファイルを変更する場合、Puppetのマニフェストでfileリソースで定義します。
/tmp/hello_puppet.txtを変更する場合の例です。指定のパスにファイルがない場合は、ファイルが作成されます。

file01.pp
file { '/tmp/hello_puppet.txt':
  ensure  => "file",
  owner   => "root",
  group   => "root",
  mode    => "0644",
  content => "hello puppet\n",
}

  • fileの右側のタイトルに、ファイルのパスを指定
  • ensure属性に、fileを指定
  • owner属性に、ファイルの所有ユーザを指定
  • group属性に、ファイルの所有グループを指定
  • mode属性に、ファイルのパーミッッション(アクセス権限)を指定
  • content属性に、ファイルの中身を指定。

ファイル変更の場合、ensure属性は必須でないですが、ensure属性にfileを指定します。なお、ensure属性にabsentを指定すると、ファイルの削除ができます。ただ、ファイル削除する場合は慎重に。
content属性は、ファイルの中身です。ファイルの中身が数行程度であれば、上記例のように直接記載することもできます。

テンプレートファイルで置き換える

あらかじめ用意したファイルに置き換える場合、テンプレートとなるファイルをcontent属性に指定します。

file02.pp
file { "/etc/httpd/conf/httpd.conf":
  ensure  => "file",
  owner   => "root",
  group   => "root",
  mode    => "0644",
  content => template("apache/httpd.conf.erb"),
}

content属性に、ファイルの中身を直接記載せず、template関数(template())にテンプレートにするファイルのパスを指定します。拡張子erbが付いている理由は次回。例のfile02.ppを実行する場合、テンプレートにするファイルを次のように配置します。

.
|-- file02.pp
`-- modules
    `-- apache
        `-- templates
            `-- httpd.conf.erb

※puppet applyの場合のディレクトリ構成

下記コマンドで実行します。※Puppetだと、テンプレートファイルと同じ内容のファイルがすでに指定のパスにある場合、ファイルは変更されません。

/opt/puppetlabs/bin/puppet apply file02.pp --modulepath=modules -t

modulepathオプションで、どこにテンプレートファイルを置いてあるか指定します。例では、カレントディレクトリのmodulesディレクトリの下にテンプレートファイルがあるので、modulesを相対パスで指定してます。ちなみに、絶対パスでもよいです。

テンプレートファイルの置き場所は、ちょっとわかりにくいですが、modulepathオプションで指定するディレクトリの下に、モジュール名のディレクトリがあって、さらにその下にtemplatesディレクトリがあって、さらにその下にテンプレートファイルがあるイメージです。
(※modulesディレクトリの2個下に、templatesという名前のディレクトリがあるのが必須で、それより下のディレクトリ構成は自由です。)

テンプレートファイルをサーバごとに変える

同じマニフェストファイルを実行して、サーバごとに配布する設定ファイルを変えたい場合、content属性のtemplate関数に渡すパスを変えることで実現できます

file03.pp
#(1)
$httpd_tmpl = $hostname ? {
    "web01"  => "apache/web01/httpd.conf.erb",
    /^web.*/ => "apache/web/httpd.conf.erb",
    default  => "apache/default/httpd.conf.erb",
}

#(2)

file { "/etc/httpd/conf/httpd.conf":
  ensure  => "file",
  owner   => "root",
  group   => "root",
  mode    => "0644",
  content => template($httpd_tmpl),
}

この例では、(1)でサーバのホスト名を条件に、テンプレートファイルのパスを指定しています。ホスト名が、

  • web01の場合、apache/web01/httpd.conf.erb
  • 正規表現/^web.*/に一致する場合、apache/web/httpd.conf.erb
  • どれにも当てはまらない場合、apache/default/httpd.conf.erb

としています。(2)のcontentに、(1)で決まったテンプレートのパスを設定しています。なお、file03.ppを実行する場合、次のようなディレクトリ構成で、ファイルを用意しておきます。

.
|-- file03.pp
`-- modules
    `-- apache
        `-- templates
            |-- default
            |   `-- httpd.conf.erb
            |-- web
            |   `-- httpd.conf.erb
            `-- web01
                `-- httpd.conf.erb

※puppet applyの場合のディレクトリ構成

ファイル変更前にシンタックスチェックする

ファイル変更前にシンタックスチェックをしたい場合、validate_cmd属性にシンタックスチェック用コマンドを指定します。チェック用コマンドは、問題がない場合に0を返すコマンドを指定します。シンタックスチェックで問題があった場合、ファイル置き換え前にエラーになります。ちなみにドライランのnoopだと、残念ながらエラーになりません。

httpd.confのチェックをする場合の例です。チェックコマンドは、CentOS7の場合です。

file04.pp
file { "/etc/httpd/conf/httpd.conf":
  ensure       => "file",
  owner        => "root",
  group        => "root",
  mode         => "0644",
  content      => template("apache/httpd.conf.erb"),
  validate_cmd => "/usr/sbin/httpd -t -f %",
}

validate_cmd属性のコマンドの%は、コマンド実行時に配布するファイル名に置き換えられます。なお、コマンドは、フルパスで記載が必要です。validate_cmd属性は、puppet3.5以降で対応しています。

配布前にシンタックスチェックする機能は、設定ファイル変更直後に自動でリロードするようなミドルウェアなどで役立ちます。配布時チェックすることで、シンタックスエラーによるサービス影響を防げます。

実際に、シンタックスエラー時のログ例の一部です。

Error: Execution of '/usr/sbin/httpd -t -f /etc/httpd/conf/httpd.conf20160502-229-11sah4d' returned 1: AH00526: Syntax error on line 103 of /etc/httpd/conf/httpd.conf20160502-229-11sah4d:
<Directory> directive missing closing '>'
Error: /Stage[main]/Main/File[/etc/httpd/conf/httpd.conf]/content: change from {md5}f5e7449c0f17bc856e86011cb5d152ba to {md5}3cd7eaeebfd2554f9d26c0fcd5031a9d failed: Execution of '/usr/sbin/httpd -t -f /etc/httpd/conf/httpd.conf20160502-229-11sah4d' returned 1: AH00526: Syntax error on line 103 of /etc/httpd/conf/httpd.conf20160502-229-11sah4d:
<Directory> directive missing closing '>'

XMLのvalidate_cmd

参考までに、XML用のチェックコマンド例です。Rubyで正常に読めるかで判定しています。

file05.pp
file { "/tmp/puppet_sample.xml":
  ensure       => "file",
  owner        => "root",
  group        => "root",
  mode         => "0644",
  content      => template("sample/puppet_sample.xml.erb"),
  validate_cmd => "/opt/puppetlabs/puppet/bin/ruby -e \"require 'rexml/document'; REXML::Document.new(open('%'))\"",
}

YAMLのvalidate_cmd

参考までに、YAML用のチェックコマンド例です。Rubyで正常に読めるかで判定しています。

file06.pp
file { "/tmp/puppet_sample.yaml":
  ensure       => "file",
  owner        => "root",
  group        => "root",
  mode         => "0644",
  content      => template("sample/puppet_sample.yaml.erb"),
  validate_cmd => "/opt/puppetlabs/puppet/bin/ruby -e \"require 'yaml'; YAML.load_file('%')\"",
}

バイナリーファイルを配布する

バイナリーファイルを配布する場合、配布するバイナリーファイルをsource属性に指定します。

file07.pp
file { "/opt/gitbucket/4.0/gitbucket.war":
  ensure => "file",
  owner  => "root",
  group  => "root",
  mode   => "0644",
  source => "puppet:///modules/gitbucket/gitbucket.war",
}

source属性に、配布するバイナリーファイルのパスを指定します。template関数の指定と違って、puppet:///modulesがつくのに注意です。file07.ppを実行する場合、配布するファイルを次のように配置ます。

.
|-- file07.pp
`-- modules
    `-- gitbucket
        `-- files
            `-- gitbucket.war

※puppet applyの場合のディレクトリ構成

下記コマンドで実行します。

/opt/puppetlabs/bin/puppet apply file07.pp --modulepath=modules -t

modulepathオプションで、どこにバイナリーファイルが置いてあるか指定します。例では、カレントディレクトリのmodulesディレクトリの下にバイナリーファイルがあるので、modulesを相対パスで指定してます。ちなみに、絶対パスでもよいです。

バイナリーファイルの置き場所は、ちょっとわかりにくいですが、modulepathオプションで指定するディレクトリの下に、モジュール名のディレクトリがあって、さらにその下にfilesディレクトリがあって、さらにその下にバイナリーファイルがあるイメージです。
(※modulesディレクトリの2個下に、filesという名前のディレクトリがあるのが必須で、それより下のディレクトリ構成は自由です。)

ファイルをwebから取得する

Puppet 4.4.0から、fileリソースで直接HTTP,HTTPS経由のファイル取得ができるようになりました。source属性に、対象のURLを記載します。

file08.pp
file { "/opt/pssh/pssh-2.3.1.tar.gz":
  ensure => "file",
  owner  => "root",
  group  => "root",
  mode   => "0644",
  source => "https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/parallel-ssh/pssh-2.3.1.tar.gz",
}

ただし、直接ダウンロードできない場合(※接続先で、302リダイレクトされるとダメ?)もあるようなので、うまくいかない場合は、execリソースのwgetコマンドで代用します。

次の例では、creates属性で配布先にファイルがないことをチェックしてから、commandのwgetコマンドを実行しています。もし、ダウンロードに時間がかかりそうな場合、timeout属性でタイムアウトを十分長い時間に設定しておきます。デフォルト300秒を、例では600秒に変更。timeout属性を0に設定すると、タイムアウトしない設定になります。

file09.pp
exec { "wget gitbucket.war":
  command => "wget https://github.com/gitbucket/gitbucket/releases/download/4.0/gitbucket.war -P /opt/gitbucket/4.0",
  creates => "/opt/gitbucket/4.0/gitbucket.war", 
  path    => "/usr/bin",
  timeout => "600",
}

ファイルがすでにある場合変更しない

すでにファイルがあった場合に、ファイルの中身を変更したくないときは、replace属性にfalseを指定します。ファイルがないときだけ、ファイルを作りたい場合に使います。

file10.pp
file { '/tmp/hello_puppet.txt':
  ensure  => "file",
  owner   => "root",
  group   => "root",
  mode    => "0644",
  content => "hello puppet\n",
  replace => "false", 
}

参考

fileリソースの詳しい情報は、下記参照です。

テンプレートファイルをサーバごとに分岐させている部分は、下記参照です。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0