復習
前回の記事では、アプリケーションの導入・設定の自動化をgithubと連携させるという試みを行いました。その際に発見された問題点は次のとおり。
・gitはファイルのオーナやパーミッションが扱えない
・アプリケーションの導入スクリプトはバージョン管理されず、職人技が入り込みやすい
ここでは、これらを改善する方法として、導入スクリプトの代わりにPuppetを利用する方法を試してみます。
通常、Puppetは、Puppetサーバから設定を一元管理しますが、実は、Puppetは、クライアントオンリーモード(?)でも使用することができます。次のように、クライアント上に用意したマニフェストファイルを指定して、puppetコマンドを実行すると、一回限りの設定作業が実行されます。
# puppet Manifest.pp
そこで、アプリケーションの導入・設定をすべてPuppetのマニフェストとして記述するというのはどうでしょうか? マニファスト、およびマニフェストから配布する設定ファイルをまとめてgithubにあげれば、アプリケーションに固有の導入手順もマニフェストとしてバージョン管理できるようになります。
これにより、KickStartから呼び出すインストールスクリプト自体は、「指定のリポジトリからマニフェストを取得して適用する」という形でアプリケーションに依存しない一般的なものになるので、前述の課題がクリアできる気がします。
というわけで、これに挑戦してみます。
前提条件として、自動インストールツールvirt-construct.pyは、タグ「article03」のバージョンを使用します。インストール対象のOSは、RHEL6.xで、puppetはEPEL経由で導入します。
Puppetマニフェストの準備
前回の記事と同様に、PostgreSQLを自動インストール/自動設定します。これをPuppetで実施するために、次のファイルを用意します。
$ tree pgsql_puppet/ pgsql_puppet/ |-- dist | |-- pg_hba.conf | `-- postgresql.conf `-- main.pp
次のように、main.ppを指定してpuppetを実行すると、必要なインストール作業が行われるように構成します。
# puppet main.pp
ここでは、次のようなマニフェストを用意しました。(マニフェストの書き方は、一夜漬けなので、変な部分があってもご容赦ください。)
main.pp
import 'variables.pp' class pgsql { service { 'postgresql': name => 'postgresql', ### ensure => running, enable => true, subscribe => Package['postgresql-server'], } package { 'postgresql-server': name => 'postgresql-server', ensure => installed, } file { '/var/lib/pgsql/data/postgresql.conf': owner => 'postgres', group => 'postgres', mode => '0600', source => "$manifest_dir/dist/postgresql.conf", notify => Service['postgresql'], require => Exec['initdb'], } file { '/var/lib/pgsql/data/pg_hba.conf': owner => 'postgres', group => 'postgres', mode => '0600', source => "$manifest_dir/dist/pg_hba.conf", notify => Service['postgresql'], require => Exec['initdb'], } exec { 'initdb': path => '/sbin', command => 'service postgresql initdb', logoutput => true, creates => '/var/lib/pgsql/data/PG_VERSION', before => Service['postgresql'], require => Package['postgresql-server'], notify => Exec['init_pw'], ; 'init_pw': path => ['/sbin', '/bin'], command => 'service postgresql start && \ su - postgres -c "psql -w -c \ \"ALTER USER postgres encrypted password \'pas4pgsql\'\"" && \ service postgresql stop', logoutput => true, refreshonly => true, before => [Service['postgresql'], File['/var/lib/pgsql/data/pg_hba.conf'], File['/var/lib/pgsql/data/postgresql.conf']], ; } } include 'pgsql'
冒頭でimportしているvariables.ppは、配布する設定ファイルdist/*のベースディレクトリ名を$manifest_dirに設定するものです。この一連のファイル群がgithubからダウンロードされて、「/tmp/gittmp/<レポジトリ名>」以下に展開される前提となっており、このディレクトリを$manifest_dirにセットします。
variables.pp
$manifest_dir = '/tmp/gittmp/pgsql_puppet'
このファイル(variables.pp)自体は、KickStartから自動実行する際に動的に生成します。dist以下の設定ファイル(postgresql.conf、pg_hba.conf)は、好みの設定にしておきます。
そして、用意したマニフェストと設定ファイル一式をgitの管理下において、githubにアップロードしておきます。(githubでのリポジトリ作成、登録はできているという前提です。)これには、「v1_0」というタグを振っておきます。
# cd pgsql_puppet # git commit -m "First release" # git tag v1_0 # git push --tags
実際にアップロードしたものは、こちらにあります。
KickStartからの自動インストール
KickStartのpostセクションで次のスクリプトを実行すると、githubから必要なマニフェストを取得して、アプリケーション(PostgreSQL)の導入・設定が行われます。
## Application deployment template yum -y install http://mirror.us.leaseweb.net/epel/6/i386/epel-release-6-7.noarch.rpm yum -y install puppet #---------------------------------# # Specify your repository and tag # #---------------------------------# GitRepository=https://github.com/enakai00/pgsql_puppet.git ConfigTag=v1_0 RepoName=${GitRepository##*/} RepoName=${RepoName%.git} rm -rf /tmp/gittmp mkdir -p /tmp/gittmp cd /tmp/gittmp git clone $GitRepository cd $RepoName [[ ! -z $ConfigTag ]] && git checkout $ConfigTag echo "\$manifest_dir = '/tmp/gittmp/$RepoName'" > variables.pp puppet main.pp
冒頭の「GitRepository」「ConfigTag」で使用するリポジトリとタグを指定する以外は、完全に汎用的な作りになっています。アプリケーションの導入・設定手順は、リポジトリから取得するマニフェストに隠蔽されているわけです。
これを先の「virt-construct」ツールから一気通貫で実行できるようにvirt-constructの設定ファイルに埋め込んだものが、こちらになります。(設定ファイルの仕様上、一部、エスケープ用の\記号が追加されています。)
実際の実行結果(postセクションの実行ログ)はこちらになります。
# cat anaconda-post.log + echo '192.168.122.99 pgsql01' + cat + yum -y install http://mirror.us.leaseweb.net/epel/6/i386/epel-release-6-7.noarch.rpm Loaded plugins: product-id, security, subscription-manager Updating certificate-based repositories. (中略) Installed: epel-release.noarch 0:6-7 Complete! + yum -y install puppet Loaded plugins: product-id, security, subscription-manager Updating certificate-based repositories. (中略) Installed: puppet.noarch 0:2.6.17-2.el6 Dependency Installed: augeas-libs.x86_64 0:0.9.0-4.el6 compat-readline5.x86_64 0:5.2-17.1.el6 facter.x86_64 0:1.6.6-1.el6 libselinux-ruby.x86_64 0:2.0.94-5.3.el6 ruby.x86_64 0:1.8.7.352-7.el6_2 ruby-augeas.x86_64 0:0.4.1-1.el6 ruby-libs.x86_64 0:1.8.7.352-7.el6_2 ruby-shadow.x86_64 0:1.4.1-13.el6 Complete! + GitRepository=https://github.com/enakai00/pgsql_puppet.git + ConfigTag=v1_0 + RepoName=pgsql_puppet.git + RepoName=pgsql_puppet + rm -rf /tmp/gittmp + mkdir -p /tmp/gittmp + cd /tmp/gittmp + git clone https://github.com/enakai00/pgsql_puppet.git Initialized empty Git repository in /tmp/gittmp/pgsql_puppet/.git/ + cd pgsql_puppet + [[ ! -z v1_0 ]] + git checkout v1_0 Note: checking out 'v1_0'. You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by performing another checkout. If you want to create a new branch to retain commits you create, you may do so (now or later) by using -b with the checkout command again. Example: git checkout -b new_branch_name HEAD is now at 5ef8f88... fix manifest dependency + echo '$manifest_dir = '\''/tmp/gittmp/pgsql_puppet'\''' + puppet main.pp warning: Could not retrieve fact fqdn notice: /Stage[main]/Pgsql/Package[postgresql-server]/ensure: created notice: /Stage[main]/Pgsql/Exec[initdb]/returns: データベースを初期化中: [ OK ] notice: /Stage[main]/Pgsql/Exec[initdb]/returns: executed successfully notice: /Stage[main]/Pgsql/Exec[init_pw]/returns: postgresql サービスを開始中: [ OK ] notice: /Stage[main]/Pgsql/Exec[init_pw]/returns: ALTER ROLE notice: /Stage[main]/Pgsql/Exec[init_pw]/returns: postgresql サービスを停止中: [ OK ] notice: /Stage[main]/Pgsql/Exec[init_pw]: Triggered 'refresh' from 1 events notice: /File[/var/lib/pgsql/data/postgresql.conf]/content: content changed '{md5}04246025b15a71bec286a19abffdcb82' to '{md5}4b7b7481f9bf86fdc7f887f65944aef4' notice: /File[/var/lib/pgsql/data/pg_hba.conf]/content: content changed '{md5}a21038ed8e80ad95d01da9cb6b0ae403' to '{md5}3d7342d0bc0c5e1700ccec5f2c5571fb' notice: /Stage[main]/Pgsql/Service[postgresql]/enable: enable changed 'false' to 'true' notice: /Stage[main]/Pgsql/Service[postgresql]: Triggered 'refresh' from 3 events notice: Finished catalog run in 28.50 seconds