Amazon FSx for NetApp ONTAP で Ansible を 試してみる

# Amazon FSx for NetApp ONTAP で NetApp Ansibleモジュールを 試してみる
Amazon FSx for NetApp ONTAPは、AWSコンソールや、NetAppのCloudManagerから GUI画面での操作が可能ですが、Ansibleを利用して 管理操作を自動化することも可能です。実際に試してみたので、手順をご紹介します。

なおAmazon FSx for NetApp ONTAPは デプロイ後の作業を記述しています。
Amazon FSx for NetApp ONTAPのデプロイはAWSコンソールから簡単に行えますが、Terraformを利用したデプロイの自動化も可能です。そちらの手順については[別の記事](https://qiita.com/yoihoka/items/9989859184c83b87d8db)で紹介しています。

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

- Amazon Linux v2
- Ansible 2.9.23
- Python 3.7.10
- NetApp-lib : 2021.6.25
- netapp.ontap:21.14.1

なお、この記事で書かれている 手順やファイルは動作を保証されたものではありません。
各環境に合わせてテスト・確認をしたうえで自己責任にて利用していただければと思います。

# 作業概要
EC2インスタンス（Linuxサーバ）にAnsibleを導入して、Amazon FSx for NetApp ONTAP上でボリューム作成を実行し、作成したVolumeをEC2インスタンス(Linuxサーバ）からNFSマウントするAnsibleのplaybookを実行をします。

　　　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/981926/084a4f9f-3440-3573-dcaf-5628ad621dd1.png)


なお、Ansibleを実行するEC2インスタンス(Linuxサーバ） と FSx for NetApp ONTAP間で TCP 22 / 443 ポートの通信が発生します。必要に応じて 事前にセキュリティグループの設定等を実施してください。



[作業の流れ]
　1. EC2インスタンス（Linuxサーバ）へのAnsible導入
　2. Ansible playbook準備
　3. Ansible 実行(ボリューム作成 ＆ NFSマウント)
　4. Ansible 実行(ボリューム削除 & NFSアンマウント)



### 1. EC2インスタンス（Linuxサーバ）へのAnsible 導入
Ansible及び必要なライブラリなどを導入します。
今回はAmazon Linuxを利用しているので、amazon-linux-extrasを利用してAnsibleをインストールしています。
また、あわせて、Ansibleコレクション及び必要なpythonライブラリも導入しています。

```shell:
$ sudo amazon-linux-extras install ansible2 -y
Installing ansible
〜〜出力省略〜〜
完了しました!
$ sudo pip3 install NetApp-Lib
WARNING: Running pip install with root privileges is generally not a good idea. Try `pip3 install --user` instead.
Collecting NetApp-Lib
〜〜出力省略〜〜
Installing collected packages: lxml, six, xmltodict, NetApp-Lib
Successfully installed NetApp-Lib-2021.6.25 lxml-4.6.4 six-1.16.0 xmltodict-0.12.0
$ sudo ansible-galaxy  collection install netapp.ontap -p /usr/share/ansible/collections
Process install dependency map
Starting collection install process
Installing 'netapp.ontap:21.14.1' to '/usr/share/ansible/collections/ansible_collections/netapp/ontap'
$ sudo ansible-galaxy  collection install ansible.posix -p /usr/share/ansible/collections

```

### 2. Ansible playbook準備
Ansibleのイベントリファイル及びplaybookファイルなどを作成します。

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

```shell:ディレクトリ・ファイル構成
~/work
   ├─ inventory
   ├─ ontap_volume.yaml
   ├─ volume_delete.yaml
   └─ vars.yaml

```

まずはインベントリ及び2つのplaybookファイルを作成します。


```shell:
$ mkdir ~/work
$ cat <<EOF > ~/work/inventory
ansitest01 ansible_host=127.0.0.1

[all:vars]
ansible_ssh_port=22
ansible_ssh_user=ec2-user
become=yes
ansible_ssh_common_args='-o StrictHostKeyChecking=no'
EOF
$ cat <<EOF > ~/work/ontap_volume.yaml
- name: ONTAP SVM NFS Volume Create
  hosts: ansitest01
  gather_facts: no
  become: yes
  vars_files:
    vars.yaml
  tasks:
    - name: make volume.
      na_ontap_volume:
        state          : present
        validate_certs : no
        https          : yes
        hostname: "{{ cluster_mgmt_ip }}"
        username: "{{ cluster_username }}"
        password: "{{ cluster_password }}"
        vserver: "{{ nfs_svm_name }}"
        name: "{{ nfs_volume_name }}"
        size: "{{ nfs_volume_size  }}"
        size_unit: gb
        space_guarantee: none
        aggregate_name: "{{ aggregate_name }}"
        volume_security_style: unix
        type: rw
        is_online: yes
        junction_path: "/{{ nfs_volume_name }}"
        snapshot_policy: none
      delegate_to: localhost

    - name: directory create
      ansible.builtin.file: path="{{ nfs_mount_dir }}" state=directory owner=ec2-user group=ec2-user mode=775

    - name: vm mount disk
      ansible.posix.mount:
        path: "{{ nfs_mount_dir }}"
        src: "{{ svm_nfs_ip }}:/{{ nfs_volume_name }}"
        fstype: nfs
        opts: _netdev
        state: mounted

    - name: directory modify
      ansible.builtin.file: path="{{ nfs_mount_dir }}" state=directory owner=ec2-user group=ec2-user mode=775
EOF
$ cat <<EOF > ~/work/volume_delete.yaml
- name: ONTAP SVM NFS Volume Delete
  hosts: ansitest01
  gather_facts: no
  become: yes
  vars_files:
    vars.yaml
  tasks:
    - name: unmount nfs volume
      ansible.posix.mount:
        path: "{{ nfs_mount_dir }}"
        src: "{{ svm_nfs_ip }}:/{{ nfs_volume_name }}"
        fstype: nfs
        opts: _netdev
        state: absent

    - name: delete directory
      ansible.builtin.file: path="{{ nfs_mount_dir }}" state=absent owner=ec2-user group=ec2-user mode=775

    - name: delete volume
      na_ontap_volume:
        state          : absent
        validate_certs : no
        https          : yes
        hostname: "{{ cluster_mgmt_ip }}"
        username: "{{ cluster_username }}"
        password: "{{ cluster_password }}"
        vserver: "{{ nfs_svm_name }}"
        name: "{{ nfs_volume_name }}"
        aggregate_name: "{{ aggregate_name }}"
      delegate_to: localhost
EOF
$
```
次にパラメータを記述するvars.yamlファイルを作成します。

vars.yamlファイルについては、FSxNの環境に合わせて以下の値を更新したうえでファイルを作成します。

[更新が必要なパラメータ]
  -　 ファイルシステム 管理エンドポイントIPアドレス
  -　 fsxadminユーザのパスワード
  -　 ストレージ仮想マシン SVM名
  -　 ストレージ仮想マシン NFS IPアドレス


```shell:
$ cat <<EOF > ~/work/vars.yaml
# vars
    ansible_python_interpreter: /usr/bin/python3
    aggregate_name: aggr1
    cluster_mgmt_ip: ＜＜ファイルシステムの管理エンドポイント IPアドレスを入力＞＞
    cluster_username: fsxadmin
    cluster_password: ＜＜fsxadminのパスワードを入力＞＞
    nfs_svm_name: ＜＜ストレージ仮想マシンのSVM名を入力＞＞
    svm_nfs_ip: ＜＜ストレージ仮想マシンのNFS IPアドレスを入力＞＞
    nfs_volume_name: ansi_nfsvol01
    nfs_volume_size: 3
    nfs_mount_dir: "/home/ec2-user/mnttest"
EOF
$ 
```


### 3. Ansible 実行(ボリューム作成 ＆ NFSマウント)
Ansibleを実行し、FSx for NetApp ONTAP上にNFSボリュームを作成します。
実行時に、実行対象情報の入力プロンプトが表示されるので、必要情報を入力することで、FSx for NetApp Ontap上に NFSボリュームが作成されます。

なお、EC2インスタンス上で、~/.ssh/id_rsaファイルを配置して公開鍵認証でssh接続できる設定を実施しています。パスワード認証を利用している場合は、--ask-passオプションをつけて実行するなどの対応をしてください。

```shell:
$ cd ~/work
$ ansible-playbook -i inventory ontap_volume.yaml

PLAY [ONTAP SVM NFS Volume Create] *************************************************************************************************************************************************************

TASK [make volume.] ****************************************************************************************************************************************************************************
changed: [ansitest01]

TASK [directory create] ************************************************************************************************************************************************************************
changed: [ansitest01]

TASK [vm mount disk] ***************************************************************************************************************************************************************************
changed: [ansitest01]

TASK [directory modify] ************************************************************************************************************************************************************************
changed: [ansitest01]

PLAY RECAP *************************************************************************************************************************************************************************************
ansitest01                 : ok=4    changed=4    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

$ df -h |grep mnttest
＜＜NFS IPアドレス＞＞:/ansi_nfsvol01   2.9G  320K  2.9G    1% /home/ec2-user/mnttest
$ cd /home/ec2-user/mnttest
$ echo "test" >> testfile
$ cat testfile
test
$ 
```
※ Ansible実行時に”Connectino timed out"が発生する場合、TCP 443ポートでの通信が許可されていないことが原因の可能性があります。その場合はセキュリティグループの設定を確認してみてください。

Ansible実行完了後に確認してみると、NFSボリュームが作成されてマウント用に作成したディレクトリでNFSマウントされていることが確認できます。

### 4. Ansible 実行(ボリューム削除 ＆ NFSアンマウント)
今度はAnsibleを利用して、アンマウントしてボリュームを削除するplaybookを実行します。

```shell:

$ cd ~/work
$ ansible-playbook -i inventory volume_delete.yaml

PLAY [ONTAP SVM NFS Volume Delete] *************************************************************************************************************************************************************

TASK [unmount nfs volume] **********************************************************************************************************************************************************************
changed: [ansitest01]

TASK [delete directory] ************************************************************************************************************************************************************************
ok: [ansitest01]

TASK [delete volume] ***************************************************************************************************************************************************************************
changed: [ansitest01]

PLAY RECAP *************************************************************************************************************************************************************************************
ansitest01                 : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

$ df -h |grep mnttest
$ ls  /home/ec2-user/mnttest
ls: /home/ec2-user/mnttest にアクセスできません: No such file or directory
$
```
ボリュームがアンマウントされ、マウント用に作成していたディレクトリも削除されていることが確認できます。


### x. 参考： ストレージ仮想マシン毎のユーザ作成
参考としてボリュームを新規作成する際に利用可能なFSx for NetApp ONTAPのストレージ仮想マシン ユーザを作成してみます。Ansible実行時に、fsxadminを利用しないで、かわりにここで作成したユーザでAnsibleのplaybookを実行することが可能です。


```shell:
$ ssh ＜＜ファイルシステムの管理エンドポイント IPアドレス＞＞ -l fsxadmin
$ security login role create -role ＜＜Role名＞＞ -cmddirname volume -access all -query "" -vserver ＜＜SVM名＞＞
$ security login role create -role ＜＜Role名＞＞ -cmddirname "event generate-autosupport-log" -access all -query "" -vserver ＜＜SVM名＞＞
$ security login create -user-or-group-name ＜＜ユーザ名＞＞ -application ssh -authentication-method password -role ＜＜Role名＞＞ -vserver ＜＜SVM名＞＞
$ security login create -user-or-group-name ＜＜ユーザ名＞＞ -application ontapi -authentication-method password -role ＜＜Role名＞＞ -vserver ＜＜SVM名＞＞
```

作成したユーザを利用する場合は、vars.yamlファイルの値に反映してください。ユーザ名、パスワードとあわせて、ファイルシステムの管理エンドポイント IPアドレスも ストレージ仮想マシン管理IPアドレスに変更が必要です。


# まとめ
Ansibleを利用したAmazon FSx for NetApp ONTAPでのNFSボリューム作成＆マウントを自動化する手順を紹介させていただきました。

今回はfsxadminユーザを利用しましたが、参考のところで紹介したようにFSx for NetApp Ontapのストレージ仮想マシン毎にユーザを作成してAnsibleを実行することも可能です。その場合、利用者側でボリューム作成からマウント操作などを自動化して利用して頂くといった運用も可能かと思います。

ストレージ側単体で自動化するだけでなく、サーバ側での設定などを含めた一連の自動化の仕組みに組み込んだりすると、より便利に利用することも可能になるかと思います。