PowerVC  API を直接実行してAnsible でVMをデプロイ (ansible-galaxy collection を使用しない方法)

#### はじめに

以前、Ansible で PowerVC の 仮想マシン・デプロイを実行した際は ansible-galaxy openstack.cloud collection モジュール を使用していましたが、今回 uri モジュール用いた API 直接実行の方法を確認しました。

https://qiita.com/c_u/items/08957da470ad6c933ce8


uri モジュールを使用して API を実行できるのであれば、余計なモジュールダウンロードが不要なところがよい点かと思います。


(コードの書きづらさがあるかもしれませんが、最近は Generative AI を利用できるから負荷は軽減されそうです。watsonx を使ってみたいこの頃です。)


---
#### 環境 

・PowerVC 2.1.1 ( RHEL8.6 ppc64le)
　　Ansible  2.9.27
　　　Python 3.9.7

　=> Ansible実行 は PowerVC サーバーでローカルで実行しています。

・デプロイ対象筐体：IBM PowerSystems : S1014
・デプロイVM：AIX 7.3TL0SP1

---

#### 実行コード

```deploytest.yml
---
- name: PowerVC Deploy 
  hosts: localhost
  gather_facts : no

  tasks:
   - name: Get auth token
     uri:
       url: "https://<PowerVC_IP>/powervc/openstack/identity/v3/auth/tokens"
       method: POST
       headers:
         Accept: application/json
       body: "{{ lookup('file', 'body_auth_token.json') }}"  #<= body 部分は外部からファイルを読み込み
       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: Send Request for Server Deployment
     uri:
       url: 'https://<PowerVC_IP>/powervc/openstack/compute/v2.1/<tenant_ID>/servers'
       method: POST
       headers:
         X-Auth-Token: "{{ OS_TOKEN }}"
         Accept: application/json
       body_format: json
       body: "{{ lookup('file', 'body_deploy_vm.json') }}"  #<= body 部分は外部からファイルを読み込み
       return_content: yes
       status_code: 202
       validate_certs: no
       timeout: 300
     register: deploy_vm

   - name: "A little Pause while Deployment 300 seconds"
     pause:
       seconds: 300

   - name: Get Status Info from the Request (polling 10 times every 20 seconds)
     uri:
       url: "{{ deploy_vm.location }}"
       method: GET
       headers:
         X-Auth-Token: "{{ OS_TOKEN }}"
         Accept: application/json
       return_content: yes
       validate_certs: no
     register: result
     until: result.json.server.status == "ACTIVE"
     retries: 10
     delay: 20

 ```

---

外部呼び出しファイル例

・body_auth_token.json


```body_auth_token.json
{
    "auth":{
       "scope":{
          "project":{
             "name":"ibm-default",
             "domain":{
                "name":"Default"
             }
          }
       },
       "identity":{
          "methods":[
             "password"
          ],
          "password":{
             "user":{
                "domain":{
                   "name":"Default"
                },
                "name":"root",
                "password":"<パスワード>"
             }
          }
       }
    }
}
```


・body_deploy_vm.json

=> flavor の extra specs も盛り込めています。


```body_deploy_vm.json
{
   "server":{
      "name":"<仮想マシン名>",
      "max_count":1,
      "imageRef":"<イメージID>",
      "availability_zone":"Default Group",
      "block_device_mapping_v2":[{
                                  "boot_index": "0",
                                  "uuid": "<ストレージ・テンプレートID>",
                                  "source_type": "image",
                                  "destination_type": "volume"
      }],
      "flavor":{         #<=必要に応じて値を修正
         "ram": "4096",　　　　　　　　　
         "vcpus": "1",　　　　　　　　　　
         "disk": "25",　　　　　　　　　　
         "extra_specs":{
            "powervm:max_proc_units":"2",　　　
            "powervm:shared_weight":"128",　　 　
            "powervm:min_mem":"2048",　　　　　
            "powervm:max_mem":"4096", 　　　 　
            "powervm:uncapped":"true",
            "powervm:proc_units":"0.2",
            "powervm:dedicated_proc":"false",
            "powervm:max_vcpu":"2",
            "powervm:availability_priority":"127",
            "powervm:min_proc_units":"0.1",
            "powervm:min_vcpu":"1",
            "powervm:storage_connectivity_group":"<ストレージ接続グループID>"
         }
      },
      "config_drive": true,
      "networks":[
         {
            "uuid": "<ネットワークID>",
            "fixed_ip": "<IPアドレス①>"
         },
         {
            "uuid": "<ネットワークID>",
            "fixed_ip": "<IPアドレス②>"
         }
      ],
      "key_name": "<PowerVCに登録したsshkey名>"
   }
}
```


---

#### Ansible でのデプロイ実行


```
# ansible-playbook -i powervc deploytest.yml

PLAY [PowerVC Deploy] *******************************************************************************************************

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

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

TASK [Send Request for Server Deployment] ******************************************************************************
ok: [localhost]

TASK [A little Pause while Deployment 300 seconds] *********************************************************************
Pausing for 300 seconds
(ctrl+C then 'C' = continue early, ctrl+C then 'A' = abort)


ok: [localhost]

TASK [Get Status Info from the Request (polling 10 times every 20 seconds)] ********************************************
ok: [localhost]

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

```

無事完了しました。


PowerVC の GUI上でも対象のサーバーが作成されていることが確認できました。

![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517421/ebcb3ca2-bf71-4bd0-fa00-0cbc1744a8d3.png)




---

#### おわりに

Ansible で実行する場合は、Terraform での tfstate ファイルなどで実施している構成を保持はないため、作成したものをそのまま削除するなどは別途開発が必要になると考えます。

ただ仮想マシンを作るだけで良いという割り切りのケースであれば使用できるかと思います。

Ansible uri モジュールでの実行により、[以前の記事](https://qiita.com/c_u/items/08957da470ad6c933ce8) で実行していた際の前提となる ansible-galaxy openstack.cloud collection モジュールが不要になるのがメリットと思います。


---

#### ご参考

Terraform を使用してPowerVCサーバーのローカルからデプロイする場合は下記をご参考ください。

https://qiita.com/c_u/items/27d034a149bf564dbcb1



以上です。