Proxmox VE基盤でAnsible AWXを使ってVMを提供する

Posted on 2021/02/21(Sun) 18:00 in technical

Proxmox VE基盤でAnsible AWXを使ってVMを提供する

概要

開発用のVMを提供したいんだけど、直接Proxmox VEを操作してもらうのは手間だし、誰が何を使っているのか全然分からなくなります。
そこで、Proxmox VEでVMを使うだけのユーザーのために、Ansible AWXを介してVMを提供するワークフローを作ってみます。
今回の手順を上から実行して動作確認できる人は、本当に極々限られているので、基本的には読み物だと思ってくださいませ。

Ansible AWXで以下のPlaybookを作ります。

  • VMのクローン
  • VMの設定変更
  • VMの起動
  • VMの停止
  • VMの削除

これをAnsible AWXのワークフローとして設定します。
作成するワークフローは以下の通りです。

Workflow Task
VMの使用開始 1. VMのクローン
2. VMの設定変更(失敗したら削除)
3. VMの起動(失敗したら削除)
VMの設定変更 1. VMの停止
2. VMの設定変更
3. VMの起動
VMの起動 1. VMの起動
VMの停止 1. VMの停止
VMの使用終了 1. VMの停止
2. VMの削除

環境説明

以下、登場人物です。

  • Proxmox VE 6.x cluster
  • Ansible AWX
    • 今回適当にインストールします
    • インストール先のIPは 192.168.122.232 です(この文書内で説明用に使います)

環境構築

Ansible AWXを入れます。既に構築済みの人はスキップしてください。

  • Ubuntu 20.04 LTS cloud image
  • Ansible AWX 17.0.1

Ubuntu 20.04の初期設定

$ sudo apt update
$ sudo apt upgrade -y
$ sudo apt install -y git docker docker-compose python3-venv
$ sudo systemctl enable docker
$ sudo systemctl start docker
$ sudo gpasswd -a $USER docker
$ exit

Ansible AWX(v17.0.1)のインストール

$ python3 -m venv ~/.virtualenvs/awx
$ source ~/.virtualenvs/awx/bin/activate
(awx)$ pip install ansible==2.9.16 docker docker-compose
(awx)$ git clone https://github.com/ansible/awx.git
(awx)$ cd awx
(awx)$ git switch -c 17.0.1 refs/tags/17.0.1
(awx)$ cd installer
(awx)$ # ----
(awx)$ # venv環境の場合(aptでansibleを入れた場合は不要)
(awx)$ # ----
(awx)$ sed -i -e "s|/usr/bin/env python3|$(which python)|" inventory 
(awx)$ # ----
(awx)$ # adminパスワードの指定
(awx)$ # ----
(awx)$ sed -i -e "s|# admin_password=password|admin_password=password|" inventory
(awx)$ # ----
(awx)$ # デモ用データが不要な場合修正する
(awx)$ # ----
(awx)$ sed -i -e "s|create_preload_data=True|create_preload_data=False|" inventory
(awx)$ export awx_version="17.0.1"
(awx)$ ansible-playbook -i inventory install.yml

Warning

デモ用データを入れる場合 ansible-playbook 実行時に [local_docker : Create Preload data] で引っかかるケースがあります: https://github.com/ansible/awx/issues/8863
数分待って再実行すると上手くいくので、失敗した場合は ansible-playbook を再実行します。

無事にインストールできていれば http://<ansible-awx-ip-address>/ にアクセスしてログインすることができるはずです。

001

変更していなければ ~/.awx/awxcompose/ に設定ファイルがあるので docker-compose.yml の内容などが気になる場合はそちらを見てみましょう。

uriモジュールでProxmox VEのAPIを叩くplaybook

uriモジュールでProxmox VEのAPIを叩くplaybookの作成は、済んでいるものとして https://github.com/ainoniwa/ansible-pve-workflow を使います。さぁ、次行こ次。

Ansible AWXの設定

それでは設定を入れていきます。
今回はデモ用データも入れていないので、かなりさっぱりしているはずです。

Organizations の追加

必須になることもあるので、とりあえず1個あればよいです。

002

003

Projects の追加

Playbookを含むリポジトリを指定します。設定後、Source Control Updateジョブが走ってソースコードが取得されます。

006

事前にサンプルとして作った https://github.com/ainoniwa/ansible-pve-workflow を指定します。
この記事を書いた時点でのタグは v1.0 を付与してあるので、もしmainブランチが進んでいるようなら Source Control Branch/Tag/Commit には v1.0 と入れてください。

007

008

Hint

今回はGithubの公開リポジトリを使用するため認証情報は不要です。
プライベートリポジトリや、認証付きのGitlabを使用する場合は、別途Credentialsの設定を追加して、それを指定します。

Inventories の追加

