AWX 設定作業 を Ansibleで 実施して自動化をシンプルに開始してみる

#   AWX 設定作業を Ansibleで 実施して自動化をシンプルに開始してみる
AWX の 各オブジェクトの 作成、管理するための モジュール郡 awx.awx Collectionが提供されているので、これらを利用して、AWX導入後の 設定作業を Ansibleで自動化することが可能です。 さらに、Github等で公開されているサンプルプレイブックを一緒に利用すれば、素早く 自動化運用の開始をするといったことも可能になるかと思います。

今回は、[Github で公開](https://github.com/NetApp-Automation)されている NetApp Ontapの運用フェーズ作業のサンプルプレイブック群を、 AWXでプロジェクト登録して、その中から NFSボリューム作成のプレイブックを ジョブテンプレート登録する作業を Ansibleのモジュールを利用して実施してみたので その内容を記載しています。



なお、AWX構成 及び Ansible実行環境（Execution Environment）用のコンテナイメージを準備済みである前提としています。その部分の作業は[以前の記事](https://qiita.com/yoihoka/items/e47f885a74c288a183d4)で紹介していますのでそちらも参考にしてください。

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

- AWX 20.0.1
- ansible 2.10.17
- Ansible Collection
    - netapp.ontap 21.21.0
    - awx.awx 21.3.0
- CentOS 7.7
- Python 3.6.8
- Ontap 9.9.1

## やってみること
1. AWX設定用の Ansible Playbook を準備
2. Ansibleを実行してAWX設定を実施する
3. 登録した ジョブテンプレートを実行してみる 
4. ジョブテンプレートに登録されている パラメータを 変更して実行してみる


## 1. AWX設定用の Ansible Playbook を準備
AWXの設定を実施するAnsible Playbookを準備します。

#### 1-1. Ansible Playbook配置用のディレクトリを作成
作業用のディレクトリを作成します。


```shell:
$ mkdir -p ~/awx/ansible/tasks ~/awx/ansible/vars
$ ls ~/awx/ansible/
tasks  vars
```

#### 1-2. playbookファイル（task)を~/awx/ansible/tasksディレクトリ配下に作成
tasksディレクトリ配下に、Playbookファイルを作成します。

AWXの設定を実施するために、AWX Organization / Inventory / Host / Project / Execution Environment / Job Template を登録するモジュールを利用しています。


```shell:
$ cat <<EOF > ~/awx/ansible/tasks/task_awx_modules.yaml
---
- hosts:              localhost
  gather_facts:       false
  vars:
    input: &input
      controller_host:     "{{ var_controller_host }}"
      controller_username: "{{ var_controller_username }}"
      controller_password: "{{ var_controller_password }}"
      validate_certs: "no"
  vars_files:
    - ../vars/var_awx_modules.yaml
  collections:
    - awx.awx
  tasks:
  - name: Create Organization in AWX
    awx.awx.organization:
      state:                     present
      name:                      "{{ org_name }}"
      <<: *input

  - name: Create Project in AWX
    awx.awx.project:
      state:                     present
      name:                      "{{ project_name }}"
      description:               "Git repository"
      organization:              "{{ org_name }}"
      scm_type:                  "git"
      scm_url:                   "{{ var_scm_url }}"
      scm_update_on_launch:      True
      scm_update_cache_timeout:  60
      <<: *input

  - name: Add LoD Inventory
    awx.awx.inventory:
      state:                     present
      name:                      "{{ inventory_name }}"
      description:               "Inventory"
      organization:              "{{ org_name }}"
      <<: *input

  - name: Host
    awx.awx.host:
      name: localhost
      inventory: "{{ inventory_name }}"
      state: present
      variables:
        ansible_connection        : "local"
        ansible_python_interpreter: "{{'{{'}} ansible_playbook_python {{'}}'}}"
      <<: *input


  - name: Add EE to the controller instance
    awx.awx.execution_environment:
      name:  "{{ ee_name  }}"
      image: "{{ ee_image }}"
      <<: *input

  - name: Create Job Template for "{{ jobtemp_name }}"
    awx.awx.job_template:
      state:                     present
      name:                      "{{ jobtemp_name }}"
      job_type:                  "run"
      inventory:                 "{{ inventory_name }}"
      project:                   "{{ project_name }}"
      execution_environment:     "{{ ee_name }}"
      playbook:                  "{{ playbook_name }}"
      ask_variables_on_launch:   "yes"
      survey_enabled:            "yes"
      survey_spec:
        name:                    "Default Survey for 'ONTAP Volume Create'"
        description:             ""
        spec:
        - { question_name: "NetApp ONTAP Cluster LIF", required: True, type: "text"    , variable: 'netapp_hostname', default: '{{ var_netapp_hostname_default }}' }
        - { question_name: "Admin User ID"           , required: True, type: "text"    , variable: 'netapp_username', default: '{{ var_netapp_username_default }}' }
        - { question_name: "Admin User PASSWORD"     , required: True, type: "password", variable: 'netapp_password', default: '{{ var_netapp_password_default }}' }
        - { question_name: "NFS Volume Name"         , required: True, type: "text"    , variable: 'volume_name'    , default: '{{ var_volume_name_default }}' }
        - { question_name: "NFS Volume Size(GB)"     , required: True, type: "text"    , variable: 'size'           , default: '10' }
        - { question_name: "ONTAP SVM(vserver) Name" , required: True, type: "text"    , variable: 'vserver'        , default: '{{ var_vserver_default}}' }
      extra_vars: {'https': 'true', 'validate_certs': 'false', 'state':'present','space_guarantee':'volume','comment': 'from awx' }
      <<: *input
EOF
$ ls tasks/
task_awx_modules.yaml
$ 
```

#### 1-3. playbookファイル（var)を~/awx/ansible/varsディレクトリ配下に作成
varsディレクトリ配下に、パラメータ用のファイルを作成します。

なお、利用する環境に合わせて 以下の値を更新したうえでファイルを作成します。

[更新が必要なパラメータ]
 -　 AWXのURL、ログインID、ログインパスワード  - 例： http://<<IPアドレス>> / admin / XXXXXXX
 -　 ansible実行環境用コンテナイメージの情報 - 例："DOCKER_ID"/ansible-ee:2.11-custom-v2
 -　 ONTAPの Cluster IP or SVM管理LIF IPアドレス、ログインID、ログインパスワード、SVM名

なお、 利用する ansible実行環境用コンテナイメージは、Ansible Collection :[Netapp.Ontap](https://docs.ansible.com/ansible/latest/collections/netapp/ontap/index.html)をCollectionとして導入してある必要があります。カスタマイズしたコンテナイメージを準備する手順は[別記事](https://qiita.com/yoihoka/items/7ab852bb9346ef6fe5b5)で紹介していますのでそちらも参考にしてください。

```shell:
$ cat <<EOF > ~/awx/ansible/vars/var_awx_modules.yaml
# AWX Connection Info
    var_controller_host:     "<< AWXのURL >>"
    var_controller_username: "<< AWXのログインID >>"
    var_controller_password: "<< AWXのログインパスワード >>"

# AWX Config
    var_scm_url    : "https://github.com/NetApp-Automation/Tower_defaults.git"

# AWX Job Info
    org_name       : "ORG 1234 from ansible"
    project_name   : "Project 1234 from ansible"
    inventory_name : "AWX INVENTORY from ansible"
    ee_name        : "AWX NetApp EE from ansible"
    ee_image       : "<< ansible実行環境用コンテナイメージの情報 >>"
    jobtemp_name   : "TEMPLATE 1234 from ansible"
    playbook_name  : "create_volume.yml"

# ONTAP INFO
    var_netapp_hostname_default : "<< Ontap Cluster LIF or SVM管理LIFのIPアドレス >>"
    var_netapp_username_default : "<< ONTAPログインID >>"
    var_netapp_password_default : "<< ONTAPログインパスワード >>"
    var_volume_name_default     : "nfsvol31_from_awx"
    var_vserver_default         : "<< ONTAP SVM名 >>"
EOF
$ ls vars/
var_awx_modules.yaml
$ 
```


## 2. Ansibleを実行してAWX設定を実施する
Playbookを実行します。


#### 2-1. awx.awx Collection導入
awx.awx Collection導入します。

```shell:
$ ansible-galaxy collection install awx.awx
/usr/local/lib/python3.6/site-packages/ansible/parsing/vault/__init__.py:44: CryptographyDeprecationWarning: Python 3.6 is no longer supported by the Python core team. Therefore, support for it is deprecated in cryptography and will be removed in a future release.
  from cryptography.exceptions import InvalidSignature
Starting galaxy collection install process
Process install dependency map
Starting collection install process
Installing 'awx.awx:21.3.0' to '/root/.ansible/collections/ansible_collections/awx/awx'
Downloading https://galaxy.ansible.com/download/awx-awx-21.3.0.tar.gz to /root/.ansible/tmp/ansible-local-26246cbvahfzx/tmp5b_m6yyc
awx.awx (21.3.0) was installed successfully
$ 
$ ansible-galaxy collection list
Collection       Version
---------------- -------
awx.awx          21.3.0
$ 
```

#### 2-2. AWX設定をAnsibleから実施
ansible-playbookコマンドを実行します。

```shell:
$ cd ~/awx/ansible/tasks
$ ansible-playbook task_awx_modules.yaml
/usr/local/lib/python3.6/site-packages/ansible/parsing/vault/__init__.py:44: CryptographyDeprecationWarning: Python 3.6 is no longer supported by the Python core team. Therefore, support for it is deprecated in cryptography and will be removed in a future release.
  from cryptography.exceptions import InvalidSignature
[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 [localhost] *************************************************************************************************************************************************************************************************************************************************************

TASK [Create Organization in AWX] ********************************************************************************************************************************************************************************************************************************************
[WARNING]: You are running collection version 21.3.0 but connecting to AWX version 20.0.1
changed: [localhost]

TASK [Create Project in AWX] *************************************************************************************************************************************************************************************************************************************************
changed: [localhost]

TASK [Add LoD Inventory] *****************************************************************************************************************************************************************************************************************************************************
changed: [localhost]

TASK [Host] ******************************************************************************************************************************************************************************************************************************************************************
changed: [localhost]

TASK [Add EE to the controller instance] *************************************************************************************************************************************************************************************************************************************
changed: [localhost]

TASK [Create Job Template for "TEMPLATE 1234 from ansible"] ******************************************************************************************************************************************************************************************************************
changed: [localhost]

PLAY RECAP *******************************************************************************************************************************************************************************************************************************************************************
localhost                  : ok=6    changed=6    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

$
```


## 3. 登録した ジョブテンプレートを実行してみる 
Ansible Playbookにより、AWX上に各種導入後の設定項目が登録されています。
テンプレートに、ONTAPのボリュームを作成するPlaybookが登録されていますので、それを実行してみます。
***
#### 3-1 ジョブテンプレート実行
AWXにアクセスし 画面左側にある、"リソース"→"テンプレート"をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/981926/11dd6085-4477-c883-8e82-f50b1f6893b8.png)

Ansibleで登録したJob Template 名 "**TEMPLATE** **1234** **from** **ansible**"をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/981926/febfcce7-bece-c8b7-ea59-b05c60477fc1.png)
**"起動"** をクリックします。

実行パラメータの指定等ができる画面が表示されます。
"**次へ**"をクリック → "**次へ**"をクリック → "**起動**" をクリックすると 処理が開始され処理結果が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/981926/8ac14740-20c7-cdb0-8be0-82ce8f8480c3.png)

