[Ansible]設定変更ログをJournalとしてNetBoxに残す

# はじめに

こちらは [エーピーコミュニケーションズ Advent Calendar 2021](https://qiita.com/advent-calendar/2021/ap-com) 21日目の記事となります。

今回は、Ansibleで設定変更した内容をNetBoxの`Journal`機能を使ってログ保存する方法について紹介します。

## NetBoxとは

NetBoxは、IPAM、DCIMの機能を持ち、デバイスインベントリ情報とIPアドレスやそれ以外の設定情報を合わせて管理することができるOSSで、Ansibleと親和性がとても高いです。

実際に、モジュールやインベントリプラグインが提供されており今回紹介する`Journal`機能以外にも、`Config Context`機能を使うことで設定パラメータをNetBox側に持たすこともできたりします。

## Journal機能について

Journal機能は、2021年4月にリリースしたv2.11で導入された機能でオブジェクト(デバイスやIPアドレス)に対して、Markdown形式でログを残することができる機能となります。

別に、Ansible Tower側の実行ログやNetBoxのChange Logでいいじゃん。
と思いますが、これらのログは永続的なものではなく、Ansible Towerのログはデフォルトで`120日`。NetBoxは`90日`で消されてしまうため、長期間保持することを想定しているものではありません。

:::note info
Ansible Towerのログ保持期間は日数変更できるのでストレージ容量を大量に確保できればそちらでも問題ないかと思います。
:::

そういったときに、今回紹介するJournal機能は使えるかと思います。

https://netbox.readthedocs.io/en/stable/additional-features/journaling/

ちなみにJournal機能はまだ新しい機能のため、Ansibleの[モジュール](https://docs.ansible.com/ansible/latest/collections/netbox/netbox/index.html)にはなく、[開発中](https://github.com/netbox-community/ansible_modules/issues/636)となっています。

そのため、現時点では、`uri`モジュールを使って作成することになります。

## Journal作成方法

### 事前準備

#### NetBoxコレクションのインストール

NetBoxコレクションを利用するので事前に下記コマンドでコレクションをインストールしておく必要があります。

```bash
ansible-galaxy collection install netbox.netbox
```

#### NetBoxからTokenを取得

NetBoxにAPIでアクセスするため、APIを取得しておきます。
取得方法は割愛します。

#### NetBoxに対象のオブジェクトを作成しておく

Journalは、NetBoxのオブジェクトに紐づく形で作成されるため、Journalを記録するためのオブジェクトを作成しておきます。

今回であれば`rt-center`というDeviceを対象にしています。

### Playbook実行
下記のようなPlaybookを作成して実行します。


```yaml:playbook.yml
---
- hosts: localhost
  gather_facts: no
  # nb_lookupの接続先、トークンとしても利用
  environment:
    NETBOX_API: <NetBoxのTOP URL>
    NETBOX_TOKEN: <NetBoxのToken>

  tasks:
    - name: NetBoxパラメータに必要な情報を取得
      set_fact:
        assigined_object_id: |
          {{
              query('netbox.netbox.nb_lookup',
                'devices',
                api_filter='name=rt-center',
                validate_certs=false)
              [0].value.id
          }}
        created_by_user_id: |
          {{
              query('netbox.netbox.nb_lookup',
                'users',
                api_filter='name=<Journalを作成するユーザ>',
                validate_certs=false)
              [0].value.id
          }}

    - name: 変更ジャーナル文章作成
      set_fact:
        journal_payload:
          assigned_object_type: dcim.device
          assigned_object_id: "{{ assigined_object_id }}"
          kind: <ジャーナルのタイプ(success|info|warning|danger)>
          created_by: "{{ created_by_user_id }}"
          comments: |-
            # Ansible Towerにて設定変更

            ## 変更内容

            ### Before

            ```yaml
            {{ <変更前設定> }}
            ```

            ### After

            ```yaml
            {{ <変更後設定> }}

            ```

            ### Diff

            ```diff
            {{ <変更前後のdiff> }}
            ```

    - name: NetBoxへジャーナル追加
      uri:
        url: "{{ lookup('env', 'NETBOX_API') }}/api/extras/journal-entries/"
        headers:
          Authorization: "Token {{ lookup('env', 'NETBOX_TOKEN') }}"
        method: POST
        body: "{{ journal_payload }}"
        body_format: json
        status_code:
          - 200
          - 201
        validate_certs: no
      register: res_netbox_journal
      changed_when: res_netbox_journal.status == 201
```

Playbook実行ログは割愛

### 実行結果

NetBox上で下記のようなJournalが作成されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335255/55ad0c89-c89f-9e58-f66d-4495d3a92bdd.png)

## おわりに

Journalについて、今回簡単なデータを保存していますが、Playbookのすべての実行ログをそのまま貼り付けることもできたりします。
\#保存容量は想像したくはないですが・・・

また、YAMLで保存することができるため、とても見やすいため運用の中でデータを確認するといった場面でも使えるかと思います。

AnsibleのNetBox連携については、Ansibleでできなかった自動化を補助してくれるパーツとして大いに期待できます。
ほかにも下記のような機能があるので今後検証したうえで記事にしてみたいと思います。

- Config Context
- IP Prefixからの空IP払い出し
- VLAN Groupからの空VLAN払い出し(今後実装予定)