Puppetで定義の一部を無効化するskip_tags


Puppet4.4.0のリリースノートで、skip_tagsの記載があったので試してみました。
Ansibleだと、playbookの一部を実行しない--skip-tagsオプションがすでにあって便利そうだなと思っていたところです。

できることは、マニフェストにタグを指定しておいて、実行時に--skip_tagsでそのタグがついている部分を実行しないようにできます。以前からあった、**そのタグがついている部分だけを実行する--tagsオプションの逆になります**。

# バージョン情報

```
# /opt/puppetlabs/bin/puppet --version
4.4.0
```

# 使える場面
一時的にスキップできると何がいいかというと、**手作業でしかインストールできないソフトウェアがある場合に便利です**。

- ソフトウェアのインストールに必要なパッケージをPuppetでインストール
- ソフトウェアをインストール(手作業)
- ソフトウェアの設定ファイルをPuppetで設定

# サンプルで試す

## サンプルマニフェスト
skip_tagsを試すためのマニフェスト。手でインストールするソフトのインストール条件になっているopenjdkをインストールする定義と、ソフトインストール後でないと実行できない設定ファイル定義があります。実行時に--skip_tagsに指定するタグとして、とりあえずpost_manual(タグ名は任意)をつけておきます。
ちなみに、/opt/manual_installはソフトインストール後にできるディレクトリのかわりです。

```puppet:skip_tag.pp
package { 'java-1.8.0-openjdk': }

file { '/opt/manual_install/config.conf':
  ensure  => file,
  mode    => '0644',
  owner   => 'root',
  group   => 'root',
  content => 'my config',
  tag     => 'post_manual',
}
```

## skip_tagsを指定しない場合
ドライラン(noop)で確認します。skip_tagを指定せずにapplyすると、ソフトインストール前に実行したくない/opt/manual_install/config.confも実行されそうです。

```
# /opt/puppetlabs/bin/puppet apply skip_tag.pp --noop
Notice: Compiled catalog for 9b025c4c740e in environment production in 0.72 seconds
Notice: /Stage[main]/Main/Package[java-1.8.0-openjdk]/ensure: current_value purged, should be present (noop)
Notice: /Stage[main]/Main/File[/opt/manual_install/config.conf]/ensure: current_value absent, should be file (noop)
Notice: Class[Main]: Would have triggered 'refresh' from 2 events
Notice: Stage[main]: Would have triggered 'refresh' from 1 events
Notice: Applied catalog in 0.14 seconds
```

なお、/opt/manual_installディレクトリはまだないので、そもそもnoopなしで実行時するとエラーになります。

```
# ls -l /opt/
total 4
drwxr-xr-x 7 root root 4096 Mar 19 19:02 puppetlabs
```

## skip_tagsで特定タグを無効化
マニフェストそのままで、--skip_tagsで無効化したいタグ(例ではpost_manual)を指定します。post_manualタグをつけていた、/opt/manual_install/config.confは変更されていません。

```
# /opt/puppetlabs/bin/puppet apply skip_tag.pp --skip_tags post_manual
Notice: Compiled catalog for 9b025c4c740e in environment production in 0.69 seconds
Notice: /Stage[main]/Main/Package[java-1.8.0-openjdk]/ensure: created
Notice: Applied catalog in 52.69 seconds
```

## 何かを手作業でインストール
何かを手作業でインストール。ここではサンプルなので、インストールのかわりにディレクトリをつくるだけ。

```
# mkdir /opt/manual_install
# ls -l /opt
total 8
drwxr-xr-x 2 root root 4096 Mar 19 19:23 manual_install
drwxr-xr-x 7 root root 4096 Mar 19 19:02 puppetlabs
```

## 手作業後にマニフェストを全部実行

手作業が終わって、そのソフトの設定ファイルも配布できるようになったので全部実行します。

```
# /opt/puppetlabs/bin/puppet apply skip_tag.pp
Notice: Compiled catalog for 9b025c4c740e in environment production in 0.64 seconds
Notice: /Stage[main]/Main/File[/opt/manual_install/config.conf]/ensure: defined content as '{md5}944357941809f96f90f761b0a5309cc2'
Notice: Applied catalog in 0.12 seconds
```

内容も反映されています。

```
# cat /opt/manual_install/config.conf
my config
```

# 補足
Automatic Tagging（クラス名とかネームスペースが自動的にタグ付けされている）などがあるため、skip_tagsが必要以上にskipするかもしれません。このあたり注意が必要ですが、どうしても自動化できない作業が間に入ると効率悪いケースもあるので、便利そうな機能な気がします。

今回のはサンプルなので簡素ですが、実際の場合にはもっと規模が大きいマニフェストでごく一部だけ実行したくない部分が存在する場合には特に便利かなと。

# 参考
Puppet4.4.0のリリースノートはこちら

- https://docs.puppetlabs.com/puppet/4.4/reference/release_notes.html

Puppetのtagについてはこちら

- https://docs.puppetlabs.com/puppet/latest/reference/lang_tags.html