Ansibleを使ってStorage(ONTAP)を管理する5【System ManagerのPlaybook生成は使える？】

## はじめに
**ONTAP 9.9.1以降のVersionではSystem Managerと呼ばれるGUI管理ツールでVolumeやLUN作成のようなプロビジョニング操作をAnsible Playbookとして生成する事ができます。**

生成されるPlaybook用には、対話型や別ファイルで定義される変数がありますので、[前回の記事](https://qiita.com/s_yosh1d/items/6ce192226ad00c51c236)を参照する事で、より理解が進むかと思います。
この記事では、生成されたPlaybookの一部を修正し、実機での確認と実行を試みる内容になっています。

:::note Information
System ManagerではCLIとは異なり、PolicyやServiceレベル指定で設定を行います。
(CLIのような細かい指定を個々に実施しないで設定)
:::

![023.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1268577/03ed75b8-580d-b80f-e9f3-5e23817c0a3b.png)


## 何をしたい？できる？
- System ManagerでAnsible Playbookを作成する
- 生成されたPlaybookをSVM向け修正して実行する

## ONTAPのSystem Managerについて
System ManagerはGUIを使用して管理されるため、Webブラウザ上からStorageシステムやそのオブジェクト（SVM、Volume、LIF、Aggregateなど）の管理や一般的な管理作業が実行できます。

ただし、**GUIへのログインにはクラスタ管理者の認証が必要**であるため、各SVMに用意された管理者権限で操作することはできません。（SSHやAPIを使用することはできます。）
そのため、生成されたPlaybookにはクラスタ管理ようのIPの記載がなされる事になり、環境によっては各SVMの管理IPに修正する必要がある場合があります。

:::note alert
生成されたPlaybookはサンプル扱いの為、保証やサポートされるものではありません。(生成されたPlaybookのREADME.txtに記載)
:::


|<img width="400" alt="qiita-square" src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1268577/2510c03c-afce-66e8-1f41-e16362d38c0f.png>
|:-:|

## ONTAPのStorageサービスのレベル定義について
ONTAPには事前定義されたサービスレベルがあり、System ManagerではこのサービスレベルやQos Policyを指定してVolume作成を実施します。サービスレベルはDiskの種類で異なり、以下のように定義されています。
(このサービスレベルはONTAP上では変更できない)
(以下のIOPS等の内容はAdaptive QoSの内容と同じ)


|Storageサービス |対象Device　|IOPS(SLA)　|ピークIOPS　|最小IOPS　|想定Latency|
|:--------|:--------|:--------|:--------|:--------|:--------|
|value|全デバイス|128 per TB|512 per TB|75|17 ms|
|performance|AFF|2048 per TB|4096 per TB|500|2 ms|
|extreme|AFF|6144 per TB|12288 per TB|1000|1 ms|

<font color="Red">**最近のONTAPではSystem Managerでもマニュアル設定でAggregate指定をしてのVolume作成は可能ですが、現時点ではAnsible Playbook生成には反映されないので、この記事では実施しません。**</font>

StorageサービスをCLIで確認する際には、Advanceモードでstorage-service showコマンドを実行します。
```bash:
> set advanced
Warning: These advanced commands are potentially dangerous; use them only when directed to do so by NetApp personnel.
Do you want to continue? {y|n}: y


*> storage-service show -vserver cifs100 -instance

                 Vserver: cifs100
         Storage Service: -CAPACITY-TIER-CUSTOM-STORAGE-SERVICE-
             Description: Capacity Tier
             Is Internal: true
    Expected IOPS per TB: 128
Expected IOPS Allocation: allocated-space
        Peak IOPS per TB: 512
    Peak IOPS Allocation: used-space
   Absolute Minimum IOPS: 75
     Target Latency (ms): 17
          Aggregate List: aggr1_node1, aggr1_node2
         Aggregate Costs: 300, 300
            Vserver UUID: ec32fcb7-bc0a-11ed-b26c-00a098f0b86b
                    UUID: 40b6d132-4255-8e4c-9916-8fb0ce343f09

                 Vserver: cifs100
         Storage Service: extreme
             Description: Extreme
             Is Internal: false
    Expected IOPS per TB: 6144
Expected IOPS Allocation: allocated-space
        Peak IOPS per TB: 12288
    Peak IOPS Allocation: used-space
   Absolute Minimum IOPS: 1000
     Target Latency (ms): 1
          Aggregate List: aggr1_node1, aggr1_node2
         Aggregate Costs: 0, 0
            Vserver UUID: ec32fcb7-bc0a-11ed-b26c-00a098f0b86b
                    UUID: 0743fa34-43b7-4a87-ba8f-96816a0590a0

                 Vserver: cifs100
         Storage Service: maxdata
             Description: MAX Data ONTAP-Internal Performance
             Is Internal: true
    Expected IOPS per TB: 8000
Expected IOPS Allocation: allocated-space
        Peak IOPS per TB: 32000
    Peak IOPS Allocation: allocated-space
   Absolute Minimum IOPS: 8000
     Target Latency (ms): 1
          Aggregate List: aggr1_node1, aggr1_node2
         Aggregate Costs: 0, 0
            Vserver UUID: ec32fcb7-bc0a-11ed-b26c-00a098f0b86b
                    UUID: b4f11909-4323-1ee4-300c-a69e75466f85

                 Vserver: cifs100
         Storage Service: performance
             Description: Performance
             Is Internal: false
    Expected IOPS per TB: 2048
Expected IOPS Allocation: allocated-space
        Peak IOPS per TB: 4096
    Peak IOPS Allocation: used-space
   Absolute Minimum IOPS: 500
     Target Latency (ms): 2
          Aggregate List: aggr1_node1, aggr1_node2
         Aggregate Costs: 200, 200
            Vserver UUID: ec32fcb7-bc0a-11ed-b26c-00a098f0b86b
                    UUID: 0069e671-43bd-be20-dccf-f4983562b9a7

                 Vserver: cifs100
         Storage Service: value
             Description: Value
             Is Internal: false
    Expected IOPS per TB: 128
Expected IOPS Allocation: allocated-space
        Peak IOPS per TB: 512
    Peak IOPS Allocation: used-space
   Absolute Minimum IOPS: 75
     Target Latency (ms): 17
          Aggregate List: aggr1_node1, aggr1_node2
         Aggregate Costs: 300, 300
            Vserver UUID: ec32fcb7-bc0a-11ed-b26c-00a098f0b86b
                    UUID: f424a03e-407b-cfb0-a1a9-e4ac238cb842
5 entries were displayed.
```


## 記事における環境情報
本記事では、以下の環境で実施した内容となります。
(Ansible環境は過去の記事と同じ)
- ONTAP(AFF) : 9.10
- Object Storage(Tiering)は用意も設定も無し

**操作対象のSVMのAggregate listが空白の場合は、Playbook操作が失敗しますので、SVM新規作成時は注意が必要です。**(GUIでは操作できてPlaybookでは失敗する)

環境のイメージとしては以下の通りです。

|<img width="500" alt="qiita-square" src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1268577/6384ee71-5ab1-ca65-e444-f51aad7fc43b.png>
|:-:|



## 設定手順
この手順例では、Volume作成のPlaybookの生成を実行しています。


### 1. System Managerへのアクセス
クラスタ管理LIFのIPアドレスをWebブラウザのURLバーに入力し、表示された画面でアカウントを入力します。
|<img width="500" alt="qiita-square" src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1268577/af58b671-b0b7-7e6c-e823-dbd57eef8435.png>

### 2. System Manager上でVolume作成画面へ移動し、必要な値を記載

画面左側の[ストレージ]=>[ボリューム]をクリックし、表示された画面の上の方にある[追加]をクリックします。
|<img width="500" alt="qiita-square" src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1268577/227337b5-000c-39a2-9191-374acd3b2523.png>


表示された画面で、[その他のオプション]を選択します。
|<img width="400" alt="qiita-square" src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1268577/6ec72a93-0c5a-2898-50f9-c46040ca1333.png>


Volume作成に必要な内容を入力します。
**[パフォーマンスサービスレベル]の項目で、[カスタム]->[既存]からvalueを選択します。**
[パフォーマンスサービスレベル]の項目で、[カスタム]ではなく[バリュー]を選んだ場合は、QoSの最大値のみを設定されているqos policy-groupのvalue-fixedが適用されます。


画面下方の[Ansible Playbookに保存]をクリックすると、Playbookがダウンロードされます。
<img width="500" alt="qiita-square" src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1268577/4a703cc7-2fda-256a-3587-0a17da29df04.png>
<img width="500" alt="qiita-square" src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1268577/bd12cde8-010c-a693-64f5-a591a1abbb9f.png>


### 3. ダウンロードしたPlaybookの確認
Zip形式でダウンロードされたPlaybookを展開して内容を確認してみると、変数とPlaybookが分かれた形であることが確認できます。


|<img width="400" alt="qiita-square" src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1268577/c216fc70-1aba-247f-b405-316f11227629.png>

中を確認すると、対話型や別ファイルで記載するなどの方法で使用される変数や、
nas_application_templateで利用するtemplateの記載が確認できます。



<details><summary>volumeAdd.yaml</summary>

```rb
---
  -  hosts: localhost
     vars_prompt:
      - name: "username"
        prompt: "Enter UserName"
        private: no
      - name: "password"
        prompt: "Enter Password"
        private: yes
     
     vars:
        login: &login
          hostname: "{{ host.ip }}"
          username: "{{ username }}"
          password: "{{ password }}"
          https: true
          validate_certs: false
     vars_files:
      - volumeAdd_variable.yaml
     collections:
      - netapp.ontap
     tasks:

      - name: Prompt remote cluster IP
        pause:
          prompt: Please enter the remote cluster IP for creating Snapmirror relationship
        when: UserInputs.snapmirror is defined and (UserInputs.remoteClusterIP|default(None) == None)
        register: remoteClusterHostIP

      - set_fact:
          remoteClusterIP: "{{ UserInputs.remoteClusterIP if (UserInputs.remoteClusterIP|default(None) != None) else remoteClusterHostIP.user_input }}"
        when: UserInputs.snapmirror is defined

      - set_fact: 
          maxThroughput: "{{ UserInputs.nas_application_template.qos.policy.fixed.max_throughput_mbps + 'MB/s'  if((UserInputs.nas_application_template.qos.policy.fixed.max_throughput_mbps | default('', true) | trim != '') and UserInputs.nas_application_template.qos.policy.fixed.max_throughput_mbps != '0') else ''}}{{',' if ((UserInputs.nas_application_template.qos.policy.fixed.max_throughput_mbps | default('', true) | trim != '') and UserInputs.nas_application_template.qos.policy.fixed.max_throughput_mbps != '0') and ((UserInputs.nas_application_template.qos.policy.fixed.max_throughput_iops | default('', true) | trim != '') and UserInputs.nas_application_template.qos.policy.fixed.max_throughput_iops != '0') else ''}}{{UserInputs.nas_application_template.qos.policy.fixed.max_throughput_iops + 'iops'  if((UserInputs.nas_application_template.qos.policy.fixed.max_throughput_iops | default('', true) | trim != '') and UserInputs.nas_application_template.qos.policy.fixed.max_throughput_iops != '0') else '' }}"
          minThroughput: "{{ UserInputs.nas_application_template.qos.policy.fixed.min_throughput_mbps + 'MB/s'  if((UserInputs.nas_application_template.qos.policy.fixed.min_throughput_mbps | default('', true) | trim != '') and UserInputs.nas_application_template.qos.policy.fixed.min_throughput_mbps != '0') else ''}}{{',' if ((UserInputs.nas_application_template.qos.policy.fixed.min_throughput_mbps | default('', true) | trim != '') and UserInputs.nas_application_template.qos.policy.fixed.min_throughput_mbps != '0') and ((UserInputs.nas_application_template.qos.policy.fixed.min_throughput_iops | default('', true) | trim != '') and UserInputs.nas_application_template.qos.policy.fixed.min_throughput_iops != '0') else ''}}{{UserInputs.nas_application_template.qos.policy.fixed.min_throughput_iops + 'iops'  if((UserInputs.nas_application_template.qos.policy.fixed.min_throughput_iops | default('', true) | trim != '') and UserInputs.nas_application_template.qos.policy.fixed.min_throughput_iops != '0') else '' }}"
      - name: Create or modify qos policy
        when: UserInputs.nas_application_template.qos is defined and UserInputs.nas_application_template.qos.policy is defined and UserInputs.nas_application_template.qos.policy.name is defined and UserInputs.nas_application_template.qos.policy.name != 'none' and UserInputs.nas_application_template.qos.policy.name != 'extreme' and  UserInputs.nas_application_template.qos.policy.name != 'extreme-fixed' and  UserInputs.nas_application_template.qos.policy.name != 'value' and  UserInputs.nas_application_template.qos.policy.name != 'value-fixed' and UserInputs.nas_application_template.qos.policy.name != 'performance' and  UserInputs.nas_application_template.qos.policy.name != 'performance-fixed'
        na_ontap_qos_policy_group:
         state: present
         name: "{{ UserInputs.nas_application_template.qos.policy.name }}"
         vserver: "{{ UserInputs.svm.name }}"
         max_throughput: "{{ omit if( maxThroughput == '') else maxThroughput  }}"
         min_throughput: "{{ omit if( minThroughput == '') else minThroughput}}"
         is_shared: "{{ UserInputs.nas_application_template.qos.policy.fixed.capacity_shared | default(omit)}}"
         <<: *login
      - name:  create FlexVolume or FlexGroup
        when: UserInputs.name is defined and UserInputs.nas_application_template.flexcache is not defined
        na_ontap_volume:
          state: present
          name: "{{ UserInputs.name }}"
          vserver: "{{ UserInputs.svm.name }}"
          size:  "{{UserInputs.size}}"
          size_unit: "{{  (UserInputs.size_unit | lower) if (UserInputs.size_unit is defined) else 'gb' }}"
          auto_provision_as: "{{ UserInputs.auto_provision_as  | default(omit) }}"
          snapshot_policy: "{{ UserInputs.nas_application_template.snapshot_policy  | default(omit) }}"
          qos_policy_group: "{{ omit if( UserInputs.nas_application_template.qos.policy.name is not defined or  UserInputs.nas_application_template.qos.policy.name == 'extreme' or  UserInputs.nas_application_template.qos.policy.name == 'performance' or UserInputs.nas_application_template.qos.policy.name == 'value') else UserInputs.nas_application_template.qos.policy.name }}"
          qos_adaptive_policy_group: "{{ omit if( UserInputs.nas_application_template.qos.policy.name is not defined or  (UserInputs.nas_application_template.qos.policy.name != 'extreme' and  UserInputs.nas_application_template.qos.policy.name != 'performance' and UserInputs.nas_application_template.qos.policy.name != 'value')) else UserInputs.nas_application_template.qos.policy.name }}"
          export_policy: "{{ UserInputs.nas_application_template.export_policy.name  | default(omit) }}"
          nas_application_template: 
              use_nas_application: true
              storage_service: "{{ UserInputs.nas_application_template.storage_service.name  | default(omit) }}"
              tiering:
                  control: "{{ UserInputs.nas_application_template.tiering.control  | default(omit) }}"
                  policy: "{{ UserInputs.nas_application_template.tiering.policy  | default(omit) }}"
                  object_stores: "{{ UserInputs.nas_application_template.tiering.object_stores[0] | default(omit) }}"
              nfs_access: "{{ UserInputs.nas_application_template.nfs_access  | default(omit) }}"
              cifs_access: "{{ UserInputs.nas_application_template.cifs_access  | default(omit) }}"
          <<: *login
      - name:  create FlexCache
        when: UserInputs.name is defined and UserInputs.nas_application_template.flexcache is defined
        na_ontap_volume:
          state: present
          name: "{{ UserInputs.name }}"
          vserver: "{{ UserInputs.svm.name }}"
          size:  "{{UserInputs.size}}"
          size_unit: "{{  (UserInputs.size_unit | lower) if (UserInputs.size_unit is defined) else 'gb' }}"
          auto_provision_as: "{{ UserInputs.auto_provision_as  | default(omit) }}"
          snapshot_policy: "{{ UserInputs.nas_application_template.snapshot_policy  | default(omit) }}"
          qos_policy_group: "{{ omit if( UserInputs.nas_application_template.qos.policy.name is not defined or  UserInputs.nas_application_template.qos.policy.name == 'extreme' or  UserInputs.nas_application_template.qos.policy.name == 'performance' or UserInputs.nas_application_template.qos.policy.name == 'value') else UserInputs.nas_application_template.qos.policy.name }}"
          qos_adaptive_policy_group: "{{ omit if( UserInputs.nas_application_template.qos.policy.name is not defined or  (UserInputs.nas_application_template.qos.policy.name != 'extreme' and  UserInputs.nas_application_template.qos.policy.name != 'performance' and UserInputs.nas_application_template.qos.policy.name != 'value')) else UserInputs.nas_application_template.qos.policy.name }}"
          export_policy: "{{ UserInputs.nas_application_template.export_policy.name  | default(omit) }}"
          nas_application_template: 
            use_nas_application: true
            storage_service: "{{ UserInputs.nas_application_template.storage_service.name  | default(omit) }}"
            tiering:
                control: "{{ UserInputs.nas_application_template.tiering.control  | default(omit) }}"
                policy: "{{ UserInputs.nas_application_template.tiering.policy  | default(omit) }}"
                object_stores: "{{ UserInputs.nas_application_template.tiering.object_stores[0] | default(omit) }}"
            nfs_access: "{{ UserInputs.nas_application_template.nfs_access  | default(omit) }}"
            cifs_access: "{{ UserInputs.nas_application_template.cifs_access  | default(omit) }}"
            flexcache: 
                dr_cache: "{{ UserInputs.nas_application_template.flexcache.dr_cache  | default(omit) }}"
                origin_svm_name: "{{ UserInputs.nas_application_template.flexcache.origin_svm_name  | default(omit) }}"
                origin_component_name: "{{ UserInputs.nas_application_template.flexcache.origin_component_name | default(omit) }}"
          <<: *login

      - name:  modify FlexCache prepopulate folders
        when: UserInputs.nas_application_template.flexcache is defined and UserInputs.nas_application_template.flexcache.prepopulate.dir_paths is defined
        na_ontap_flexcache:
            state: present
            name: "{{ UserInputs.name }}"
            vserver: "{{ UserInputs.svm.name }}"
            prepopulate:  
              dir_paths: "{{ UserInputs.nas_application_template.flexcache.prepopulate.dir_paths | default(omit) }}"
              exclude_dir_paths: "{{ UserInputs.nas_application_template.flexcache.prepopulate.exclude_dir_paths | default(omit) }}"
              recurse: "{{ UserInputs.nas_application_template.flexcache.prepopulate.recurse | default(omit) }}"
            <<: *login

      - name: Create SnapMirror relationship
        when: UserInputs.snapmirror is defined
        na_ontap_snapmirror:
          state: present
          policy: "{{ UserInputs.snapmirror.policy.name | default(omit) }}"
          initialize: "{{ UserInputs.snapmirror.initialized }}"
          source_endpoint:
            cluster: "{{ UserInputs.snapmirror.source.cluster }}"
            consistency_goup_volumes: "{{ UserInputs.snapmirror.source.consistency_group_volumes | default(omit)}}"
            ipspace: "{{ UserInputs.snapmirror.source.ipspace | default(omit)}}"
            path: "{{ UserInputs.snapmirror.source.path }}"
          destination_endpoint:
            cluster: "{{ UserInputs.snapmirror.destination.cluster.name }}"
            consistency_goup_volumes: "{{ UserInputs.snapmirror.destination.consistency_group_volumes | default(omit) }}"
            path: "{{ UserInputs.snapmirror.destination.path }}"
          create_destination:
            enabled: "{{ UserInputs.snapmirror.create_destination.enabled }}"
            storage_service:
              enabled:  "{{ UserInputs.snapmirror.create_destination.storage_service.enabled }}"
              enforce_performance: "{{ UserInputs.snapmirror.create_destination.storage_service.enforce_performance }}"
              name: "{{ UserInputs.snapmirror.create_destination.storage_service.name | default(omit)}}"
            tiering:
              supported: "{{ UserInputs.snapmirror.create_destination.tiering.supported | default(omit) }}"
              policy: "{{ UserInputs.snapmirror.create_destination.tiering.policy | default(omit) }}"
          source_hostname: "{{ host.ip }}"
          hostname: "{{ remoteClusterIP }}"
          username: "{{ username }}"
          password: "{{ password }}"
          https: true
          validate_certs: false
```
</details>


<details><summary>volumeAdd_variable.yaml</summary>

```rb
# 変数ファイルのキーの間隔をフォーマットしたり変更したりしないでください。  文字列値を二重引用符（ "string" ）で囲むことを推奨します。
host:
    name: "localhost"
    ip: 192.168.123.45

# 選択したオブジェクトに適用するプロパティがコメントに含まれていないことを確認します。
UserInputs:
    name: "vol100"
    # 整数値のみを指定してください。
    size: 5368709120
    # 「size unit」の値には、「bytes」、「b」、「kb」、「MB」、「GB」、「TB」、「PB」、「eb」、「ZB」、または「YB」を使用できます。デフォルト値は「GB」です。
    size_unit: bytes
    #auto_provision_as: "-"
    svm:
        name: "cifs100"
    nas_application_template:
        # FlexCache ボリュームに Snapshot ポリシーを設定できません。
        snapshot_policy: "none"
        export_policy:
            name: "default"
        tiering:
            control: "disallowed"
            #policy: ""
            #object_stores:
            #- ""
        #storage_service:
            #name: ""
        qos:
            policy:
                name: "value"
                # 固定 QoS の詳細を指定します。  新しいポリシーを作成するときは、固定 QoS の詳細を指定し、名前を追加します。
                #fixed:
                # QoS 制限の「最小 / 最大スループット」の値を MB/ 秒で指定します。
                    #capacity_shared: 
                    #min_throughput_mbps: ""
                    #max_throughput_mbps: ""
                    #min_throughput_iops: ""
                    #max_throughput_iops: ""

        #nfs_access:
               #-   access:  "rw"
                   #host: "0.0.0.0/0"
            
        #cifs_access:
               #-   access:  "full_control"
                   #user_or_group: "Everyone"
            
        #flexcache:
            #dr_cache: true
            # リモートボリュームの名前を指定します
            #origin_component_name: ""
            # リモートクラスタの選択した Storage VM にピア関係が設定されている必要があります。名前の競合が発生しないように、ピア Storage VM のローカル名を指定します。
            #origin_svm_name: ""
            #prepopulate:
                #dir_paths:
                
                #exclude_dir_paths:
                
                #recurse: false

        # SnapMirror のビジネス継続性機能は、このリリースではサポートされていません。
        # Snapmirror inputs
    # SnapMirror 関係を作成するには、リモートクラスタの IP を入力してください。
    #remoteClusterIP:
    #snapmirror:
        #create_destination:
            #enabled: true
            #storage_service:
                #enabled: true
                #enforce_performance: true
                #name: 
            #tiering:
                #supported: 
                #policy: 
        #policy:
            #name: ""
        #initialized: "true"
        
        #destination:
            #cluster:
                #name: ""
            #path: ""
        #source:
            #cluster: ""
            #path: ""
            #ipspace: ""
```
</details>

### 4. Playbookの修正
実行環境で動作するように、以下の項目について修正を行います。
- volumeAdd.yamlのTaskのcreate FlexVolume or FlexGroupでnas_application_templateのtieringに関する内容を削除
- volumeAdd.yamlのvars_filesに記載した別ファイル名の変更(ファイル名を変えている場合)
- volumeAdd_variable.yamlのhostのipを操作対象のSVM管理IPに変更


**Tieringが設定されてない環境でnas_application_templateのtieringを削除せずにPlaybookを実行すると以下のようなエラーとなります。**

```bash:
TASK [create FlexVolume or FlexGroup] ***********************************************************************************************
fatal: [localhost]: FAILED! => {"changed": false, "msg": "Error getting object store for aggregate: aggr1_node2: calling: storage/aggregates/XXXXX/cloud-stores: got {'message': 'not authorized for that command', 'code': '6'}."}
```

ファイル修正後のdiffコマンドによる比較は以下の通りです。

```bash:
> diff volumeAdd_before.yaml volumeAdd_after.yaml
19c19
<       - volumeAdd_variable.yaml
---
>       - volumeAdd_variable_after.yaml
63,66d62
<               tiering:
<                   control: "{{ UserInputs.nas_application_template.tiering.control  | default(omit) }}"
<                   policy: "{{ UserInputs.nas_application_template.tiering.policy  | default(omit) }}"
<                   object_stores: "{{ UserInputs.nas_application_template.tiering.object_stores[0] | default(omit) }}"


> diff volumeAdd_variable_before.yaml volumeAdd_variable_after.yaml
4c4
<     ip: 192.168.123.45
---
>     ip: 172.16.10.147
```



### 5. Playbookの実行
Playbook実行の際に、SVM上のアカウント入力が必要になりますので、入力を実施します。

```bash:
>  ansible-playbook -i inventory.yml -u user01 volumeAdd_after.yaml --ask-pass
SSH password:
Enter UserName: testuser
Enter Password:

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

TASK [Gathering Facts] **************************************************************************************************************
ok: [localhost]

TASK [Prompt remote cluster IP] *****************************************************************************************************
skipping: [localhost]

TASK [set_fact] *********************************************************************************************************************
skipping: [localhost]

TASK [set_fact] *********************************************************************************************************************
ok: [localhost]

TASK [Create or modify qos policy] **************************************************************************************************
skipping: [localhost]

TASK [create FlexVolume or FlexGroup] ***********************************************************************************************
changed: [localhost]

TASK [create FlexCache] *************************************************************************************************************
skipping: [localhost]

TASK [modify FlexCache prepopulate folders] *****************************************************************************************
skipping: [localhost]

TASK [Create SnapMirror relationship] ***********************************************************************************************
skipping: [localhost]

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

Storage側でVolumeが作成されている事を確認します。

```bash:
>  volume show -vserver cifs100 -volume vol100 -fields volume,size,qos-adaptive-policy-group
vserver volume size qos-adaptive-policy-group
------- ------ ---- -------------------------
cifs100 vol100 5GB  value

```



## 参考及びリンク
[Storage service definitions](https://docs.netapp.com/us-en/ontap/s3-config/storage-service-definitions-reference.html)

[Ansibleを使ってStorage(ONTAP)を管理する1 【Rocky LinuxへAnsible Install編】](https://qiita.com/s_yosh1d/items/f437b8ea284a6e90936f)

[Ansibleを使ってStorage(ONTAP)を管理する2【ChatGPTでVolume作成用Playbookを作成】](https://qiita.com/s_yosh1d/items/6774760fd046c0314618)

[Ansibleを使ってStorage(ONTAP)を管理する3【変数編1】](https://qiita.com/s_yosh1d/items/62b2c89250ccc7698e70)

[Ansibleを使ってStorage(ONTAP)を管理する4【変数編2】](https://qiita.com/s_yosh1d/items/6ce192226ad00c51c236)