これは Ansible Advent Calendar 2020 と vExperts Advent Calendar 2020 の記事になります。
Contents
AnsibleでVMwareを操作する
Ansible 2.10から Collections という新しい概念でモジュールやプラグインなどが個別で管理できるようになりました。
VMwareのモジュールもCollections化され個別で管理されるようになり、現在では次の2つに分かれています。
community.vmware
では、Ansible 2.9でバンドルされていたvSphere API(SOAP)経由で操作が実装されているモジュールが管理されています。
vmware.vmware_rest
は、vCenter Server6.5から実装されたREST API経由で操作が実装されているモジュールが管理されています。
vmware_restは2020/10/10に正式リリースされており、まだ出てきてホヤホヤです。
そこで、ここでは vmware_rest の使い方について紹介したいと思います。
vmware.vmware_rest
2020/12/11時点で使用できるモジュールは53個です。
vmware_restモジュール群は、APIのエンドポイント毎にモジュールが作成されています。
モジュールの生成は vmware_rest_code_generator で自動化されています。
操作系で用意されているのはデータセンターの作成・削除、リソースプール作成・削除、ESXiホストの追加・削除、仮想マシンの作成・削除・一部の設定変更のみです。
それ以外は情報を取得する *_info
モジュールになります。
そのため、現状vmware_restで出来る範囲は少ないのが実情です。
また、vCenterのREST APIでは、vSphere API(SOAP)よりも出来ることが少ないという点もありますが、今後徐々に増えていく事が期待されます。
今回のアドカレでは、仮想マシンのクローンをvmware_restを使って実装してみようと思います。
仮想マシンの新規作成については、モジュールの EXAMPLES に書いてあります。
仮想マシンのクローン自動化
ここでは、virtualenvを前提としています。
環境
項目 | バージョン | 備考 |
---|---|---|
VCSA | 7.0.0.10400 | |
Python | 3.6.8 | |
Ansible Base | 2.10.3 | |
vmware.vmware_rest | 1.0.1 | |
cloud.common | 1.1.0 | 依存関係でインストールされる |
cloud.common
は依存関係で必要になるCollectionです。
vmware_restはcloud.commonで実装されている AnsibleTurboModule を使用して処理の高速化を図っています。
ここでは、cloud.commonの詳細については省略します。
vmware_restインストール
それでは、vmware_restをGalaxy 1 経由からインストールしてみましょう。
ここでは、開発で使用するカレントディレクトリの collections
にインストールしてみます。
1 2 |
(venv) $ ansible-galaxy collection install vmware.vmware_rest -p collections |
インストールされているか確認してみましょう。
1 2 3 4 5 6 7 |
(venv) $ ansible-galaxy collection list -p collections/ (snip) Collection Version ------------------ ------- cloud.common 1.1.0 vmware.vmware_rest 1.0.1 |
vmware_restを動作させるために必要なライブラリ関連をインストールします。
ライブラリをインストールするには gcc
と python3-devel
がインストールされている必要があります。
1 2 |
(venv) $ pip install -r collections/ansible_collections/vmware/vmware_rest/requirements.txt |
Playbookの作成
今回は以下のPlaybookを作成しました。
test_vm1
を元にクローンで test_vm3
を作成し F0
フォルダに保存します。
注意点
VMの存在チェックをしない
まず、最初のタスクで新しく作ろうとしているVMがvCenterに存在していないか?確認しています。
何故そんなことをしているのか?という点を説明すると、vmware_restはAPIエンドポイントに対してリクエストを投げるだけなので、これから作成しようとしているVMの存在チェックはません。
そのため、VMが存在してもしてなくてもリクエストが飛びます。
もし、VM(test_vm3)が存在している状態でリクエストを実行するとモジュール実行結果でエラーは発生しませんが、vCenter上で既にVMが存在しているというエラーが発生します。
オブジェクトのパラメーターは基本MOIDを使う
community.vmwareでは人間が分かりやすいvCenterで表示されている 表示名
でVMなどのオブジェクトを指定できました。
これは、モジュール側で表示名を元にオブジェクトを特定(検索)する処理が実装されていたため可能でした。
vmware_restでは、モジュールが自動生成されているということもあり実装自体はシンプルです。
そのため、モジュールで扱うパラメーターの値もREST APIでサポートされているタイプを指定する必要があります。
それが MOID
になります。
MOID/MORef ID(Managed Object ID/Managed Object Reference ID)は各オブジェクトの内部識別子(ユニークID)になります。
例えば、以下はフォルダと仮想マシンのMOIDの例になります。
Object | MOID |
---|---|
Folder | group-v1159 |
VM | vm-1034 |
クローンを実行するタスクを例として見てみましょう。
name
以外のパラメーターはMOIDを指定しています。
MOIDは _info
モジュールを使って取得することができますし、vCenter Serverの https://vcsa host or ip/mob
から確認できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
(snip) - name: Start to clone a new VM vmware.vmware_rest.vcenter_vm: vcenter_hostname: "{{ vcenter_hostname }}" vcenter_username: "{{ vcenter_username }}" vcenter_password: "{{ vcenter_password }}" vcenter_validate_certs: false placement: folder: "{{ folder_info_result.value.0.folder }}" # MOIDを指定 name: "{{ new_vm_name }}" source: "{{ template_info_result.value.0.vm }}" # MOIDを指定 state: clone register: clone_vm_result changed_when: clone_vm_result.failed is sameas false (snip) |
タスク完了待ちはしない
vmware_restはAPIエンドポイントに対してリクエストを投げるだけなので、vCenterで実行されたタスクの結果待ちをしません。
投げたら終わりです。
そこで、実行したタスクの状態確認をするための処理を以下のように追加しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
(snip) - name: Get a vmware api session id for getting a status state uri: url: "https://{{ vcenter_hostname }}/rest/com/vmware/cis/session" user: "{{ vcenter_username }}" password: "{{ vcenter_password }}" validate_certs: false force_basic_auth: true method: POST headers: Accept: application/json register: get_vmware_api_session_id_result - name: Set vmware_api_session_id variable set_fact: vmware_api_session_id: "{{ get_vmware_api_session_id_result.json.value }}" - name: Wait until the status isn't RUNNING uri: url: "https://{{ vcenter_hostname }}/rest/cis/tasks/{{ clone_task_id }}" validate_certs: false method: GET headers: vmware-api-session-id: "{{ vmware_api_session_id }}" retries: 60 delay: 5 until: status_result.json.value.status != "RUNNING" register: status_result - name: Delete the vmware api session id uri: url: "https://{{ vcenter_hostname }}/rest/com/vmware/cis/session" validate_certs: false method: DELETE headers: vmware-api-session-id: "{{ vmware_api_session_id }}" register: delete_vmware_api_session_id_result - name: Occur a failing if the condition isn't match fail: msg: "{{ new_vm_name }} clone failed" when: status_result.json.value.status != "SUCCEEDED" |
uriモジュールでREST APIを実行するために必要なセッションIDを取得し、そのIDを使用してステータス状態を取得します。
実行中は RUNNING
になっているので、それ以外のステータスになるまで待ちます。
RUNNING以外になったら、ステータス確認用のセッションIDを破棄しています。
最後にクローン処理が SUCCEEDED
では無い場合にエラーを発生させる処理を追加しています。
Playbook実行
以下はPlaybook実行のデモになります。
Demo: Clone a new VM with vmware_rest from sky_joker on Vimeo.
クローンで新しいVMを作ることが出来ました 🙂
仮想マシンの電源をONにしたい場合は vcenter_vm_power を使う事で可能です。
最後に
vmware_restの使い方について簡単にですがクローンを例にして説明しました。
現状は、REST APIを直叩きみたいな作りになっているのでcommunity.vmwareのような感覚で使おうと思ったら注意が必要です。
まだ、出来たてホヤホヤなので今後どう改善されていくか期待しましょう 🙂
- 正式なサポートが必要な場合は Automation Hub からインストールしてください。 ↩