ansible-builderでNetApp Ansibleモジュール用の実行環境を準備してみる

# ansible-builderでNetApp Ansibleモジュール用の実行環境を準備してみる
Ansible実行環境の作成を支援するツール["ansible-builder"](https://www.ansible.com/blog/introduction-to-ansible-builder)を利用すると、任意のAnsible Collectinoやpythonモジュールが導入された自動化実行環境(Execution Environment)用のコンテナイメージを簡単に準備することができます。

AWXやAnsible Contorollerも 制御プレーンと実行プレーンが分離された分散型のモジュラーアーキテクチャとなり、Ansilbeは自動化実行環境用コンテナイメージ上で実行されるようになります。そのような利用シーンで、ansible-builderを利用してplaybookの要件にあわせた自動化実行環境用コンテナイメージをシンプルな手順で用意することが可能です。

実際にNetApp Ansibleモジュールを利用するplaybookの要件をみたす自動化実行環境用コンテナイメージ作成を試してみましたので、その手順をご紹介します。

##前提
以下の環境で試しています

- Cent 7.7
- Python 3.6.8
- docker 20.10.9
- ansible-builder 1.0.1


##やってみること
1. ansible-builder インストール 
2. ansible-builder で ansible実行環境用コンテナイメージを作成
3. 簡単なNetApp Ansibleモジュールを利用するplaybook を実行してみる

##ディレクトリ・ファイル構成
作成する各ディレクトリ・ファイルの構成・配置は以下となります。

```shell:ディレクトリ・ファイル構成
~/builder
   ├─ execution-environment.yml
   ├─ requirements.txt
   └─ requirements.yml
~/runner
      ┝─ env
      │   └─ settings     
      └─ project 
          └─ ontap_info.yaml
```

## 1. ansible-builderインストール
まずはansible-builderをインストールします。

[Ansibleのサイト](https://www.ansible.com/blog/introduction-to-ansible-builder)でも紹介されていますので、そちらも参照してください。


前提にも記載している通り、今回はCentOS 7を利用した場合の作業例を記載します。


```shell:
$ sudo python3 -m pip install ansible-builder
〜出力省略〜
$ ansible-builder --version
1.0.1
```


## 2. Ansible実行環境用のコンテナイメージを作成
ansible-builderを利用して、新しいAnsible実行環境用のコンテナイメージを作成します

今回は、作成したコンテナイメージはDocker Hubにアップロードしてみます。
プライベートレジストリがある場合はそちらへのアップロードの方が快適に利用できるかと思います。



| パラメータ名 | 値 | 備考
|:---:|---|---|
|実行環境イメージ名|　ansible-ee:stable-2.11-custom-v2 | 
|Baseとするイメージ| quay.io/ansible/ansible-runner:stable-2.11-latest|



前提にも記載している通り、今回はCentOS 7を利用した場合の作業例を記載します。


```shell:
$ DOCKER_ID=<<Docker ID>>
$ sudo docker login -u $DOCKER_ID
Password: <<Docker IDのパスワード>>
Login Succeeded
$ mkdir builder
$ cd builder
$ cat <<EOF > execution-environment.yml
---
version: 1
 
build_arg_defaults:
  EE_BASE_IMAGE: quay.io/ansible/ansible-runner:stable-2.11-latest
 
dependencies:
  galaxy: requirements.yml
  python: requirements.txt
EOF
$ cat <<EOF > requirements.txt
netapp-lib
solidfire-sdk-python
EOF
$ cat <<EOF > requirements.yml
---
collections:
  - name: netapp.ontap
  - name: netapp.elementsw
EOF
$ sudo ansible-builder build --tag $DOCKER_ID/ansible-ee:2.11-custom-v2 --container-runtime docker
$ sudo docker push $DOCKER_ID/ansible-ee:2.11-custom-v2


```
※ ansible-builder実行時、"Please provide a source image with `from` prior to commit"というエラーメッセージが表示される場合 Dockerのバージョンが古いことが原因の可能性（要バージョンアップ）。
※ ansible-builderコマンドが見つからない旨のメッセージが表示される場合は、PATHの問題の可能性（フルパス指定で実行）＜ 例：sudo /usr/local/bin/ansible-builder build --tag $DOCKER_ID/ansible/ee:2.11-custom-v2 --container-runtime docker ＞



## 3. 簡単なNetApp Ansibleモジュールを利用するplaybook を実行してみる
ansible-runnerというコマンドを利用して、作成した実行環境用のコンテナイメージ上でplaybookを実行できます。
今回は対象のNetAppのストレージOS Ontapの情報を出力する簡単なplaybookを実行してみます。

ansible-builderで作成した自動化実行環境用のコンテナイメージ名は、envディレクトリ配下のsettingファイルに記述しておきます。（じっk）
利用するイメージ名などを記述しておくことで、自動的にその情報を読み込んで実行してくれます。

```shell:
$ cd ~
$ mkdir -p ~/runner/env ~/runner/project
$ cat <<EOF > ~/runner/env/settings
container_image: `echo $DOCKER_ID`/ansible-ee:2.11-custom-v2
process_isolation_executable: docker
process_isolation: true
EOF
$ cat <<EOF > ~/runner/project/ontap_info.yaml
---
- name: ONTAP INFO
  hosts: localhost
  gather_facts: no
  vars:
    cluster_hostname: "10.128.211.112"
    cluster_username: "admin"
    cluster_password: "NetApp123$"
  tasks:
    - name: ontap info
      netapp.ontap.na_ontap_rest_info:
        validate_certs : no
        https          : yes
        hostname: "{{ cluster_hostname }}"
        username: "{{ cluster_username }}"
        password: "{{ cluster_password }}"
      register: ontap_info

    - name: msg
      debug: var=ontap_info
EOF
$ sudo pip3 install ansible-runner
$ sudo ansible-runner run runner -p ontap_info.yaml
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'

PLAY [ONTAP INFO] *************************************************************************************************************************************************

TASK [ontap info] *************************************************************************************************************************************************
[WARNING]: option 'state' is deprecated.
ok: [localhost]

TASK [msg] ********************************************************************************************************************************************************
ok: [localhost] => {
〜出力省略〜
PLAY RECAP ********************************************************************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
$
```

※ コマンドが見つからない旨のメッセージが表示される場合はコマンドをフルパスで指定  : ＜ 例 ：sudo /usr/local/bin/ansible-runner run runner -p ontap_info.yaml　＞

※ envディレクトリにsettingsファイルを置く代わりに実行時のオプション指定も可能  ＜ 例：sudo /usr/local/bin/ansible-runner run runner -p ontap_info.yaml --container-image  `echo $DOCKER_ID`/ansible-ee:2.11-custom-v2 --process-isolation --process-isolation-executable docker ＞


NetAppモジュール実行に必要なPython Library、 Ansible Collectionを導入済みのAnsible実行環境のコンテナイメージ上で playbookを実行することでされ、正常に処理が行われています。


## まとめ
ansible-builderで実行環境の作成を試してみました。
ansible-builderを利用することで数コマンドで簡単に自動化実行環境用のコンテナイメージ作成が可能です。

自動化実行環境用のコンテナイメージを複数用意することで、playbookにあわせて実行環境を使い分けるといったことも可能かと思います。

今回はansible-runnerを利用して動作を確認しましたが、ここで作成したAnsible実行環境はAWX等で実行環境として登録・利用が可能なものとなります。興味ある方はぜひAWX環境での利用を試してみてください。

AWXを簡易的に試すためシングルホストで構成する手順が[NetAppのサイト](https://netapp.io/2021/08/19/how-to-guide-setting-up-awx-on-a-single-host/)でも紹介されていますので参考になるかと思います。