BIG-IP Virtual Editionを使ってみる。（その３：Ansibleによるライセンスアクティベート）

# はじめに
F5社の`BIG-IP`は`Ansible`による自動化に積極的で、基本的な設定は大体`Ansible`のモジュール化がされていることから、今回は`Ansible`を使って基本設定を行ってみたいと思います。

- 【前】[BIG-IP Virtual Editionを使ってみる。（その２：BIG-IP VEの起動とライセンス登録）](https://qiita.com/sakai00kou/items/e7e458709e9771b85181)
- 【次】[BIG-IP Virtual Editionを使ってみる。（その４：Ansibleによる初期設定）](https://qiita.com/sakai00kou/items/92c73ee329d1cf63318a)

## Ansible参考資料
`Ansible Automates Tokyo 2020`で公開された以下の資料がサンプルも書かれていて参考になります。

- [F5自動化の取り組みとAnsiblex BIG-IP Playbookユースケースのご紹介](https://redhat.lookbookhq.com/automates-tokyo-2020/ansible-f5-webinar-1)

# Ansibleのセットアップ
`Ansible`を使うためのサーバを準備します。

今回は以下で作成しました。

|スペック|備考|
|:--|:--|
|OS|CentOS 8.2 2004|
|ソフトウェアの選択|最小限のインストール|
|Ansibleバージョン|2.9|

# Ansibleについて
基本設定は「[F5自動化の取り組みとAnsiblex BIG-IP Playbookユースケースのご紹介](https://redhat.lookbookhq.com/automates-tokyo-2020/ansible-f5-webinar-1)」で紹介されている内容をベースに作っていきますが、紹介されている`Playbook`は`Ansible`の[ベストプラクティス](https://docs.ansible.com/ansible/2.9_ja/user_guide/playbooks_best_practices.html)の構成になっていません。

とはいえ、ベストプラクティスの構成も公式で紹介されているものからオレオレベストプラクティスまで様々ありますが、なるべく公式で紹介されている構成に寄せて作っていきます。

**【注意】**
`Ansible`のバージョン2.10から、`Ansible`の仕様が大きく変わるようなので、バージョン2.10以降を使用する場合はベストプラクティスの構成が変わるかもしれないため、ご注意ください。

## Ansibleのインストール
準備したAnsible実行サーバに`Ansible`をインストールしていきます。

```shell:Ansibleインストール
dnf -y install epel-release
dnf -y install ansible
```

`Ansible`実行時、SSHのフィンガープリントがAnsible実行サーバに登録されていないとエラーとなるため、一度rootユーザで`BIG-IP`にアクセスしておきましょう。

```shell:SSHアクセス
ssh -l root [BIG-IPのIPアドレス]
(略)
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
```

# Ansibleのファイル・ディレクトリ構成
今回は以下の様な構成で進めていきます。

`Ansible`自体の仕様などについて紹介すると、今回の趣旨からずれてしまうので、細かいファイルやディレクトリの仕様、意味などは各自`Ansible`のサイトなどを調べて下さい。

|パス|説明|
|:--|:--|
|host_vars/|ホストごとの変数設定ディレクトリ|
|┗ bigip01.yml|bigip01用の変数ファイル|
|group_vars/|ホストグループごとの変数設定ディレクトリ|
|┗ bigip.yml|bigipグループ用の変数ファイル|
|bigip.yml|グループごとの実行するロールを指定しているファイル|
|site.yml|メインのPlaybook|
|hosts-all|インベントリファイル|
|roles/|ロール格納ディレクトリ|
|┗ xxxx/|各種ロール用ディレクトリ|

# Ansible Playbookの作成
[前回](https://qiita.com/sakai00kou/items/e7e458709e9771b85181)の記事でGUIからライセンスのアクティベートを実施していますが、「[F5自動化の取り組みとAnsiblex BIG-IP Playbookユースケースのご紹介](https://redhat.lookbookhq.com/automates-tokyo-2020/ansible-f5-webinar-1)」で、`Ansible`によるライセンスアクティベートの方法も書かれているため、せっかくなので`Playbook`で作成してみようと思います。

作成するロール名は以下とします。

|ロール名|説明|
|:--|:--|
|setup_bigip-license|ライセンスアクティベートを行うロール|

## ロールの作成
rolesディレクトリ配下に各種ロールを作成していきます。

ベストプラクティスに沿ったロールの構成を作成する場合、個々に作成しても良いですが、`ansible-galaxy`コマンドを使うと、ベストプラクティスに沿ったロールのディレクトリ構成、必要なファイルを作成してくれるため、ロールの雛形を`ansible-galaxy`コマンドで作成して、`Playbook`を作っていきたいと思います。

```shell:ansible-galaxyコマンドでのロール雛形作成
cd roles/
ansible-galaxy init setup_bigip-license
```

ちなみに`ansible-galaxy init`コマンドでロールを作成すると`roles/[ロール名]`の配下に以下の様な構成でロールが作成されます。

|パス|説明|
|:--|:--|
|README.md|Readmeファイル|
|defaults/|デフォルトの変数を指定|
|┗ main.yml||
|files/|ファイルを展開する際などに使用する実ファイルを格納|
|handlers/|設定後に実行する処理(サービス再起動等)を指定|
|┗ main.yml||
|meta/|メタデータを指定|
|┗ main.yml||
|tasks/|実行するタスクを指定|
|┗ main.yml||
|templates/|ファイルを展開する際などに使用する雛形ファイルを格納|
|tests/|テスト用実行用|
|┣ inventory||
|┗ test.yml||
|vars/|ロール用の変数を指定|
|┗ main.yml||

## tasksの作成
`tasks`ディレクトリにある`main.yml`に実行するタスクを記述していきます。

後から使いまわせるように、機器によって異なる値をすべて変数化して、別途変数ファイルから読み取るようにします。

```yaml:roles/setup_bigip-license/tasks/main.yml
---
# tasks file for setup_bigip-license
- name: BIG-IPライセンスアクティベート
  bigip_device_license:
    license_key: "{{ bigip_license }}"
    accept_eula: "yes"
    provider: "{{ bigip_provider }}"
  delegate_to: "{{ bigip_delegate_to }}"

- name: BIG-IP LTMのnominalレベルプロビジョン
  bigip_provision:
    module: ltm
    level: nominal
    provider: "{{ bigip_provider }}"
  delegate_to: "{{ bigip_delegate_to }}"
```

尚、「[F5自動化の取り組みとAnsiblex BIG-IP Playbookユースケースのご紹介](https://redhat.lookbookhq.com/automates-tokyo-2020/ansible-f5-webinar-1)」では、`provider`の設定を`set_fact`を使って`Playbook`内で変数を設定することで指定するやり方をしていましたが、今回は1ファイルの`Playbook`方式ではないのと、後述のグループ変数ファイルやホスト変数ファイルに変数がまとまっていたほうが管理がしやすいので、`set_fact`の処理は行っていません。

## グループ変数の作成
`BIG-IP`同士で共通となる変数一覧を`group_vars`に作成していきます。

今回は`bigip`という名前でグループをまとめようと思うので、`bigip.yml`という名前のファイルを作成します。

基本的に`Ansible`の`BIG-IP`用モジュールは、`API`で設定を行うように作られているため、`BIG-IP`に対して`Ansible`を実行する場合、Ansible実行サーバから`BIG-IP`に`HTTPS`で`API`アクセスして設定するような方法となります。

そのため、GUIアクセス用のユーザID、パスワードだけ設定されていれば、`BIG-IP`の設定ができますが、SSHアクセス用の設定を行っていないと、`Ansible`実行時にデフォルトで動く、`Gathering Facts`が失敗するのと、`BIG-IP`用モジュール以外のモジュールを使用する場合に失敗することから、SSHアクセス用の設定も行っておきます。

```yml:group_vars/bigip.yml
---
# BIG-IP SSHログイン設定
ansible_ssh_user: root
ansible_ssh_pass: [CLIパスワード]

# BIG-IP GUIログイン設定
bigip_user: admin
bigip_password: [GUIパスワード]
bigip_delegate_to: localhost

# Provider設定
bigip_provider:
  server: "{{ bigip_server }}"
  user: "{{ bigip_user }}"
  password: "{{ bigip_password }}"
  server_port: 443
  validate_certs: no
```

ちなみに、`bigip_delegate_to`の設定は、**Ansible実行サーバからAPIでBIG-IPにアクセスする**ことから、**Ansible実行サーバ自身**を示すため`localhost`で指定しています。

また、`bigip_provider`で指定している**APIアクセス用の設定**では`validate_certs`が`no`でないと失敗するため、`no`としています。

## ホスト変数の作成
各ホスト固有の変数一覧を`host_vars`に作成していきます。

`bigip_license`は前回取得したライセンス番号を記載します。

```yml:host_vars/bigip01.yml
---
bigip_license: XXXXX-XXXXX-XXXXX-XXXXX-XXXXXXX
bigip_server: [BIG-IPのIPアドレス]
```

## インベントリファイルの作成
Ansibleで構築する`BIG-IP`を登録します。

今回は2台分設定し、グループ名を`bigip`、ホスト名を`bigip01`にします。

```shell:hosts-all
[bigip]
bigip01
```

## グループごとのロール実行ファイルの作成
`bigip`グループのホストに対して実行するロールを指定します。

また、前述の通り、`BIG-IP`用モジュールはAPIでアクセスするため、いちいち`Gathering Facts`を実行しても遅くなるだけなので実行しないようにしておきます。

```yml:bigip.yml
---
- hosts: bigip
  gather_facts: no
  roles:
    - setup_bigip-license
```

## 全体のロール実行ファイルの作成
今回の場合、無くても良いですが、ベストプラクティスに沿って作っておきます。

`Ansible`ベストプラクティスでの構成として、`roles`には機器問わず、個々の処理を記載したロールを格納しておき、グループごとのロール実行ファイルでロールディレクトリにあるものの中から実行するロールを指定、最後に`site.yml`で各種グループごとのロール実行ファイルをインポートすることで、環境全体を表す構成となっています。

今回は`BIG-IP`分しか作っていないため、`bigip.yml`をインポートする定義のみ設定します。

```yml:site.yml
---
- import_playbook: bigip.yml
```

# Ansibleの実行
実際に作成した`Playbook`を実行していきます。

前回ライセンスのアクティベートは行っているため、問題なければ以下の様に`ok=2`が表示されるはずです。

```shell:Playbookの実行
ansible-playbook -i hosts-all site.yml
```

```shell:実行例

PLAY [bigip] *******************************************************************

TASK [setup_bigip-license : BIG-IPライセンスアクティベート] ********************************
ok: [bigip01]

TASK [setup_bigip-license : BIG-IP LTMのnominalレベルプロビジョン] ***********************
ok: [bigip01]

PLAY RECAP *********************************************************************
bigip01                    : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
```

# おわりに
モジュールの存在有無によって変わりますが、`BIG-IP`のようなネットワーク機器も`Ansible`であっという間に構築できてしまうのを見ると、最初の学習コストはかかりますが、ネットワークインフラの人も積極的に覚えていくべきだと感じました。

今回はライセンスアクティベートの`Playbook`を作成するまでとなったので、次回は残りの初期設定を進めていきたいと思います。