ansibleでBIG-IPを制御してみよう①

# はじめに
ansibleでBIG-IPの制御をやりたくなったでの、試してみた。
まずは検証の環境の構築。

# 検証環境
VMWare ESXi 5.5
　CentOS Linux release 7.4.1708 (Core)
　　ansible 2.4.0.0
　BIG-IP VE trial 12.1.2 Build 0.0.249


ansible2.4用python環境 : /opt/ansible2.4
playbookの格納先 : /opt/playbook
ansibleの実行ユーザ : ansibleuser

# 環境構築
## CetnOS 7.4
CnetOS7.4をminimulでインストール。

## ansible 2.4
2017/10/17時点で、CentOS標準のリポジトリでインストールできるansibleのバージョンは2.3.2.0。
2.4でBIG-IP関連のモジュールが大分増えているので、2.4を使うためにpipでインストールする。
OS標準のPythonのパッケージに影響を与えないように、virtualenvで環境を分離する。

- 対応するBIG-IPのバージョンについて
Ansibleの各モジュール毎のドキュメントに、動作要件としてBIG-IPのバージョンが書かれていることがあるので、使う前にチェックしておいた方が良いでしょう。
ansible2.4から管理対象（接続先）の動作要件のPythonのバージョンが2.6以上に変わっている。
BIG-IPの11系はPython2.4、12系はPython2.6なので、11系でrawモジュール等、F5以外のモジュールを使うときは、動かないものがあるかもしれません。

- 必要なライブラリなどのインストール
pipでインストールするときに必要とされるパッケージ等をインストールする。
ansibleの実行時に必要とされるOSのパッケージ（sshpass）や、ベースになるコンフィグ（/etc/ansible/ansible.cfg）を流用するため、標準パッケージのansibleもインストールする。 
 
```
# yum install ansible libffi-devel gcc python-devel libyaml-devel openssl-devel python-virtualenv -y
```  

- ansible用のpython環境を作成

```
# mkdir /opt/ansible24
# cd /opt
# virtualenv --no-site-packages ansible24
# source /opt/ansible24/bin/activate
# pip install --upgrade pip
# pip install --upgrade setuptools
# pip install ansible
# pip install f5-sdk bigsuds netaddr
```

- ansible実行ユーザの作成  
通常はpythonの仮想環境を切替えて使用するが、面倒なので、ログイン時に2.4に切り替えてくれるユーザを作成する。
playbookを作成するディレクトリも用意しておく。

```
# useradd ansibleuser
# passwd ansibleuser
# echo "source /opt/ansible24/bin/activate" >> /home/ansibleuser/.bash_profile
# mkdir /opt/playbook
# chown ansibleuser:ansibleuser /opt/playbook
```

## BIG-IP VE trial
BIG-IP VE Setup のドキュメントを見ながらセットアップしていく。
https://support.f5.com/kb/en-us/products/big-ip_ltm/manuals/product/bigip-ve-setup-vmware-esxi-12-1-0.html

### BIG-IP VE trialのデプロイ 
- 評価版の申し込み
以下のサイトから評価版の申し込みを行うと、ライセンスキーが送られてくる。 
https://www.f5.com/trial/big-ip-trial.php

- ESXi用の仮想イメージのダウンロード
ライセンスキーと一緒に、ダウンロード先のURLも記載されているので、そこからVMWareESXi用のBIG-IP VE imageをダウンロードする。
https://devcentral.f5.com/articles/getting-started-with-big-ip-ve-trial-22469

- イメージ（OVF）の展開
NICがとして、Management,Internal,External,HAの４つがあるので、ESXiにポートグループを4つ用意する。一番目が管理ポートになる。ポート作成後、ダウンロードしたイメージ（OVF)をデプロイする。

- 起動
BIG-IP VE trialの仮想マシンの電源をいれる。

### BIG-IP VE trialの初期設定
- ManagementポートのIPアドレス設定  
仮想マシンコンソール上で、root/defaultでログインし、以下のようにIPアドレスを設定する。

