Cisco Nexus を Puppet で設定する３

# 本稿の構成

| タイトル | 内容 | コメント |
|:-----------|:------------|:------------|
|[Cisco Nexus を Puppet で設定する１](http://qiita.com/dyoshiha/items/079d04e42a1e66e29d89)|Puppet Master のインストール|元ネタ：[Installing Puppet: Linux](https://docs.puppet.com/puppet/4.0/reference/install_linux.html#installing-release-packages-on-yumrpm-systems)|
|[Cisco Nexus を Puppet で設定する２ａ](http://qiita.com/dyoshiha/items/19026aa3ab5e5a5f678b)|Puppet Agent のインストール・Bash編|元ネタ：[Puppet Agent Installation & Setup: Cisco Nexus](https://github.com/cisco/cisco-network-puppet-module/blob/develop/docs/README-agent-install.md)|
|Cisco Nexus を Puppet で設定する２ｂ|Puppet Agent のインストール・guestshell編|未完成|
|[Cisco Nexus を Puppet で設定する３](http://qiita.com/dyoshiha/items/2642ea3d4b3bf9c02e51)|puppetlabs-ciscopuppet モジュールのインストール|元ネタ：[cisco-network-puppet-module: Example Manifest Usage](https://github.com/cisco/cisco-network-puppet-module/blob/develop/examples/README.md)|

# はじめに

前回までで Puppet Master と Puppet Agent の基本インストール・設定が完了。今回は puppetlabs-ciscopuppet モジュールを Puppet Master へインストールした後、実際に動作を確認してみる。

# 説明：Puppet モジュールとは？

Puppet モジュールは Puppet Master へインストールする拡張モジュールで、標準では扱えない多様なソフトウェア・デバイスが扱えるようになる。Cisco Nexus 用拡張モジュールは Github 上では **puppetlabs-ciscopuppet モジュール** と呼ばれているのでここでもその呼び方を踏襲する。

## Puppet モジュールの重要ディレクトリ

（puppetlabs-ciscopuppet モジュールに限らず一般に）Puppet モジュールをインストールするにあたり、いくつかのディレクトリを覚えておくと理解がすっきりする：

| 名称  | 説明 | デフォルトパス|確認方法|
|:-----------|:------------|:------------|:------------|
| [環境メインディレクトリ](https://docs.puppetlabs.com/puppet/latest/reference/environments.html) | Puppet Agent を「環境」に所属させると「環境」毎に異なるメインマニフェストと modulepath を指定できる。その際のルートになるディレクトリのこと|/etc/puppetlabs/code/environments/production/|
|[メインマニフェスト](https://docs.puppetlabs.com/puppet/latest/reference/dirs_manifest.html)が置かれるディレクトリ | メインマインフェストとは Puppet 起動時に読み込まれるマニフェストファイルのこと。|(環境メインディレクトリ) /manifests/|# puppet config print manifest|
|拡張モジュールが置かれるディレクトリ（＝[modulepath](https://docs.puppetlabs.com/puppet/latest/reference)） | Puppet は modulepath で指定したディレクトリに存在するモジュールを自動的に読み込む|(環境メインディレクトリ) /modules/| # puppet config print modulepath|

## puppetlabs-ciscopuppet モジュールの重要ディレクトリ

puppetlabs-ciscopuppet モジュールは modulepath 配下にインストールされる。このモジュールの内、今回のインストール作業をするうえで重要なディレクトリについてもまとめておく：

| 名称  | 説明 | デフォルトパス|
|:-----------|:------------|:------------|
|examples| サンプルのマニフェストが多数存在| (modulepath)/ciscopuppet/examples/|
|manifests| 拡張モジュールのマニフェストを配置する。デフォルトは空| (modulepath)/ciscopuppet/manifests/|

# puppetlabs-ciscopuppet モジュールのインストール 
## puppetlabs-ciscopuppet 旧バージョンの削除

puppetlabs-ciscopuppet の古いバージョンをインストールしているのであれば削除が必要。確認するには Puppet Master にて puppet module list を使う。以下サンプルログ：

```
# puppet module list
/etc/puppetlabs/code/environments/production/modules
|
+-- puppetlabs-ciscopuppet (v1.0.1)
/etc/puppetlabs/code/modules (no modules installed)
/opt/puppetlabs/puppet/modules (no modules installed)
```

上記例では v1.0.1 がインストールされている。アンインストールするには以下のコマンドを使用する：

```
# puppet module uninstall puppetlabs-ciscopuppet
```

## puppetlabs-ciscopuppet モジュールのイントール

ダウンロードについて推奨の方法は cisco-ciscopuppet.git レポジトリを Puppet Master へクローンするのがよい。Git 設定が完了していれば以下のコマンドでダウンロード可能：

```
# git clone https://github.com/cisco/cisco-network-puppet-module.git
```

puppetlabs-ciscopuppet モジュールをインストールには cisco-network-puppet-module ディレクトリの一つ上のディレクトリにて以下のコマンドを使用する：

```
# puppet module build cisco-network-puppet-module/
# cd cisco-network-puppet-module/pkg/
# puppet module install ./puppetlabs-ciscopuppet-[version].tar.gz
```

## Puppet Master の Proxy 設定

puppet module install ./puppetlabs-ciscopuppet-[version].tar.gz
実行時に次のようなエラーが出た場合：

```
Notice: Preparing to install into /etc/puppetlabs/code/environments/production/modules ...
Notice: Downloading from https://forgeapi.puppetlabs.com ...
Error: Could not connect to https://forgeapi.puppetlabs.com
  There was a network communications problem
    The error we caught said 'getaddrinfo: Name or service not known'
    Check your network connection and try again
```

は可能性の一つとして Puppet Master 上での Proxy サーバの誤設定が考えられる。正しく設定されているかを確認：

```
vi /etc/puppetlabs/puppet/puppet.conf
[user]
http_proxy_host = proxy.yourdomain.com
http_proxy_port = 8080
```


## puppetlabs-ciscopuppet モジュールの内容確認

puppetlabs-ciscopuppet モジュールは modulepath へインストールされ、(modulepath)/ciscopuppet/examples/ には以下のようにサンプルのマニフェストファイルが複数存在する：

```
# ls /etc/puppetlabs/code/environments/production/modules/ciscopuppet/examples/
demo_aaa.pp              demo_interface.pp                   demo_profile                demo_tacacs_server.pp
demo_all.pp              demo_netdev_network_trunk.pp        demo_radius.pp              demo_tcollector.pp
demo_bgp_ipv4.pp         demo_netdev_snmp.pp                 demo_repo.pp                demo_vlan.pp
demo_bgp_ipv4_site.pp    demo_netdev_tacacs_global.pp        demo_role                   demo_vrf.pp
demo_bgp_ipv6.pp         demo_netdev_tacacs.pp               demo_role.pp                demo_vtp.pp
demo_bgp_ipv6_site.pp    demo_netdev_tacacs_server_group.pp  demo_roles_site.pp          demo_vxlan.pp
demo_bgp.pp              demo_netdev_tacacs_server.pp        demo_site.pp                init.pp
demo_cisco_patch_rpm.pp  demo_ntp.pp                         demo_snmp.pp                install.pp
demo_command_config.pp   demo_ospf.pp                        demo_syslog.pp              README.md
demo_domain.pp           demo_patching.pp                    demo_tacacs_server_host.pp
```


# サンプルマニフェストを利用したデモンストレーション

## サンプルデモの概要（demo_all.pp）

上記サンプルのマニフェストを使ってデモ的に動作確認ができる。ここではその内 demo_all.pp のセットアップを行ってみる。demo_all.pp は3つのマニフェストが以下の順番に呼び出される。

**メインマニフェスト：site.pp
 → puppetlabs-ciscopuppet モジュール：demo_all.pp
 →  puppetlabs-ciscopuppet モジュール：demo_aaa.pp から demo_vxlan.pp まで**

## puppetlabs-ciscopuppet モジュール用マニフェストの作成
全てのサンプルマニフェストを (modulepath)/ciscopuppet/examples/ から (modulepath)/ciscopuppet/manifests へコピーする：

```
# cd /etc/puppetlabs/code/environments/production/modules/ciscopuppet/examples
# cp -r ./demo* /etc/puppetlabs/code/environments/production/modules/ciscopuppet/manifests/
```

## メインマニフェストの作成

メインマニフェストとして利用できるのが  (modulepath)/ciscopuppet/examples/ 内にある demo_site.pp である。これを「メインマニフェストが置かれるディレクトリ」 production/manifests/ へコピーする。名称は site.pp へ変更する：

```
# cd /etc/puppetlabs/code/environments/production/modules/ciscopuppet/examples
# cp ./demo_site.pp /etc/puppetlabs/code/environments/production/manifests/site.pp
```

site.pp を修正する。今回は Nexus3048 の hostname が n3k なので node を以下の形に書き換える：

```
node 'n3k' {
  include ciscopuppet::demo_all
}
```

site.pp は上記内容を見て分かる通り、puppetlabs-ciscopuppet モジュール内の demo_all.pp を呼び出す。demo_all.pp の中身を覗いてみると同ディレクトリの複数のマニフェストを呼び出しているのがわかる。

※なお、初めの include ciscopuppet::install により cisco_node_utils gem をインストールしている

```
# cat /etc/puppetlabs/code/environments/production/modules/ciscopuppet/manifests/demo_all.pp
class ciscopuppet::demo_all {

  include ciscopuppet::install

  # If a custom gem repo and/or proxy is needed, the installer
  # can be configured as follows:
  #
  # class {'ciscopuppet::install':
  #   repo  => 'http://gemserver.domain.com:8808',
  #   proxy => 'http://proxy.domain.com:8080',
  # }

  include ciscopuppet::demo_aaa
  include ciscopuppet::demo_bgp
  include ciscopuppet::demo_command_config
  include ciscopuppet::demo_domain
  include ciscopuppet::demo_interface
  include ciscopuppet::demo_ntp
  include ciscopuppet::demo_ospf
  include ciscopuppet::demo_patching
  include ciscopuppet::demo_radius
  include ciscopuppet::demo_snmp
  include ciscopuppet::demo_syslog
  include ciscopuppet::demo_tacacs_server
  include ciscopuppet::demo_tacacs_server_host
  include ciscopuppet::demo_vlan
  include ciscopuppet::demo_vrf
  include ciscopuppet::demo_vtp
  include ciscopuppet::demo_snmp
  include ciscopuppet::demo_vxlan
}
```

## サンプルデモの実行

とはいえ、複数のマニフェストを同時に実行すると動作確認がしづらいので、ここでは demo_command_config のみを実行し意図通りに NX-OS の設定が変更されるか確認する。

そこで demo_all.pp から demo_command_config を除いて全てコメントアウトして実行してみる：

```
# vi /etc/puppetlabs/code/environments/production/modules/ciscopuppet/manifests/demo_all.pp

class ciscopuppet::demo_all {

  include ciscopuppet::install

  # If a custom gem repo and/or proxy is needed, the installer
  # can be configured as follows:
  #
  # class {'ciscopuppet::install':
  #   repo  => 'http://gemserver.domain.com:8808',
  #   proxy => 'http://proxy.domain.com:8080',
  # }

#  include ciscopuppet::demo_aaa
#  include ciscopuppet::demo_bgp
  include ciscopuppet::demo_command_config
#  include ciscopuppet::demo_domain
#  include ciscopuppet::demo_interface
#  include ciscopuppet::demo_ntp
#  include ciscopuppet::demo_ospf
#  include ciscopuppet::demo_patching
#  include ciscopuppet::demo_radius
#  include ciscopuppet::demo_snmp
#  include ciscopuppet::demo_syslog
#  include ciscopuppet::demo_tacacs_server
#  include ciscopuppet::demo_tacacs_server_host
#  include ciscopuppet::demo_vlan
#  include ciscopuppet::demo_vrf
#  include ciscopuppet::demo_vtp
#  include ciscopuppet::demo_snmp
#  include ciscopuppet::demo_vxlan
}
```

これで demo_all.pp から呼び出されるマニフェストは demo_command_config.pp のみとなった。
demo_command_config.pp は NX-OS の書式で設定を記述するマニフェストである。その内容を参照すると以下の通り、interface loopback42, no system default switchport, ip route の3つの設定をコマンドラインで追加している：

```
# cat modules/ciscopuppet/manifests/demo_command_config.pp

class ciscopuppet::demo_command_config {

  cisco_command_config { 'loop42':
    command => "
      interface loopback42
        description configured by puppet
        ip address 192.168.1.42/24
    "
  }

  cisco_command_config { 'system-switchport-default':
    command => 'no system default switchport'
  }

  cisco_command_config { 'route42':
    command => 'ip route 192.168.42.42/32 Null0',
  }
}
```

NX-OS に戻り現在上記設定が入っていないことを確認する（NS-OS に戻るには exit を三回）：

```
n3k# show run int lo 42
                      ^
Invalid range at '^' marker.
n3k# show run | in 'system default switchport'
n3k# show run | in 'ip route'
```

マニフェスト：site.pp を読み込ませるには Puppet Agent にて puppet agent -t を実行する。その後、NX-OS にて３つの設定が入っていることを確認する：

```
root@n3k#puppet agent -t
Info: Using configured environment 'production'
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Loading facts
Info: Caching catalog for n3k
Info: Applying configuration version '1453124228'
Notice: /Stage[main]/Ciscopuppet::Demo_command_config/Cisco_command_config[loop42]/command: command changed '' to 'interface loopback42
description configured by puppet
ip address 192.168.1.42/24
'
Notice: /Stage[main]/Ciscopuppet::Demo_command_config/Cisco_command_config[system-switchport-default]/command: command changed '' to 'no system default switchport
'
Notice: /Stage[main]/Ciscopuppet::Demo_command_config/Cisco_command_config[route42]/command: command changed '' to 'ip route 192.168.42.42/32 Null0
'
Notice: Applied catalog in 34.69 seconds
root@n3k#
root@n3k#exit
exit
root@n3k#exit
logout
bash-4.2$ exit
exit
n3k# show run int lo 42

!Command: show running-config interface loopback42
!Time: Mon Jan 18 14:03:38 2016

version 7.0(3)I2(2a)

interface loopback42
  description configured by puppet
  ip address 192.168.1.42/24

n3k# show run | in 'system default switchport'
no system default switchport
n3k# show run | in 'ip route'
  ip route 0.0.0.0/0 10.71.135.254
ip route 192.168.42.42/32 Null0
```

期待通り設定が入っていることを確認できた。

## gem install 

[こちら](https://github.com/cisco/cisco-network-node-utils/blob/master/docs/README-develop-node-utils-APIs.md#prerequisites)に記述がある以下の gem は Puppet Master へインストールしておいた方がいい模様。

```
gem install cisco_nxapi
gem install rake
gem install rubocop
gem install simplecov
gem install minitest
```