sudo -i puppet ssl clean sudo -i puppet agent --no-daemonize --verbose --onetime --pluginsync --detailed-exitcodes --noop --test ... Error: certificate verify failed [unable to get local issuer certificate for CN=host1.example.com]
sudo -i puppet ssl clean sudo mv /etc/puppetlabs/puppet/ssl/crl.pem /etc/puppetlabs/puppet/ssl/crl.pem.bk sudo -i puppet agent --no-daemonize --verbose --onetime --pluginsync --detailed-exitcodes --noop --test # または sudo mv /etc/puppetlabs/puppet/ssl /etc/puppetlabs/puppet/ssl.bk
Warning: SSL_connect returned=1 errno=0 state=error: certificate verify failed: [unable to get issuer certificate for /CN=Puppet CA: puppet.example.com]
sudo mkdir /etc/puppetlabs/puppet/ssl sudo chown -R puppet:puppet /etc/puppetlabs/puppet/ssl sudo service puppetserver start
DAYS=30 cacert_pem=$(sudo -i puppet config print cacert) openssl x509 -in $cacert_pem -checkend $(( 86400 * $DAYS )) -enddate notAfter=Apr 1 05:06:07 2030 GMT Certificate will not expire
記事:
puppet v3のデフォルトが2分で、起動時にタイムアウトしてしまう事がある。
puppet v5のデフォルトは5分になっている。
sudo vim /etc/systemd/system/puppetserver.service.d/timeout.conf -- [Service] TimeoutStartSec=300 -- sudo systemctl daemon-reload systemctl show puppetserver -p TimeoutStartUSec TimeoutStartUSec=5min
-- vim /etc/sysconfig/puppetserver START_TIMEOUT=300 --
exec { "tmp-exist": command => "false", unless => "test -f /tmp/example.tmp", path => ["/usr/bin", '/bin'], }
puppet.confに未定義だが、デフォルト値を確認したい時など。
sudo puppet config print --section master
# puppet 3.8.x sudo puppet config print vardir --section master /var/lib/puppet
sudo puppet master --configprint modulepath
[master] ... modulepath=/etc/puppetlabs/code/environments/production/modules:/etc/puppetlabs/code/modules:/opt/puppetlabs/puppet/modules
Older (> 3 years old) releases are regularly removed from this reposit
puppetlabs_archive_enabled: yes puppetlabs_archive_yum_repository: - name: "puppetlabs-products-archives" description: "Puppet Labs Products El $releasever - $basearch" baseurl: "http://release-archives.puppet.com/yum/el/$releasever/products/$basearch" - name: "puppetlabs-deps-archives" description: "Puppet Labs Dependencies El $releasever - $basearch" baseurl: "http://release-archives.puppet.com/yum/el/$releasever/dependencies/$basearch"
- name: install archive repository yum_repository: name: "{{ item.name }}" description: "{{ item.description }}" baseurl: "{{ item.baseurl }}" enabled: yes gpgcheck: no state: "{{ 'present' if puppetlabs_archive_enabled else 'absent' }}" with_items: "{{ puppetlabs_archive_yum_repository }}"
三項演算子同じような処理がしたい時
$enabled = versioncmp($mysql_version, '5.5') == 0 ? { true => 1, default => 0 }
class example( enabled = false ){ file { '/opt/example': mode => 755, force => true, ensure => str2bool($enabled) ? { true => directory, default => absent }; '/opt/example/start.sh': mode => 755, ensure => str2bool($enabled) ? { true => file, default => absent }, require => File['/opt/example'], content => template('example/start.erb'); } }
package { ['python-setuptools', 'python-pip']: ensure => 'installed' } -> file { '/usr/bin/pip-python': ensure => 'link', target => '/usr/bin/pip', require => Package["python-pip"] }
package { 'awscli': provider => 'pip', ensure => 'installed', }
cat /etc/puppet/puppet.conf [main] ... http_proxy_host = <proxy-host or IP> http_proxy_port = <8080>
sudo cat /etc/squid/squid.conf ... acl SSL_ports port 443 # https acl SSL_ports port 8140 # puppet acl Safe_ports port 80 # http acl Safe_ports port 443 # https acl CONNECT method CONNECT http_port 8080
curl -x proxy-host:8080 https://puppetmaster:8140/ curl: (56) Received HTTP code 403 from proxy after CONNECT ...
curl https://puppetmaster:8140/ curl: (60) Peer certificate cannot be authenticated with known CA certificates ...
ハッシュで複数項目を定義して、複数回のリソース(ファイル等)呼び出し時に利用できる。
hieraからhashを渡す時にも使える。
class test::main( $files = { '/var/log/messages' => { 'mode' => '0640', 'group' => 'wheel', }, } ){ $defaults = { ensure => file, notify => Service['td-agent'], } create_resources('file', $files) # 標準のfileリソースを使う場合 # create_resources('test::set_attr', $files, $defaults) # 独自のdefineを使う場合 } define test::set_attr( $ensure = file, $mode = '0640', $owner = 'root', $group = 'wheel' ) { file { "${title}": ensure => $ensure, mode => $mode, owner => $owner, group => $group, } }
puppet agent --color=false --no-daemonize --verbose --onetime --pluginsync --noop
-define('ZBX_GRAPH_FONT_NAME', 'DejaVuSans'); // font file name +define('ZBX_GRAPH_FONT_NAME', 'ipagp'); // font file name
exec { "/usr/bin/perl -pi.bak -e \"s/ZBX_GRAPH_FONT_NAME\',\\s+\'DejaVuSans/ZBX_GRAPH_FONT_NAME\', \'ipagp/\" 'defines.inc.php'" : onlyif => "/usr/bin/perl -ne \"BEGIN { \\\$ret = 1; } \\\$ret = 0 if /ZBX_GRAPH_FONT_NAME\',\\s+\'DejaVuSans/ ; END { exit \\\$ret; }\" 'defines.inc.php'", }
# manifest側 $var="hoge" # template側 <%= "var="+@var if var != "" %>
# manifest側 $logfile=undef # template側 <%- unless @logfile.nil? -%> logfile <%= @logfile %> <%- end -%>
Error: Could not retrieve catalog from remote server: SSL_connect returned=1 errno=0 state=SSLv3 read server session ticket A: sslv3 alert certificate revoked
service puppetmaster restart
sudo puppet cert list --all | grep "certificate revoked" | awk '{gsub("\"","",$2);print $2}'
puppet node clean [hostname]
sudo find /var/lib/puppet/ssl/ -name '*.pem' -delete sudo puppet agent --server master.example.com --no-daemonize --verbose --onetime --pluginsync --noop --test
sudo puppet cert list sudo puppet cert sign agent.example.com # certを個別に削除する場合 sudo puppet cert clean agent.example.com # certを全部削除する場合。この場合、puppetserverの再起動が必要 sudo find /var/lib/puppet/ssl/ -name '*.pem' -delete sudo service puppetserver restart
puppetでこのエラーが出て調べた所、facterのエラーメッセージだった。
なぜか、t1.microで発生し、m1.smallでは発生しなかった。
# error facter Illegal instruction # env cat /etc/redhat-release CentOS release 6.2 (Final) rpm -qa | grep ruby | sort ruby-1.8.7.352-13.el6.x86_64 ruby-libs-1.8.7.352-13.el6.x86_64 rpm -qa | grep facter facter-2.1.0-1.el6.x86_64
exec { "add_resolv_conf": path => "/usr/local/bin/:/bin:/usr/sbin", command => "sed -i -e '1inameserver 127.0.0.1' /etc/resolv.conf", unless => "grep -P '^nameserver\s+127.0.0.1' /etc/resolv.conf"; }
puppet masterの/var/lib/puppet/reports/に古い*.yamlが貯まって、ディスクが溢れる場合がある。
sudo crontab -e ---- 5 1 * * * /bin/find /var/lib/puppet/reports/ -type f -name "*.yaml" -mtime +7 -delete 2>&1 | logger -i -t delete-puppet-reports ----
sudo vim /etc/puppet/puppet.conf ---- [main] ... reports=none ---- sudo service puppetmaster restart
sudo gem install r10k r10k help
sudo r10k deploy environment <ENV-NAME> -p -v
cron { 'test': ensure => present, user => 'user01', hour => '*', minute => fqdn_rand(60), command => "/tmp/test.sh > /dev/null 2>&1"; }
notice("message")
notify {"message":} # リソースフルパスも表示 notify {"message": withpath => true}
cd /etc/puppet/modules puppet module install puppetlabs/mysql
vim /etc/puppet/manifests/example.pp ---- $mysql_root_password='YOUR ROOT PASSWORD' file { '/root/.my.cnf': ensure => file, content => " [client] user=root host=localhost password='$mysql_root_password' "; } database_user { 'bob@%': password_hash => mysql_password('foo'); 'bob@localhost': password_hash => mysql_password('foo'); } database_grant { 'bob@%': privileges => ['Select_priv']; 'bob@localhost': privileges => ['Select_priv']; } ----
vim /etc/puppet/puppet.conf ---- [master] reports = tagmail,daily,security reportfrom = puppetmaster@example.com ---- vim /etc/puppet/tagmail.conf ---- all: user01@example.com ---- service puppetmaster restart
vim /etc/puppet/puppet.conf ---- [agent] report=true ----
サーバに常駐して指定したプロセスを監視し、落ちたら自動的に再起動等を設定できる
fluentdの安定版であるtd-agentをpuppetでインストール
wget -O puppet-module-tdagent.zip https://github.com/ziguzagu/puppet-module-tdagent/archive/master.zip unzip puppet-module-tdagent.zip mv puppet-module-tdagent-master /etc/puppet/modules/td-agent rm puppet-module-tdagent.zip cd /etc/puppet/modules/ patch -p0 < puppet-module-td-agent.centos.patch # 対象ホストを許可 vim /etc/puppet/fileserver.conf ---- [plugins] allow *.localdomain ----
node default { include 'td-agent' package { [ 'fluent-plugin-datacounter', 'fluent-plugin-growthforecast' ]: ensure => 'installed', provider => 'fluentgem', require => Package['td-agent'], } }
puppet agent --server server.localdomain --no-daemonize --verbose --onetime --pluginsync
less /etc/yum.repos.d/td.repo chkconfig --list td-agent td-agent 0:off 1:off 2:on 3:on 4:on 5:on 6:off service td-agent status td-agent (pid 2923) を実行中... tree -a /etc/td-agent/ /etc/td-agent/ ├── conf.d ├── plugin ├── prelink.conf.d │ └── td-agent.conf ├── td-agent.conf └── td-agent.conf.tmpl 3 directories, 3 files
/usr/lib64/fluent/ruby/bin/gem list | grep fluent fluent-logger (0.4.3) fluent-mixin-config-placeholders (0.1.0) fluent-mixin-plaintextformatter (0.1.0) fluent-plugin-datacounter (0.4.0) fluent-plugin-flume (0.1.1) fluent-plugin-growthforecast (0.1.5) fluent-plugin-mongo (0.6.11) fluent-plugin-s3 (0.2.5) fluent-plugin-scribe (0.10.9) fluent-plugin-td (0.10.13) fluent-plugin-webhdfs (0.1.0) fluentd (0.10.30)
yum -y update td-agent yum -y install make gcc libxml2-devel libxslt-devel /usr/lib64/fluent/ruby/bin/gem update
yum erase td-agent td-libyaml rm -rf /etc/td-agent rm -rf /usr/lib64/fluent
wget -O master.zip https://github.com/danheberden/puppet-nodejs/archive/master.zip unzip master.zip sudo mv puppet-nodejs-master /etc/puppet/modules/nodejs sudo vi /etc/puppet/manifests/example/example.pp # CentOS向けパッチ patch -p0 < nodejs-init.pp.centos.patch # manifest ---- node default { class { 'nodejs': version => '0.8.16'; } } ---- # インストール後のバージョンの確認 node -v v0.8.16 npm -v 1.1.69
wget https://raw.github.com/isaacs/nave/master/nave.sh bash nave.sh uninstall 0.8.16
/.bashrc に追加
function puppet-validate() { local ext=${1##*.} case $ext in [pP][pP]) puppet parser validate "$1" ;; [eE][rR][bB]) erb -P -x -T '-' "$1" | ruby -c ;; [yY][aA][mM][lL]|[yY][mM][lL]) ruby -e "require 'yaml'; YAML.parse(File.open('$1'))" # find duplicate key egrep -v "^( |-|$|#)" $1 | cut -d' ' -f1 | sort | uniq -d -c ;; *) echo "ERROR: $1 is not supported" 1>&2 ;; esac }
source ~/.bashrc puppet-validate example.pp puppet-validate example.erb puppet-validate example.yaml
include test::test_file
node /^server\d+.localdomain/ { define test::define_test { if defined(File['/tmp/test.tmp']) == false { file { '/tmp/test.tmp': ensure => file, content => "test file", ; } } } test::define_test { "test1":; } test::define_test { "test2":; } }
puppet-master[3904]: Host is missing hostname and/or domain: example
facter -p | grep fqdn
HOST=test.example.com hostname $HOST HOSTNAME=`hostname` perl -p -i -e "s#localhost.localdomain localhost4 localhost4.localdomain4#$HOSTNAME#" /etc/hosts perl -p -i -e "s#localhost.localdomain#$HOSTNAME#" /etc/sysconfig/network
0, 2の場合は成功と見なして良い
puppet agent --server server.localdomain --no-daemonize --verbose --onetime --detailed-exitcodes echo $?
facter変数や任意のリソースタイプを追加できる
mkdir -p ~/lib/ruby/facter/ cp resolver.rb ~/lib/ruby/facter/ export RUBYLIB=~/lib/ruby facter nameservers 192.168.61.2
export FACTER_my_key1=value1 export FACTER_my_key2=value2 export FACTER_my_key3=value3 facter | grep my my_key1 => value1 my_key2 => value2 my_key3 => value3
sudo mkdir -p /etc/facter/facts.d/ sudo vim /etc/facter/facts.d/my.txt ---- my_key1=value1 my_key2=value2 my_key3=value3 ---- facter | grep my my_key1 => value1 my_key2 => value2 my_key3 => value3
vi /etc/puppet/puppet.conf ---- [main] ... pluginsync = true ---- service puppetmaster restart
mkdir -p /etc/puppet/modules/{MODULE_NAME}/lib/facter vi /etc/puppet/modules/{MODULE_NAME}/lib/facter/my.rb ---- Facter.add("my_var1") { setcode { "my_value1" } } Facter.add("my_var2") { setcode { "my_value2" } } ---- # puppetmaster側で確認 FACTERLIB=/etc/puppet/modules/{MODULE_NAME}/lib/facter:$FACTERLIB facter -p my_var1 my_value1 # agent側で確認 facter -p my_var1 my_value1
puppet agent --server server.localdomain --no-daemonize --verbose --onetime --pluginsync
--- ec2.rb +++ ec2.rb @@ -30,4 +30,7 @@ Timeout::timeout(1) { metadata } rescue Timeout::Error puts "ec2-metadata not loaded" +rescue => ex + # No route to host - connect(2) + puts "#{ex.class}\t#{ex.message}" end
puppet-module search aws
puppet-module install larstobi/dns
puppet-module install puppetlabs/cloud_provisioner
puppet-module install branan/s3file
service puppetmaster stop chkconfig puppetmaster off
sudo yum install httpd httpd-devel ruby-devel rubygems mod_ssl gcc-c++ curl-devel zlib-devel sudo gem install rack passenger
sudo passenger-install-apache2-module
mkdir -p /usr/share/puppet/rack/puppetmasterd/{public,tmp} cp /usr/share/puppet/ext/rack/files/config.ru /usr/share/puppet/rack/puppetmasterd/ chown puppet. /usr/share/puppet/rack/puppetmasterd/config.ru
cat >> /etc/httpd/conf.d/passenger.conf << 'EOS' # passenger.conf LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/passenger-3.0.17/ext/apache2/mod_passenger.so PassengerRoot /usr/lib/ruby/gems/1.8/gems/passenger-3.0.17 PassengerRuby /usr/bin/ruby EOS cat >> /etc/httpd/conf.d/puppetmaster.conf << 'EOS' # puppetmaster.conf # Performance #PassengerPoolIdleTime 300 # default: 300 PassengerUseGlobalQueue on PassengerMaxPoolSize 60 Listen 8140 <VirtualHost *:8140> SSLEngine on SSLCipherSuite SSLv2:-LOW:-EXPORT:RC4+RSA SSLCertificateFile /var/lib/puppet/ssl/certs/puppet-001.example.com.pem SSLCertificateKeyFile /var/lib/puppet/ssl/private_keys/puppet-001.example.com.pem SSLCertificateChainFile /var/lib/puppet/ssl/certs/ca.pem SSLCACertificateFile /var/lib/puppet/ssl/certs/ca.pem # CRL checking should be enabled; if you have problems with Apache complaining about the CRL, disable the next line SSLCARevocationFile /var/lib/puppet/ssl/ca/ca_crl.pem SSLVerifyClient optional SSLVerifyDepth 1 SSLOptions +StdEnvVars # The following client headers allow the same configuration to work with Pound. RequestHeader set X-SSL-Subject %{SSL_CLIENT_S_DN}e RequestHeader set X-Client-DN %{SSL_CLIENT_S_DN}e RequestHeader set X-Client-Verify %{SSL_CLIENT_VERIFY}e PassengerHighPerformance on # DO NOT USE Global config!!(disable mod_rewrite) RackAutoDetect On RackBaseURI / DocumentRoot /usr/share/puppet/rack/puppetmasterd/public/ CustomLog /var/log/httpd//puppet_access_log combined ErrorLog /var/log/httpd//puppet_error_log <Directory /usr/share/puppet/rack/puppetmasterd/> Options None AllowOverride None Order Allow,Deny Allow from all </Directory> </VirtualHost> EOS service httpd restart
sudo passenger-status sudo passenger-memory-stats
vi /usr/share/puppet/rack/puppetmasterd/config.ru ---- ARGV << "--masterport=8140" ----
yum -y install rubygems ruby-devel gem install mongrel --include-dependencies vi /etc/rc.d/init.d/puppetmaster ---- PUPPETMASTER_OPTS="--servertype mongrel" ---- service puppetmaster restart
puppet module search apache puppet module install puppetlabs/apache
# インストール sudo gem install puppet-module # README確認 puppet-module usage # ヘルプ puppet-module help # 検索 puppet-module search apache # インストール(カレントディレクトリにインストールされるので注意) cd /etc/puppet/modules/ puppet-module install puppetlabs/apache
マニフェスト,テンプレート,ファイルのセット
iptablesを設定してくれる
特定リソースだけ実行したいなどに使える。
file { '/etc/hosts': owner => 'root', group => 'root', mode => 644, tag => 'hosts', } file { '/etc/sudoers': owner => 'root', group => 'root', mode => 440, tag => 'sudoers', }
sudo puppetd --tags hosts,sudoers
class ssh { # package { 'sshd': ensure => present, tag => 'ssh' } と同じ package { 'sshd': ensure => present } # service { 'sshd': ensure => running, tag => 'ssh' } と同じ service { 'sshd': ensure => running } }
デフォルトでは30分でagentがpuppetmasterに取りに行くが、任意のタイミングで実行させたい時にpuppetrunが使える
masterからagentへファイルを配布できる
sudo /usr/sbin/puppetmasterd --no-daemonize --verbose notice: Starting Puppet master version 2.6.17 Could not run: Invalid mount files vi /etc/puppet/fileserver.conf ---- [files] # path /var/lib/puppet/files ----
OSのコマンドの違いを吸収してくれる中間レイヤー
vim /etc/puppet/fileserver.conf ---- [plugins] allow *.localdomain ----
package { 'ntp': provider => 'yum', ensure => 'present', } # packageリソースタイプのデフォルトプロバイダを指定 Package { provider => 'yum' }
masterからagentへ操作(puppet kick)したい時
vi /etc/puppet/namespaceauth.conf ---- # puppetdからのマニフェスト取得アクセスのコントロール [puppetmaster] allow *.example.org deny deny.example.org # puppetdからのレポート通知アクセスのコントロール [puppetreports] allow *.example.org deny deny.example.org # puppetdからのファイルサーバ機能へのアクセスコントロール [fileserver] allow *.example.org deny deny.example.org ----
vi /etc/puppet/auth.conf ---- path /run method save allow server.localdomain ----
sudo puppet agent --no-daemonize -d -v -l console --no-client --listen
sudo puppet kick --host agent01.localdomain --debug
notice('Something weird is going on') notice 'Something weird is going on'
<%= ipaddress.split(".")[3] %>
<%= ipaddress.split(".").length %>
$sudo = $operatingsystem ? { freebsd => 'security/sudo', default => 'sudo', }
case $operatingsystem { openbsd: {} default: { package { 'sudo': ensure => present } } }
if $boolean { file { '/some/file': ensure => present } } else { file { '/some/other/file': ensure => present } }
# =~, !~ if $host =~ /^www(\d+)\./ { notice('Welcome web server #$1') }
$eatme = 'eat' if $eatme in ['ate', 'eat'] { ... }
# manifest側 $vars=[ '1', '2', '3' ] # template側 csv='<% @vars.each_with_index do |var, i| -%><%= var %><%= "," if i < (vars.size - 1) %><% end -%>'
$default_owner = 'root' $default_group = 'root' #$default_owner = 'hoge'; # エラー #$default_owner => 'hoge'; # エラー file { '/etc/hosts': #$default_owner = 'hoge'; # エラー #$default_owner => 'hoge'; # エラー owner => $default_owner, group => $default_group, }
$owner = 'root' define testing { $owner = 'nobody' }
/var/lib/puppet/yaml/facts/[NODENAME].yaml
worker_processes <%= processorcount %>;
$vars=[ '1', '2', '3' ] service { 'ntpd': ensure => running, require => [ File['ntpd.conf'], User['ntp'], Package['ntp'] ], }
$ntp_server=[ 'ntp.nict.jp', 'ntp.jst.mfeed.ad.jp', 'ntp.ring.gr.jp' ]
<% ntp_server.each do |val| -%> server <%= val %> <% end -%>
$sites = { 'site01' => { 'title' => 'sample01', 'url' => 'http://www01.example.com/'. }, 'site02' => { 'title' => 'sample02', 'url' => 'http://www02.example.com/'. } }
<% sites.keys.sort.each do |id| -%> <%= id %>, <%= sites[id]['title'] %>, <%= sites[id]['url'] %> <% end -%>
$var1_class=inline_template("<%= $var1.class %>") notify { "$var1": message => "class: $var1_class" }
facter -p architecture => x86_64 augeasversion => 0.10.0 hostname => server fqdn => server.localdomain kernel => Linux ...
export FACTER_system_role=`cat /etc/system_role`; facter # puppet実行時でも可能 FACTER_system_role=dev puppet agent --noop --test
host { 'ntp.example.com': ensure => 'present', # uninstall: absent ip => '10.100.10.20', host_aliases => 'timeserver' }
node /^server\d+.localdomain/ { @file{ '/tmp/test.tmp': ensure => file, content => "test file", ; } define test::realize_test { realize(File["/tmp/test.tmp"]) } test::realize_test { "test1":; } test::realize_test { "test2":; } }
node /^server\d+.localdomain/ { define test::mkfile( $body="" ){ file { "$title": ensure => file, content => $body, ; } } @test::mkfile{ '/tmp/test.tmp': body => "test file", ; } define test::realize_test { realize(Test::Mkfile["/tmp/test.tmp"]) } test::realize_test { "test1":; } test::realize_test { "test2":; } }
マニフェストでリソースの依存関係を定義できる
package { 'php-mysql': ensure => 'absent', provider => 'rpm', before => Package['php-mysqlnd'], uninstall_options => ['--nodeps']; 'php-mysqlnd': ensure => 'installed'; }
define svn_repo($path) { exec { "/usr/bin/svnadmin create $path/$title": creates => "$path/$title", } }
svn_repo { puppet: path => '/var/svn' }
class apache { service { 'apache': require => Package['httpd'] } } class apache-ssl inherits apache { # host certificate is required for SSL to function Service[apache] { require +> File['apache.pem'] } }
class example ( ) { # backup define backup ( $user, $group, $path, $cron_hour=1, $cron_minute=5, $cron_ensure="absent" ) { # virtual resource @file { "${path}": ensure => directory, ; } realize(File["${path}"]) file { "${path}/backup.sh": owner => $user, group => $group, mode => 755, source => "puppet:///modules/example/backup.sh"; } cron { "cron-backup.sh": require => File["${path}/backup.sh"], ensure => $cron_ensure, command => "/bin/nice ${path}/backup.sh > ${path}/backup.log 2>&1", user => $user, hour => $cron_hour, minute => $cron_minute, ; } } }
node 'web01.example.com' { include 'example' example:backup { 'default': user => 'root', group => 'root', path => "/root/bin", cron_hour => 1, cron_minute => 5, cron_ensure => "present", # present, absent ; } }
define test_a($a="aaa", $b=$a) { notice($a) # aaa notice($b) # undef } test_a {"hoge":;}
define print { notice("The value is: '${name}'") } define func_a { print { $name:; } } func_a {["a","b"]:;}
複数のリソースを一つにまとめ、名前を付けられる。
defineとの違いは、インスタンスの数。一つの場合はclass、複数の場合はdefine
class unix { file { '/etc/passwd': owner => 'root', group => 'root', mode => 644; } file { '/etc/shadow': owner => 'root', group => 'root', mode => 440; } exec { 'blah': path => '/usr/bin', cwd => '/tmp', } }
node 'client.example.com' { include 'unix' }
class freebsd inherits unix { File['/etc/passwd'] { group => 'wheel' } File['/etc/shadow'] { group => 'wheel' } }
どのクライアントに適用させるかを記述する
node 'client.example.com' { file { '/etc/passwd': owner => 'root', group => 'root', mode => 644; } }
node 'mail.example.com' { file { ...省略 } } node 'www.example.com' { file { ...省略 } } node default { file { ...省略 } }
node base { file { ...省略 } } node 'client1.example.com' inherits base { } node 'client2.example.com' inherits base { }
# www01.example.com, www02.example.com 等にマッチ node /^www(\d+)\./ { ... }
#geshMemo/Puppet#uebe2935]]を使う
puppet-master[3904]: Host is missing hostname and/or domain: example
facter -p | grep fqdn
HOST=test.example.com hostname $HOST HOSTNAME=`hostname` perl -p -i -e i(dos){{ $HOME/.vim/
$HOME/vimfiles/
yum install vim-enhanced mkdir -p ~/.vim/ cp -r /usr/share/vim/vimfiles/ftdetect ~/.vim/ cp -r /usr/share/vim/vimfiles/syntax ~/.vim/
特定ドメインだけ自動承認させる事で、サーバ側で「puppetca sign」する手間が省ける
cat >> /etc/puppet/autosign.conf << 'EOS' client.example.org *.example.com *.local *.localdomain #*.internal EOS service puppetmaster restart # 確認 service puppetmaster genconfig | grep autosign autosign = /etc/puppet/autosign.conf # 後は autosign.conf への変更は puppetmaster の再起動は不要
vi /etc/puppet/puppet.conf ---- [main] autosign = true ---- service puppetmaster restart
vi /etc/puppet/puppet.conf ---- [main] # [クライアントのFQDN or IPAddress] certname=agent01.localdomain ---- find /var/lib/puppet/ssl/ -name '*.pem' -delete service puppet restart
+---mbc1=000000 ex + # No route to host - connect(2) + puts anifests | | nodes.pp | | site.pp | | templates.pp | | | \---example | example.pp | \-- [client] user=root host=localhost password='$mysql_root_password' -modules +---centos | +---files | +---manifests | | init.pp | | | \---templates +---httpd-document-root | +---files | | .htaccess | | robots.txt | | | +---manifests | | init.pp | | | \---templates | index.html.erb | \---puppetclient +---files +---manifests | init.pp | \---templates puppet.conf.erb
# 展開されない $value = '$one' # 展開される $value = "$one" $value = "${one}two"
true false define inherits class
import 'other.pp' import 'classes/*' import 'packages/[a-z]*'
/etc/puppet/manifests/site.pp
file { '/etc/hosts': owner => 'root', group => 'root', mode => 644, }
# 2.7.x puppet parser validate manifests/site.pp # 2.6.x puppet --parseonly manifests/site.pp
# 2.7.x puppet agent --noop --test # 2.6.x puppet agent --noop
puppet apply manifests/site.pp
File { owner => 'root', group => 'root', mode => 644, } file { '/etc/hosts': ; '/etc/passwd': ; '/etc/group' : ; '/etc/sudoers': mode => 440; }
/etc/yum.repos.d/REPONAME.repo を作成するリソース
package { "vim-enhanced": ensure => present; }
package { がある。手動でwgetならうまくいくケースがある #geshi(bash){{ package { 'zabbix-jp-release':0 ensure => installed, provider => rpm, source => 'http://www.zabbix.jp/binaries/relatedpkgs/rhel6/x86_64/zabbix-jp-release-6-5.noarch.rpm' }
exec { 'wget-zabbix-jp-release': cwd => "/tmp/", path => ["/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin"], user => "root", timeout => 600, command => "wget -q 'http://www.zabbix.jp/binaries/relatedpkgs/rhel6/x86_64/zabbix-jp-release-6-5.noarch.rpm' && rpm -i --oldpackage zabbix-jp-release-6-5.noarch.rpm && rm -f zabbix-jp-release-6-5.noarch.rpm", creates => "/usr/share/zabbix-jp-release"; } package { 'zabbix-jp-release': ensure => installed, require => Exec['wget-zabbix-jp-release']; }
package {"epel-release": provider=>rpm, ensure=>installed, install_options => ['--nodeps'], source=>"http://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm", }
package { "openssl": provider => "rpm", ensure => ["1.0.1e-30.el6.8", "1.0.1e-30.el6.8"], source => ["rpms/openssl-devel-1.0.1e-30.el6.8.x86_64.rpm","rpms/openssl-1.0.1e-30.el6.8.x86_64.rpm"], }
@package { "gcc": ensure => installed; "gcc-c++": ensure => installed; "make": ensure => installed; "e2fsprogs-devel": ensure => installed; } realize(Package["make"], Package["gcc"], Package["gcc-c++"], Package["e2fsprogs-devel"]) exec { 'install-extundelete': cwd => "/tmp/", path => ["/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin"], user => "root", timeout => 600, command => "wget -O extundelete-0.2.0.tar.bz2 'http://downloads.sourceforge.net/project/extundelete/extundelete/0.2.0/extundelete-0.2.0.tar.bz2?r=http%3A%2F%2Fsourceforge.net%2Fprojects%2Fextundelete%2F&ts=1347001409&use_mirror=jaist' && tar xvfj extundelete-0.2.0.tar.bz2 && cd extundelete-0.2.0 && ./configure && make && make install && cd .. && rm -rf extundelete-0.2.0.tar.bz2 extundelete-0.2.0", creates => "/usr/local/bin/extundelete", require => [Package["make"], Package["gcc"], Package["gcc-c++"], Package["e2fsprogs-devel"]]; }
file { '/etc/httpd/conf.d/welcome.conf': ensure => absent, require => Package['httpd'], ; }
file { '/tmp/dummy': ensure => file, mode => 644, content => "dummy file", ; }
file { '/etc/hosts': owner => 'root', group => 'root', mode => 644, ; }
file { [ "/tmp/var/", "/tmp/var/foo" ]: ensure => directory; }
file { '/etc/localtime': ensure => link, target => "/usr/share/zoneinfo/Asia/Tokyo", }
file { '/tmp/example.conf': path => "/tmp/example.conf", ensure => file, mode => 644, source => "puppet:///modules/module_name/example.conf"; }
# puppet-server-2.6.17-2.el6.noarch OK: なし OK: .tar OK: .conf OK: .gz OK: .hoge.gz OK: .tar.bz2 NG: .tar.gz
# facter変数 hostname=<%= hostname %>
file { '/tmp/example.conf': path => "/tmp/example.conf", ensure => file, mode => 644, content => template("module_name/example.conf.erb"); }
<% ntp_server.each do |val| -%> server <%= val %> <% end -%>
class my-ntp ( $package_version='latest', $ntp_server=[ 'ntp.nict.jp', 'ntp.jst.mfeed.ad.jp', 'ntp.ring.gr.jp' ] ) { package { "ntp": ensure => $package_version } service { "ntpd": enable => true, ensure => running, require => Package["ntp"]; } exec { "/sbin/chkconfig --add ntpd": cwd => "/etc", unless => "/bin/ls /etc/rc3.d | grep ntp" } exec { "/bin/mv localtime localtime.org;/bin/ln -s /usr/share/zoneinfo/Japan /etc/localtime": cwd => "/etc", onlyif => "/usr/bin/test ! -h /etc/localtime.org" } file { "/etc/ntp.conf": path => "/etc/ntp.conf", ensure => file, require => Package[ntp], content => template('my-ntp/ntp.conf.erb'), notify => Service["ntpd"]; } }
user { 'testuser': name => 'testuser', password => 'test123', managehome => true, groups => 'wheel', }
service puppetmaster genconfig # モジュールパス service puppetmaster genconfig | grep -i modulepath modulepath = /etc/puppet/modules:/usr/share/puppet/modules # Factパス service puppetmaster genconfig | grep -i factpath factpath = /var/lib/puppet/lib/facter:/var/lib/puppet/facts
puppetca generate hostname # 以下に作成される /var/lib/puppet/ssl/
puppetca list # 認証済みも表示 puppetca --all list
puppetca sign hostname
puppetca revoke hostname
puppetca clean hostname #全ての認証リクエストの削除 puppetca clean --all
puppetca print hostname
puppet kick --host hostname
puppet kick --host hostname --tag newsetting
# 2.7.x puppet parser validate manifests/site.pp # 2.6.x puppet --parseonly manifests/site.pp
# 2.7.x puppet agent --noop --test # 2.6.x puppet agent --noop
puppet apply manifestでなくs/site.pp
cat >> ~/.bashrc << 'EOS' alias puppet-agent='puppet agent --server server.localdomain --no-daemonize --verbose --onetime --pluginsync' EOS # dry-run puppet-agent --noop # exec puppet-agent
puppet agent --server=server.localdomain --no-daemonize --verbose --onetime --pluginsync echo $? # 0: エラーがあっても0が返る
service puppet genconfig
puppet agent --test --debug
puppet resource service httpd
puppet resource service service { 'httpd': ensure => 'stopped', enable => 'false', } service { 'iptables': ensure => 'running', enable => 'true', } service { 'ntpd': ensure => 'running', enable => 'true', }
puppet resource package package { 'httpd': ensure => '2.2.3-65.el5.centos', } package { 'iptables': ensure => '1.3.5-9.1.el5', } package { 'iptables-ipv6': ensure => '1.3.5-9.1.el5', }
sudo rpm -ivh https://yum.puppetlabs.com/el/6/products/x86_64/puppetlabs-release-6-7.noarch.rpm sudo yum install puppet
vi /etc/sysconfig/iptables ---- # puppet-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 8140 -j ACCEPT ---- service iptables restart hostname agent01.localdomain echo "127.0.0.1 agent01.localdomain" >> /etc/hosts echo "192.168.1.100 server.localdomain" >> /etc/hosts yum install puppet --enablerepo=rpmforge vi /etc/sysconfig/puppet ---- PUPPET_SERVER=server.localdomain ---- vi /etc/puppet/puppet.conf ---- [main] # [クライアントのFQDN or IPAddress] certname=agent01.localdomain ---- service puppet restart chkconfig puppet on
puppetca list agent01.localdomain puppetca sign agent01.localdomain
tail -f /var/log/puppet/puppet.log
sudo rpm -ivh https://yum.puppetlabs.com/el/6/products/x86_64/puppetlabs-release-6-7.noarch.rpm sudo yum install puppet-server
vi /etc/sysconfig/iptables ---- # puppet-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 8140 -j ACCEPT ---- service iptables restart hostname server.localdomain echo "127.0.0.1 server.localdomain" >> /etc/hosts yum install puppet-server --enablerepo=rpmforge vi /etc/puppet/puppet.conf ---- [main] # [サーバのFQDN or IPAddress] certname=server.localdomain ---- service puppetmaster restart chkconfig puppetmaster on # 証明書確認。勝手にサーバ用のものが作られているはず puppetca list --all
tail -f /var/log/puppet/masterhttp.log