この実行結果の情報は AWXの画面左側にある、"ビュー"→"ジョブ"の画面で 実行履歴として 後から再度確認が可能です。

#### 3-2 ジョブテンプレート実行結果確認
ONTAPにアクセスして、ボリュームが作成されていることを確認します。

```plaintext:
$ ssh << Ontap Cluster LIF or SVM管理LIFのIPアドレス >> -l << OntapのログインID >>
Password:

Last login time: MM/DD/YYYY hh:mm:ss
Unsuccessful login attempts since last login: 1
$ ontap::> volume show -vserver svm1 -volume nfsvol31_from_awx -fields size
vserver volume            size
------- ----------------- ----
svm1    nfsvol31_from_awx 10GB

$ ontap::> exit
```


## 4. ジョブテンプレートに登録されている パラメータを 実変更して実行してみる
AWXからジョブテンプレートを実行するタイミングで、パラメータに任意の値を指定することも可能です。
別のボリューム名を指定したり、ボリュームサイズを変更するなどが可能となります。

volume_nameの値を変更して先ほど作成したボリュームとは別のボリュームを作成してみます。

***
#### 4-1 ジョブテンプレート実行
AWXにアクセスし 画面左側にある、"リソース"→"テンプレート"をクリックします。
Ansibleで登録したJob Template 名 "**TEMPLATE** **1234** **from** **ansible**"をクリックし、
"**起動**"をクリックします


