Ansible uri モジュールを使用してPowerVC API でボリューム・クローニングを実行

#### はじめに

PowerVC で Ansible の uri モジュールを用いて API でのボリュームのクローニングを確認しました。

・PowerVC : [Clone volume API](https://www.ibm.com/docs/en/powervc/2.0.2?topic=apis-clone-volume-api)
・PowerVC : [Images (Glance) APIs](https://www.ibm.com/docs/en/powervc/2.0.2?topic=apis-images-glance)

---
#### 環境

・PowerVC 2.0.2 (RHEL 8.4, ppc64le on S824)
・Ansible 2.13.1, python 3.10.5 (localhost, Mac に導入して実行)


---
#### 実行スクリプト


クローン対象は VM の ブートボリュームです。


```clone_volume.yml
---
- name: Cloning Virtual Machine Boot Volume
  hosts: localhost
  gather_facts: no
  vars:
    powervc_ip: <PowerVC IP address>      #<= 要編集
    tenant_id: <PowerVC Tenant ID>　　　   #<= 要編集
    target_vm_id: <取得対象のVM ID>        #<= 要編集
  tasks:
   - name: Get auth token
     uri:
       url: "https://{{ powervc_ip }}:5000/v3/auth/tokens"
       method: POST
       headers:
         Accept: application/json
       body: "{{ lookup('template', 'token.json') }}"
       body_format: json
       return_content: yes
       status_code: 201
       validate_certs: no
     register: auth_token

   - name: Set Variable OS_TOKEN
     set_fact: OS_TOKEN="{{ auth_token.x_subject_token }}"

   - name: Volume Cloning
     uri:
       url: 'https://{{ powervc_ip }}:9000/v3/{{ tenant_id }}/clone-volumes'
       method: POST
       headers:
         X-Auth-Token: "{{ OS_TOKEN }}"
         Accept: application/json
       body_format: json
       body: "{{ lookup('template', 'clone_volume.json') }}"
       return_content: yes
       status_code: 202
       validate_certs: no
       timeout: 300
     register: clone_volume

   - name: show previous stdout
     debug:   
       var: clone_volume
```

```clone_volume.json
{ 
	"clone-volumes": {
		"display-name": "test0822",
    	"description": "clone-test0822",
    	"volumes": ["c7xxxxbb-a85f-xxxx-99b3-ce8xxxx5eb"]
 	}
}
```



---

#### 実行


```
$ time ansible-playbook clone_volume.yml

PLAY [Cloning Virtual Machine Boot Volume] ***************************************************************************************************************************************************************************

TASK [Get auth token] ***************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [Set Variable OS_TOKEN] ********************************************************************************************************************************************************************************************
ok: [localhost]

TASK [Volume Cloning] ***************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [show previous stdout] *********************************************************************************************************************************************************************************************
ok: [localhost] => {
    "clone_volume": {
        "changed": false,
        "connection": "close",
        "content": "{\"clone-volumes\": {\"task_uri\": \"https://XX.xx.XX.XX:9000/v3/exxxxx5624915b4xxxxdfbb6fb83/clone-volumes/get_progress?action=clone-volumes&task_id=9560xxxx3-96fc-48e4-9xxx-3639xxxx585a\"}}",
        "content_length": "188",
        "content_type": "application/json",
        "cookies": {},
        "cookies_string": "",
        "date": "Mon, 22 Aug 2022 04:53:27 GMT",
        "elapsed": 3,
        "failed": false,
        "json": {
            "clone-volumes": {
                "task_uri": "https://XX.xx.XX.XX:9000/v3/exxxxx5624915b4xxxxdfbb6fb83/clone-volumes/get_progress?action=clone-volumes&task_id=95xxxx-96fc-48e4-99ef-36xxxxx"
            }
        },
        "msg": "OK (188 bytes)",
        "openstack_api_version": "volume 3.0",
        "redirected": false,
        "server": "Apache",
        "status": 202,
        "url": "https://XX.xx.XX.XX:9000/v3/exxxxx5624915b4xxxxdfbb6fb83/clone-volumes",
 

```

"msg" OK が出力しています。

---

#### 確認

・GUI で確認
![スクリーンショット 2022-08-22 13.55.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517421/8aff3a9d-26fe-29cd-c087-5376852f4f5e.png)

目的のボリュームが作成されています。


・確認スクリプトでの確認

available かどうかを確認しています。

```get_volume.yml

---
- name: Get Clone Volume Information
  hosts: PowerVC_Server
  gather_facts: no
  vars:
    powervc_ip: <PowerVC IP address>         #<= 要編集
    tenant_id: <PowerVC Tenant ID>　　　      #<= 要編集
    target_vm_id: <取得対象のVM ID>            #<= 要編集
    volume_name: <対象のボリューム名>           #<= 要編集
    OS_USERNAME: <openstack cli 実行ユーザー>  #<= 要編集
    OS_PASSWORD: <パスワード>                  #<= 要編集
    tmpfile: <一時ファイル(/tmp/ansible_volume_tmp.txt)>    #<= 要編集
  tasks:
   - name: get get volume status via openstack CLI
     shell: |
         exec 2>&1
         source /opt/ibm/powervc/powervcrc
         export OS_USERNAME={{ OS_USERNAME }}
         export OS_PASSWORD={{ OS_PASSWORD }}
         openstack volume show clone-{{ volume_name }} > {{ tmpfile }}
         export STATUS=`cat {{ tmpfile }} | grep "| status" | awk '{print $4}'`
         export VOLUME_NAME=`cat {{ tmpfile }}| grep "name" | awk '{print $4}'`
         echo $VOLUME_NAME
         if [[ $STATUS = available ]] ; then
            echo "target volume status is available"
            exit 0
         else 
            echo "target volume status is NOT available"
            exit 10
         fi
         rm {{ tmpfile }}
     register: volume_status 

   - debug:   
        var: volume_status.stdout_lines

```

実行

```
$ time ansible-playbook get_volume.yml

PLAY [Get Clone Volume Information] *************************************************************************************************************************************************************************************

TASK [get get volume status via openstack CLI] **************************************************************************************************************************************************************************
changed: [PowerVC_Server]

TASK [debug] ************************************************************************************************************************************************************************************************************
ok: [PowerVC_Server] => {
    "volume_status.stdout_lines": [
        "clone-test0822",
        "target volume status is available"
    ]
}

PLAY RECAP **************************************************************************************************************************************************************************************************************
PowerVC_Server              : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

ansible-playbook get_volume.yml  0.69s user 0.24s system 13% cpu 6.938 total
$
```

---

#### 課題

・確認スクリプトはAPIの実行で確認しようとしましたが、取得したい値を綺麗に成形できず結局shell モジュールで openstack コマンドを発行しました。一旦はスクリプトはこのままとして、目的の値の取り方はあると思いますので課題として保留しておこうと思います。
・変数が多くなってきたのでそろそろ外部ファイル化が必要。
・パスワードは Ansible vault もしくは環境変数ファイルを変更するか実装検討中。


以上です。