```
# tmsh
(tmos)# modify sys global-settings mgmt-dhcp disabled 
(tmos)# create sys management-ip xxx.xxx.xxx.xxx/255.255.255.0
(tmos)# create sys management-route default gateway yyy.yyy.yyy.yyy
(tmos)# save sys config 
(tmos)# quit
# exit
```
# Ansibleでの制御
ansibleは、ansibleuserで作業を行う。

## インベントリファイル作成（BIG-IPとの接続設定）
```
$ cd /opt/playbook/
$ vi hosts
```

```
localhost ansible_connection=local ansible_python_interpreter=python
bigip ansible_host=XXX.XXX.XXX.XX
[all:vars]
bigip_ip=XXX.XXX.XXX.XX
bigip_user=ansibleuser
bigip_passwd=password
```
BIG-IP用のタスク（Ansibleのモジュール）は、基本的にローカルホストで実行され、リモートのBIG-IPのAPIをたたく。
インベントリに列挙されるホストとは別に、変数としてBIG-IPへの接続情報（アドレス/アカウント/パスワード）を設定することになる。
実際に運用するときは、アカウント・パスワードは、ansible vaultで暗号化するなど、適切に運用してください。
２行目のホストは、F5のモジュール以外の、rawモジュールなどで、Linuxと同じようにSSHで接続して操作するために記述しています。

## 接続テスト
bigip_command - Run arbitrary command on F5 devices
を使用して、tmshでバージョン情報を取得するコマンド実行するPlaybookで接続テスト。

- playbookの作成

```
$ vi connection_test.yml
```
```
- hosts: localhost
  become: no
  gather_facts: no

  vars_prompt:
  - name: "bigip_ip"
    prompt: "Enter BIG-IP ip address "
    private: no
  - name: "bigip_user"
    prompt: "Enter BIG-IP user "
    private: no
  - name: "bigip_passwd"
    prompt: "Enter BIG-IP password "
    private: yes

  tasks:
  - name: run show version on remote devices
    bigip_command:
      commands: show sys version
      server: "{{ bigip_ip }}"
      user: "{{ bigip_user }}"
      password: "{{ bigip_passwd }}"
      validate_certs: "no"
    register: result
  - debug: var=result.stdout_lines
```
- playbookの実行

```
$ ansible-playbook -i hosts connection_test.yml
Enter BIG-IP ip address : XXX.XXX.XXX.XXX　<--- BIG-IPのIPアドレスを入力
Enter BIG-IP user : root　<--- BIG-IPのユーザを入力
Enter BIG-IP password :      　<--- BIG-IPのパスワードを入力。表示はされない。

PLAY [localhost] *****************************************************

TASK [run show version on remote devices] ****************************
changed: [localhost]

TASK [debug] *********************************************************
ok: [localhost] => {
    "result.stdout_lines": [
        [
            "",
            "Sys::Version",
            "Main Package",
            "  Product     BIG-IP",
            "  Version     12.1.2",
            "  Build       0.0.249",
            "  Edition     Final",
            "  Date        Wed Nov 30 16:04:00 PST 2016",
            "",
            ""
        ]
    ]
}

PLAY RECAP ***********************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=0
```

## ユーザ作成
bigip_user - Manage user accounts and user attributes on a BIG-IP
を使用して、BIG-IPにrootとは別のansibleで使用するユーザを作成する。
※作らなくてもよいが、今回は検証のため作成。

- playbookの作成

```
$ vi useradd.yml
```
```
- hosts: localhost
  become: no
  gather_facts: no

  tasks:
  - name: Add the user 'ansibleuser' as an admin
    bigip_user:
      server: "{{ bigip_ip }}"
      user: "root"
      password: "default"
      username_credential: "{{ bigip_user }}"
      password_credential: "{{ bigip_passwd }}"
      shell: "bash"
      full_name: "{{ bigip_user }}"
      partition_access: "all:admin"
      update_password: "on_create"
      state: "present"
```

- playbookの実行

```
$ ansible-playbook -i hosts  useradd.yml
```

- 接続テストで使用したPlaybookで、作成したユーザの接続テスト

```
$ ansible-playbook -i hosts connection_test.yml
```