"**次へ**"をクリック → "**②Survey**"の画面で "NFS Volume Name"の値を ”nfsvol31_from_awx2”に変更して "**次へ**"をクリック → "**起動**" をクリックすると 処理が開始されます。
![Survey](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/981926/4dfb8b48-8bc2-edb7-5dcf-b083bcd7f382.png)

#### 4-2 ジョブテンプレート実行結果確認
ONTAPにアクセスして、ボリューム "nfsvol31_from_awx2" が作成されていることを確認します。

```plaintext:
$ ssh << Ontap Cluster LIF or SVM管理LIFのIPアドレス >> -l << OntapのログインID >>
Password:

Last login time: MM/DD/YYYY hh:mm:ss
Unsuccessful login attempts since last login: 1
$ ontap::> volume show -vserver svm1 -volume nfsvol31_from_awx* -fields size
vserver volume            size
------- ----------------- ----
svm1    nfsvol31_from_awx 10GB
svm1    nfsvol31_from_awx2
                          10GB
2 entries were displayed.

$ ontap::> exit
```


## まとめ
AWXの設定作業をAnsibleで実施してみました。
awx.awx Collectionモジュールと 公開されているサンプルのPlaybook を 組み合わせて利用すれば 素早く 自動化環境を構成できました。
自動化のための準備フェーズがシンプルになり 自動化運用を素早く スタートできるようになるのではないかと思います。

AWXを利用することでチーム単位での自動化運用が可能となり、定常運用などの効率化が期待できます。
自動化の効果を さらに広げていくことを考えた場合、エンドユーザ向けのリソース払い出しを、 Ansibleとポータル画面を連動させて 処理を自動化するといった使い方が考えられるかと思います。
そういった使い方も興味あれば是非試してみてください。