uriモジュールだけを使い他のマシンにログインしないようなケースでは本来不要なのですが、ジョブ作成の際に必須入力となっているので localhost という名前の登録を追加します。

009

010

Warningが無い方が気分がいいので、Host一覧にも localhost を追加しておきます。

011

012

Credential Types の追加

今回はProxmox VEのAPIを叩くので認証情報が必要ですが、これをユーザーに意識させたくはありません。

そこで、以下の3つのパラメータをあらかじめAnsible AWXに記憶させることが出来るよう、Proxmox VE用の認証タイプを追加します。

  • PVE_API_ENDPOINT
  • PVE_API_USERNAME
  • PVE_API_PASSWORD

013

014

詳しい入力様式は https://docs.ansible.com/ansible-tower/latest/html/userguide/credential_types.html#create-a-new-credential-type を参照してください。

今回の Input configurationInjector configuration の設定値は以下の通りです。

Input configuration

---
fields:
  - type: string
    id: PVE_API_ENDPOINT
    label: API URL
  - type: string
    id: PVE_API_USERNAME
    label: API username
  - type: string
    id: PVE_API_PASSWORD
    label: API username
    secret: true
required:
  - PVE_API_ENDPOINT
  - PVE_API_USERNAME
  - PVE_API_PASSWORD

Injector configuration

---
envs:
  PVE_API_ENDPOINT: "{{ PVE_API_ENDPOINT }}"
  PVE_API_USERNAME: "{{ PVE_API_USERNAME }}"
  PVE_API_PASSWORD: "{{ PVE_API_PASSWORD }}"

Credentials の追加

先ほど作成したCredential Typeを使って、Proxmox VEの認証情報を追加します

Note

今回作成したPlaybookでは、環境変数を使ってAPIを実行する作りになっています。
環境変数を使っているのは、Dynamic inventoryが引数を取れないという制約に合わせて、Playbookも環境変数を使うように実装にしたためです。
Dynamic inventoryを使用しない場合は、extra_varsを使用することもできるので、条件に合わせて作成してください。
※なお、この記事の中ではDynamic inventoryは出てきません

015

016

Job templates の追加

ここからジョブの追加です。
ここでは一例として pve_qemu_start.yaml という「VMの起動」にあたるPlaybookをジョブとして登録します。

Add job template を選択します。

017

今まで作成してきたパラメータを入れます。

018

Hint

Credentials には、事前に作成した Proxmox VE API というCategoryが追加されているので、それを選択します。
019

Surveyの追加はWorkflow templateの設定をするまで保留

pve_qemu_start.yaml では、APIを実行するための認証情報以外に、以下の情報が必要になります。

  • node: 起動するProxmox VEマシンの名前
  • vmid: 起動対象VMのID

しかし、この後設定する予定のWorkflow templateでは、ジョブを設置するタイミングでSurveyが行われるため、Workflowの定義時に値を入れる必要が出てきてしまいます。
これだと「Workflow templateを呼び出すときのextra_varsを共通して使いたい」場合には適さないので、Surveyの設定はWorkflow templateを作って、そちらで行います。

一応、単体で設定した場合の例も載せておきます。(ただし使いません)

(おまけ)Surveyの設定例(Job template)

node を管理者が pve01 とあらかじめ指定しておき、vmid はユーザーが選択できるようにSurveyに追加します。

020

ユーザーに入力された値を変数名 vmid に格納するように設定します。今回、ユーザーが指定可能なVM ID範囲は 8000~8999 にしました。

021

忘れずにSurveyをONにします。

022

これで、Ansible AWXでジョブを起動するときに入力プロンプトが出るようになります。

023

024

Proxmox VEで適当にVMを作って、起動できるか確認してみましょう。
問題なければ、以下のようにPlaybookが走り切ってVMが起動するはずです。

025

Detailsから確認できるVariablesも、管理者(AWX操作者)が設定した node とユーザー(と言ってもAdminのまま操作していますけど)が指定した vmid がそれぞれ入っています。

026

Job templates の追加(AWX CLI経由)

1つ1つ設定していくのは手間なので、一例を挙げたあとはスクリプトで流し込みます。

$ pip install awxkit==17.0.1
$ awx --conf.host http://192.168.122.232 --conf.username admin --conf.password password login
{
     "token": "lB25nRgh9PSu6vSLgoE0sDL40K56lI"
}
$ export AWX_TOKEN=lB25nRgh9PSu6vSLgoE0sDL40K56lI
$ awx --conf.host http://192.168.122.232 --conf.token ${AWX_TOKEN} import < job_templates/pve_qemu_clone.json
$ awx --conf.host http://192.168.122.232 --conf.token ${AWX_TOKEN} import < job_templates/pve_qemu_config.json
$ awx --conf.host http://192.168.122.232 --conf.token ${AWX_TOKEN} import < job_templates/pve_qemu_start.json
$ awx --conf.host http://192.168.122.232 --conf.token ${AWX_TOKEN} import < job_templates/pve_qemu_stop.json
$ awx --conf.host http://192.168.122.232 --conf.token ${AWX_TOKEN} import < job_templates/pve_qemu_delete.json