## 設定の保存
メモリ上の設定をファイルに保存しないと、再起動等で消えてしまうので保存する。
bigip_userのモジュールに限らず、他のモジュールでも同様と思われるので、設定変更して問題なければ保存するように。

- playbookの作成

```
$ vi sava.yml
```
```
- hosts: localhost
  become: no
  gather_facts: no

  tasks:
  - name: Save the running configuration of the BIG-IP
    bigip_config:
      save: yes
      server:         "{{ bigip_ip }}"
      user:           "{{ bigip_user }}"
      password:       "{{ bigip_passwd }}"
      validate_certs: "no"
      state: "present"
```

- playbookの実行

```
$ ansible-playbook -i hosts save.yml
```

## ライセンスキーのアクティベーション
ansibleにBIG-IPのアクティベーションのモジュールは無いよう。
こちら（ https://support.f5.com/csp/article/K2595 ）の手順を見るとtmshのコマンドは無い。
bigip_commandのモジュールではtmshでのコマンドになってしまうので、このモジュールが使えない。
Linuxサーバと同じようにSSHで接続して、rawモジュールでコマンド実行を行う。

- playbookの作成

```
$ vi regkey.yml
```

```
- hosts: bigip
  become: no
  gather_facts: no

  vars:
    ansible_user: "{{ bigip_user }}"
    ansible_password: "{{ bigip_passwd }}"

  vars_prompt:
  - name: "regkey"
    prompt: "Enter BIG-IP Registration key(XXXXX-XXXXX-XXXXX-XXXXX-XXXXXXX) "
    private: no

  tasks:
  - name: When activating a new license, specify only the base registration key in the get_dossier command
    raw: "get_dossier -b {{ regkey }}"
    register: result
  - debug: var=result.stdout_lines
```

- playbookの実行

```
$ ansible-playbook -i hosts regkey.yml
Enter BIG-IP Registration key(XXXXX-XXXXX-XXXXX-XXXXX-XXXXXXX) : XXXXX-XXXXX-XXXXX-XXXXX-XXXXXXX  <-- メールで送られてきたライセンスキーと一緒に、BIG-IP Registration keyとして記載されていた情報を入力。

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

TASK [When activating a new license, specify only the base registration key in the get_dossier command] *************************
changed: [bigip]

TASK [debug] *********************************************************
ok: [bigip] => {
    "result.stdout_lines": [
        "XXX・・・XXX"  <-- この結果(Dossier)を使用する。
    ]
}

PLAY RECAP ***********************************************************
bigip                      : ok=2    changed=1    unreachable=0    failed=0
```

- Registration keyのアクティベート
https://secure.f5.com/Infopage/index.jsp にアクセス
-> "Activate F5 product registration key"
-> "Enter Your Dossier"に、先ほど作成したDossierを入力して、次の画面に遷移
-> ライセンス許諾にチェックして、次の画面に遷移
-> ライセンスが作成されるので保存

- ライセンスファイルの作成
作成したライセンスを、ansibleのインストールされているマシンの、/opt/playbook/files/bigip.license に作成する。

- playbookの作成

```
$ vi license.yml
```

```
- hosts: bigip
  become: no
  gather_facts: no

  vars:
    ansible_user: "{{ bigip_user }}"
    ansible_password: "{{ bigip_passwd }}"

  tasks:
  - name: Copy license file
    copy:
      src: /opt/playbook/files/bigip.license
      dest: /config/bigip.license

  - name: reload the license
    raw: "reloadlic"
```

- playbookの実行

```
ansible-playbook -i hosts license.yml
```

## 設定の保存

- playbookの実行

```
$ ansible-playbook -i hosts save.yml
```

# 最後に
アクティベートは何度も実行するような作業ではないので、わざわざAnsibleを使わなくても良いかと思いますが、今回はAnsibleの検証なので使ってみました。次は、バーチャルサーバの作成を行いたいと思います。

# この記事に関して
この記事が提供している情報に関しては、合法性、正確性、安全性等、いかなる保証もされません。この記事を利用することによって生ずるいかなる損害に対しても一切責任を負いません。