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
- cloudinitが前提なので Proxmox VE 5.2でCloud-Initが使えるようになったので使う話 は使えるようになってるものとします
- クローン元になるイメージは登録済みとします
- 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>/
にアクセスしてログインすることができるはずです。
変更していなければ ~/.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個あればよいです。
Projects の追加
Playbookを含むリポジトリを指定します。設定後、Source Control Updateジョブが走ってソースコードが取得されます。
事前にサンプルとして作った https://github.com/ainoniwa/ansible-pve-workflow を指定します。
この記事を書いた時点でのタグは v1.0
を付与してあるので、もしmainブランチが進んでいるようなら Source Control Branch/Tag/Commit
には v1.0
と入れてください。
Hint
今回はGithubの公開リポジトリを使用するため認証情報は不要です。
プライベートリポジトリや、認証付きのGitlabを使用する場合は、別途Credentialsの設定を追加して、それを指定します。
Inventories の追加
uriモジュールだけを使い他のマシンにログインしないようなケースでは本来不要なのですが、ジョブ作成の際に必須入力となっているので localhost
という名前の登録を追加します。
Warningが無い方が気分がいいので、Host一覧にも localhost
を追加しておきます。
Credential Types の追加
今回はProxmox VEのAPIを叩くので認証情報が必要ですが、これをユーザーに意識させたくはありません。
そこで、以下の3つのパラメータをあらかじめAnsible AWXに記憶させることが出来るよう、Proxmox VE用の認証タイプを追加します。
- PVE_API_ENDPOINT
- PVE_API_USERNAME
- PVE_API_PASSWORD
詳しい入力様式は https://docs.ansible.com/ansible-tower/latest/html/userguide/credential_types.html#create-a-new-credential-type を参照してください。
今回の Input configuration
と Injector 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は出てきません
Job templates の追加
ここからジョブの追加です。
ここでは一例として pve_qemu_start.yaml
という「VMの起動」にあたるPlaybookをジョブとして登録します。
Add job template
を選択します。
今まで作成してきたパラメータを入れます。
Hint
Credentials には、事前に作成した Proxmox VE API
というCategoryが追加されているので、それを選択します。
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に追加します。
ユーザーに入力された値を変数名 vmid
に格納するように設定します。今回、ユーザーが指定可能なVM ID範囲は 8000~8999
にしました。
忘れずにSurveyをONにします。
これで、Ansible AWXでジョブを起動するときに入力プロンプトが出るようになります。
Proxmox VEで適当にVMを作って、起動できるか確認してみましょう。
問題なければ、以下のようにPlaybookが走り切ってVMが起動するはずです。
Detailsから確認できるVariablesも、管理者(AWX操作者)が設定した node
とユーザー(と言ってもAdminのまま操作していますけど)が指定した vmid
がそれぞれ入っています。
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の使用開始
を対象に設定してみましょう、
手順をおさらいすると、以下の通りです。
- VMのクローン
- VMの設定変更(失敗したら削除)
- VMの起動(失敗したら削除)
まず、Workflow templateを作ります。
作成するとVisualizerが起動するので、続行します。
一番最初に実行されるJobの選択画面になります。
VMのクローンを実行するJob templateを選択してSaveすると、ジョブが設置されます。
あとは、後続のジョブを +
ボタンで追加していきます。
今度から、1つ前のジョブの結果に応じた選択が可能になるので、作成したいワークフローに合わせてジョブを繋いでいきます。
大体下図のようになるので、これでSaveします。
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
を作成します。
Workflow templates のアクセス権設定
作成した user001
のRolesに移動して、各ワークフローの Execute
実行権限を与えます。
実行例
user001
でログインして、動きを見てみます。
VMの使用開始となるWorkflowを起動します。
パラメータを適当に埋めて...
実行します。
走り切りました。
Proxmox VE側のコンソールで、起動してきたことが確認できました。
権限を与えていないので、当然 user001
からはProxmox VEのAPI認証情報は確認できません。
これで、Proxmox VEでVMを使うだけのユーザーのために、Ansible AWXを介してVMを提供するワークフローが提供できそうです。
深刻な課題
ここまで読んで「ちょっと待って?ユーザーが適当にVMIDを入れたら他のユーザーのVMを落としたり消したりも簡単に出来るよね???」と思いますよね。
Ansible AWXはワークフローとして使うことは出来ても、それをベースにしたステート管理は出来ないので、他のユーザーに提供するためには適切なステートと在庫(Ansible文脈とは異なる意味でのInventory)管理をしなければならないことに気付きます。
Ansible AWXのAPIを叩けるステート管理用のサービスを作らないと、管理者が手を出さなくてもユーザーにVMを提供出来るようなサービスにはならなさそうです。
今後に向けてかなり深刻な課題になってしまいました。
おしまい
手順と画像が増えすぎて、とってもダルい記事になってしまいました。反省。
出来れば起動してきたVMにZabbix Agentを入れたりするDynamic Inventoryの例まで書こうと思ってたんですが、これ書くだけでも力尽きてる感があるので、続きを書くかどうかはちょっと分かんないです。
最後に書いた深刻な課題に対しては、上手く説明可能な解答を持っていないので、それを求めて彷徨うことになりそうです。