Warning

Job template以外の設定(例えばOrganizationsとか)は ainoniwa.net みたいなデータが入っていたりするので、その辺りは事前に置換してimportしてください。

Workflow templates の追加

基本はJob templatesと同様です。
特にStart, Stopのような1つのPlaybookで完結するWorkflow templateは、特に作らなくても良いんじゃないかというレベルです。

複数のPlaybookを含む VMの使用開始 を対象に設定してみましょう、
手順をおさらいすると、以下の通りです。

  1. VMのクローン
  2. VMの設定変更(失敗したら削除)
  3. VMの起動(失敗したら削除)

まず、Workflow templateを作ります。

027

028

作成するとVisualizerが起動するので、続行します。

029

一番最初に実行されるJobの選択画面になります。

030

VMのクローンを実行するJob templateを選択してSaveすると、ジョブが設置されます。

031

あとは、後続のジョブを + ボタンで追加していきます。
今度から、1つ前のジョブの結果に応じた選択が可能になるので、作成したいワークフローに合わせてジョブを繋いでいきます。

032

大体下図のようになるので、これでSaveします。

033

Note

失敗時にVMを削除するようにしていますが、これはWorkflowとしては「成功」扱いになってしまうようです。
実際にはVMは作成できていないのですがWorkflowとしては成功してしまうため、必ず失敗するJobを最後に置いたり、そもそも失敗した場合にVMの削除をしないようにするなどして、ワークフローの結果制御をすると良いと思います。

Workflow templates の追加(AWX CLI経由)

相変わらず1つ1つ設定していくのは手間なので、一例を挙げたあとはスクリプトで流し込みます。

$ awx --conf.host http://192.168.122.232 --conf.token ${AWX_TOKEN} import < wf_templates/vm_service_start.json
$ awx --conf.host http://192.168.122.232 --conf.token ${AWX_TOKEN} import < wf_templates/vm_service_config_vm.json
$ awx --conf.host http://192.168.122.232 --conf.token ${AWX_TOKEN} import < wf_templates/vm_service_start_vm.json
$ awx --conf.host http://192.168.122.232 --conf.token ${AWX_TOKEN} import < wf_templates/vm_service_stop_vm.json
$ awx --conf.host http://192.168.122.232 --conf.token ${AWX_TOKEN} import < wf_templates/vm_service_terminate.json

これには既にSurveyが設定済みなので、説明は省略します。(設定方法はJob templateと同じ)

Note

Surveyにはいくつか制約があるので、以下の点には注意が必要です。

  • TypeをIntegerにすると、入力を必須にしなくても「空白は数値ではない」というエラーが出るため、実質必須になる
  • Booleanが無い

動作確認

これにて、ワークフローが完備できたので、一般ユーザーに実行してもらいます。

一般ユーザーの作成

例として user001 を作成します。

034

035

Workflow templates のアクセス権設定

作成した user001 のRolesに移動して、各ワークフローの Execute 実行権限を与えます。

036

037

038

039

実行例

user001 でログインして、動きを見てみます。

VMの使用開始となるWorkflowを起動します。

040

パラメータを適当に埋めて...

041

実行します。

042

走り切りました。

043

Proxmox VE側のコンソールで、起動してきたことが確認できました。

044

権限を与えていないので、当然 user001 からはProxmox VEのAPI認証情報は確認できません。

045

これで、Proxmox VEでVMを使うだけのユーザーのために、Ansible AWXを介してVMを提供するワークフローが提供できそうです。

深刻な課題

ここまで読んで「ちょっと待って?ユーザーが適当にVMIDを入れたら他のユーザーのVMを落としたり消したりも簡単に出来るよね???」と思いますよね。

Ansible AWXはワークフローとして使うことは出来ても、それをベースにしたステート管理は出来ないので、他のユーザーに提供するためには適切なステートと在庫(Ansible文脈とは異なる意味でのInventory)管理をしなければならないことに気付きます。

Ansible AWXのAPIを叩けるステート管理用のサービスを作らないと、管理者が手を出さなくてもユーザーにVMを提供出来るようなサービスにはならなさそうです。

今後に向けてかなり深刻な課題になってしまいました。

おしまい

手順と画像が増えすぎて、とってもダルい記事になってしまいました。反省。

出来れば起動してきたVMにZabbix Agentを入れたりするDynamic Inventoryの例まで書こうと思ってたんですが、これ書くだけでも力尽きてる感があるので、続きを書くかどうかはちょっと分かんないです。

最後に書いた深刻な課題に対しては、上手く説明可能な解答を持っていないので、それを求めて彷徨うことになりそうです。