Puppet Master/Agent on Debian 7.8

Puppet Master/Agent構成をDebianで試す
====================================

# 免責事項

## 2015年2月時点での試行です

最新のPuppet/Debianを使用した場合、この通りに行かない可能性があります。

## 不正確です

できるだけ正確な記事を心がけていますが、おそらく不正確な場所があります。

## インセキュアです

ローカルでの試行なので、publicな場所での試行を想定したものではありません。

# 下準備

## 色々インストール

下記のソフトウェアをインストールします。

- Oracle VirtualBox 4.3.20
- Vagrant 1.7.2 (Box作成用)

## Debian 7.8 ISOをダウンロード

[ここ](https://www.debian.org/CD/http-ftp/#stable)から環境(amd64/x86)に合わせて適切なISOをダウンロードしておきます。

## セットアップ

VirtualBoxで普通にセットアップを行い、puppetインストール用のdebファイルを[ここ](https://apt.puppetlabs.com/)からダウンロードしてぶち込みます。

VirtualBox Guest Additionsは[公式ドキュメント](https://docs.vagrantup.com/v2/virtualbox/boxes.html)にしたがってコマンドライン経由でインストールします。

最終的にmaster/agentのbase boxを作るので、先ほどのdebファイルを`dpkg -i`したら[udevの設定周り](http://memo.saitodev.com/home/vagrant/)以外は特にいじらず、`vagrant package --base debian78-puppet --output debian78-puppet.box`というような感じでboxファイルを作成します。

# Master/Agent構成を作る

## :black_square_button: Vagrantfile

master用の仮想マシンと、agent用の仮想マシンの2つを用意します。

```rb:Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure(2) do |config|

  config.vm.box = "debian78-puppet"

  config.vm.define "puppet-master" do |ppm|

    ppm.vm.network "private_network", ip: "192.168.24.24"

    ppm.vm.hostname = "puppet-master"

    ppm.vm.provider "virtualbox" do |vb|
      # Customize the amount of memory on the VM:
      vb.memory = "512"
      # VB Name
      vb.name = "debian78-puppet-master"
    end

  end

  config.vm.define "puppet-agent" do |ppa|

    ppa.vm.network "private_network", ip: "192.168.24.25"

    ppa.vm.hostname = "puppet-agent"

    ppa.vm.provider "virtualbox" do |vb|
      # Customize the amount of memory on the VM:
      vb.memory = "512"
      # VB Name
      vb.name = "debian78-puppet-agent"
    end

  end

end
```

### 起動して色々変更・確認

- master/agent両方に、/etc/hostsのエントリーを追加しておく
- `telnet puppet-master 8140`でmaster側の8140ポートに入れることを確認しておく(入れなければiptables/selinux等を無効化、ただdebianを素のままインストールした場合は両方とも最初から無効化されているはず…)


## :black_square_button: Puppet Masterを設定する

### puppetのインストール

インストール可能なパッケージが2種類(puppetmaster/puppetmaster-passenger)あるようなのですが、基本puppetmaster-passengerをインストールすればオッケーだと思います。puppetmaster-passengerの依存パッケージにpuppetmasterが入っているので。

```shell-session:shell
$ sudo apt-get install puppetmaster-passenger
```

### puppet.confの編集

`$ sudo nano /etc/puppet/puppet.conf`でpuppet.confを開いて下記の内容を設定します。

```ini:/etc/puppet/puppet.conf
[main]
logdir=/var/log/puppet
vardir=/var/lib/puppet
ssldir=/var/lib/puppet/ssl
rundir=/var/run/puppet
factpath=$vardir/lib/facter
templatedir=$confdir/templates
certname=puppet-master
certificate_revocation=false
dns_alt_names=puppet-master,puppet-master.local

[master]
# These are needed when the puppetmaster is run by passenger
# and can safely be removed if webrick is used.
ssl_client_header = SSL_CLIENT_S_DN
ssl_client_verify_header = SSL_CLIENT_VERIFY
autosign=true
ca_name='Puppet CA on puppet-master'
```

### puppetmasterをスタートしておく

どうもapache2が起動している状態だとrun出来ないぽいのでapache2を止めてからスタートさせます。

```shell-session:shell
$ sudo service apache2 stop
$ sudo puppet master --no-daemonize --verbose
```

これでmasterはagentからのcertificate requestを待っている状態になります。

## :black_square_button: Puppet Agentを設定する

### puppetをインストールする

masterと同じようにインストールします。

```shell-session:shell
$ sudo apt-get install puppet
```

masterと同じようにpuppet.confを設定します。

```ini:/etc/puppet/puppet.conf
[main]
logdir=/var/log/puppet
vardir=/var/lib/puppet
ssldir=/var/lib/puppet/ssl
rundir=/var/run/puppet
factpath=$vardir/lib/facter
templatedir=$confdir/templates

[master]
# These are needed when the puppetmaster is run by passenger
# and can safely be removed if webrick is used.
ssl_client_header = SSL_CLIENT_S_DN
ssl_client_verify_header = SSL_CLIENT_VERIFY

[agent]
server=puppet-master
certname=puppet-agent
environment=develop
```

## :black_square_button: Provisioningしてみる

### moduleのインストール

```shell-session:shell
$ puppet module install puppetlabs-stdlib
```

### site.ppの作成

下記の内容でsite.ppを作成します。


```puppet:/etc/puppet/manifests/site.pp
node 'puppet-agent' {
  include stdlib

  # /opt/htdocsというディレクトリを作る
  file { '/opt/htdocs':
    ensure => directory,
  }
}
```

### 手動でやってみる

```shell-session:shell
$ sudo puppet agent --test
Warning: Setting templatedir is deprecated. See http://links.puppetlabs.com/env-settings-deprecations
   (at /usr/lib/ruby/vendor_ruby/puppet/settings.rb:1139:in `issue_deprecation_warning')
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Loading facts
Info: Caching catalog for puppet-agent
Info: Applying configuration version '1423285552'
Notice: /Stage[main]/Main/Node[puppet-agent]/File[/opt/htdocs]/ensure: created
Notice: Finished catalog run in 0.02 seconds
$ ls /opt/
VBoxGuestAdditions-4.3.20  htdocs
```

出来てますねー。

### 自動でやってみる

クライアント側で手動でprovisioningするのはなんの意味もないので、ちゃんと自動で出来るようにする。

#### agent側設定

puppetサービスを起動させます。`/etc/default/puppet`の`START`を`yes`にしておきます。

```bash:/etc/default/puppet
# Defaults for puppet - sourced by /etc/init.d/puppet

# Enable puppet agent service?
# Setting this to "yes" allows the puppet agent service to run.
# Setting this to "no" keeps the puppet agent service from running.
START=yes

# Startup options
DAEMON_OPTS=""
```

また、runinterval(プロビジョニングが走る間隔)を設定しておきます。

```ini:/etc/puppet/puppet.conf
[main]
logdir=/var/log/puppet
vardir=/var/lib/puppet
ssldir=/var/lib/puppet/ssl
rundir=/var/run/puppet
factpath=$vardir/lib/facter
templatedir=$confdir/templates

[master]
# These are needed when the puppetmaster is run by passenger
# and can safely be removed if webrick is used.
ssl_client_header = SSL_CLIENT_S_DN
ssl_client_verify_header = SSL_CLIENT_VERIFY

[agent]
server=puppet-master
certname=puppet-agent
environment=develop
runinterval=60
```

最後に`service puppet start`で起動します。

#### master側設定

site.ppで、htdocsの下に別のディレクトリを作成するような設定を追加します。

```puppet:/etc/puppet/manifests/site.pp
node 'puppet-agent' {
  include stdlib

  file { '/opt/htdocs':
    ensure => directory,
  } ->
  file { '/opt/htdocs/dummy':
    ensure => directory,
  }
}
```

#### agent側で確認

runintervalを60に設定したので、念のため1分ぐらい待ってから確認します。

```shell-session:shell
$ ls /opt/htdocs/
dummy
```

オッケー :bangbang: 

# 嵌ったところ

## `Info: Could not find certificate for ...`とか`Exiting; failed to retrieve certificate and waitforcert is disabled`とか出た場合

- [Could not call sign: Could not find certificate request for puppet](http://serverfault.com/questions/498496/could-not-call-sign-could-not-find-certificate-request-for-puppet)
- [Puppet: Exiting; no certificate found and waitforcert is disabled ](http://thejmlcontinuum.blogspot.jp/2013/08/puppet-exiting-no-certificate-found-and.html)

上記等サイトを参考に、master側の`/var/lib/puppet/ssl/certificate_requests`の下のファイルを削除してみてください。解決されるかもしれないです。

# 参考文献

- [Learning Puppet — Basic Agent/Master Puppet](https://docs.puppetlabs.com/learning/agent_master_basic.html#learning-puppet-%E2%80%94-basic-agent/master-puppet)
- [入門Puppet - Automate Your Infrastructure](http://p.booklog.jp/book/70667)
- [Installing Puppet: Pre-Install Tasks](https://docs.puppetlabs.com/guides/install_puppet/pre_install.html#installing-puppet:-pre-install-tasks)
- [Installing Puppet: Debian and Ubuntu](https://docs.puppetlabs.com/guides/install_puppet/install_debian_ubuntu.html#installing-puppet:-debian-and-ubuntu)