この記事はConoHa Advent Calendar 2022カレンダーの24日目の記事です。
17日の記事でAPI概論をされていたので、そこに乗っかって各論として実際にVPSサーバーをAPI経由で作成してみようと思います。
VMの作成に必要なトークンID、対象 image の UUID、VMプラン(flavor) の UUID、セキュリティグループ名の取得1から、
取得した情報を使用してVMの作成を行うまでを順に見ていきます。
トークンIDを取得
コントロールパネルからAPIユーザーの追加を行います。
トークン発行APIへ向けてリクエストを行います。
curl https://identity.tyo1.conoha.io/v2.0/tokens \
--data '{
"auth": {
"passwordCredentials": {
"username": "【API情報/APIユーザー/ユーザー名】",
"password": "【API情報/APIユーザー/パスワード】"
},
"tenantId": "【API情報/テナント情報/テナントID】"
}
}' \
--request POST \
| jq '.access.token | {expires, id}'
{
"expires": "2022-12-20T04:26:48Z",
"id": "【トークンID】"
}
access.token.id
の値を使用します。
取得したアクセストークンは access.token.expires
の日時(UTC)まで有効のようです。
対象imageのUUIDを取得
イメージ一覧取得APIへ向けてリクエストを行います。
curl https://image-service.tyo1.conoha.io/v2/images \
--request GET \
--header 'Accept: application/json' \
--header 'X-Auth-Token: 【トークンID】' \
| jq '.images[] | select(.name | contains("centos-stream")) | [.name, .id] | @csv' \
--raw-output
"vmi-kusanagimanager9-0.5.1-centos-stream8-amd64-100gb","3259adb3-8df6-4687-978b-c25f2f6bf5c4"
"vmi-kusanagimanager9-0.5.1-centos-stream8-amd64","4de6e408-9b07-4e99-b1d1-10b29a5cbdd3"
"vmi-centos-stream9-amd64-100gb","642d1a41-5a32-490c-8fac-a4229363dd76"
"vmi-centos-stream9-amd64","d16ba42f-a1ce-4775-bace-50f159b672d9"
"vmi-centos-stream9-amd64-30gb","5005e687-d644-471a-8f34-8c6594fba487"
"vmi-centos-stream9-amd64-20gb","ce13c434-fa6f-43b0-a7e5-7ad8f600c370"
"vmi-centos-stream-8-latest-amd64-100gb","c67cfd69-b096-4903-ad8a-fe02fe7aa896"
"vmi-centos-stream-8-latest-amd64","d8af04f6-6bce-40bf-8dc5-867d0a52cdc3"
"vmi-centos-stream-8-latest-amd64-30gb","39376bda-80b2-4b7c-b6eb-3b44cbac5faa"
"vmi-centos-stream-8-latest-amd64-20gb","33b8f21a-1a2e-4609-9178-99809606bc6b"
vmi-centos-stream9-amd64
を使いたいけど -30gb
とかサフィックスがついてるやつは何、、、ストレージの容量でしょうか?
とりあえず一番数字の小さいかつ後で検証できそうな vmi-centos-stream9-amd64-20gb
( ce13c434-fa6f-43b0-a7e5-7ad8f600c370
) を使用します。
VMプラン(flavor)のUUIDを取得
VMプラン一覧取得APIへ向けてリクエストを行います。
curl https://compute.tyo1.conoha.io/v2/【API情報/テナント情報/テナントID】/flavors \
--header 'Accept: application/json' \
--header 'X-Auth-Token: 【トークンID】' \
--request GET \
| jq '.flavors[]| [.name, .id] | @csv' \
--raw-output
"g-2gb","294639c7-72ba-43a5-8ff2-513c8995b869"
"g-16gb","3aa001cd-95b6-46c9-a91e-e62d6f7f06a3"
"g-c4m4d100","5d3b29d1-511e-4f06-bb69-42f79b00e514"
"g-c12m32d100","5f58bcf4-cf4b-46ea-886c-de04b632c7f2"
"g-4gb","62e8fb4b-6a26-46cd-be13-e5bbf5614d15"
"g-c8m16d100","7ddaba07-b000-45f7-99ce-540fbbf8b965"
"g-1gb","7eea7469-0d85-4f82-8050-6ae742394681"
"g-c1m512d30","93b572a0-f1c7-4753-8384-47d9dcc826ee"
"g-8gb","965affd4-d9e8-4ffb-b9a9-624d63e2d83f"
"g-c6m8d100","a13e5367-b191-4d31-9df5-d196862b9a94"
"g-32gb","a20905c6-3733-46c4-81cc-458c7dca1bae"
"g-c2m1d100","ab7b9b6d-108c-4487-90a4-2da604ad6a92"
"g-64gb","c2a97b05-1b4b-4038-bbcb-343201659279"
"g-c24m64d100","c36c5701-65e1-492c-b757-af843fe25599"
"g-512mb","d92b02ce-9a4f-4544-8d7f-ae8380bc08e7"
"g-c3m2d100","ead5edd0-27af-4799-aecf-4e5633b46adc"
んん、、、?
ドキュメントの例だと 64gb-flavor
みたいな名前がついてるはずなんですが、、、
コントロールパネルでいうところのこの辺でしょうか?
APIからだとメモリの大きさとストレージの大きさを別で指定できるってことなんでしょうか、、、?
とりあえず1GBにしたかったので g-1gb
( 7eea7469-0d85-4f82-8050-6ae742394681
) を使用します。
セキュリティグループ名を取得
セキュリティグループ一覧取得APIへ向けてリクエストを行います。
curl https://networking.tyo1.conoha.io/v2.0/security-groups \
--header 'Accept: application/json' \
--header 'X-Auth-Token: 6e9ccdb87eb64ead84b68795536a61ac' \
--request GET \
| jq '.security_groups[] | {n: .name} + (.security_group_rules[] | {d: .direction, pmn: .port_range_min, pmx: .port_range_max}) | [.n, .d, .pmn, .pmx] | @csv' \
--raw-output
"gncs-ipv4-all","ingress",,
"gncs-ipv4-all","egress",,
"gncs-ipv4-all","egress",,
"gncs-ipv6-mysql","egress",,
"gncs-ipv6-mysql","ingress",3306,3306
"gncs-ipv6-mysql","egress",,
"gncs-ipv4-mysql","egress",,
"gncs-ipv4-mysql","egress",,
"gncs-ipv4-mysql","ingress",3306,3306
"gncs-ipv6-ssh","ingress",22,22
"gncs-ipv6-ssh","egress",,
"gncs-ipv6-ssh","egress",,
"gncs-ipv6-web","egress",,
"gncs-ipv6-web","egress",,
"gncs-ipv6-web","ingress",21,21
"gncs-ipv6-web","ingress",443,443
"gncs-ipv6-web","ingress",80,80
"gncs-ipv6-web","ingress",20,20
"gncs-ipv4-ssh","ingress",22,22
"gncs-ipv4-ssh","egress",,
"gncs-ipv4-ssh","egress",,
"gncs-ipv6-all","egress",,
"gncs-ipv6-all","egress",,
"gncs-ipv6-all","ingress",,
"gncs-ipv4-web","egress",,
"gncs-ipv4-web","ingress",80,80
"gncs-ipv4-web","ingress",21,21
"gncs-ipv4-web","ingress",443,443
"gncs-ipv4-web","egress",,
"gncs-ipv4-web","ingress",20,20
"default","egress",,
"default","ingress",,
"default","ingress",,
"default","egress",,
今回はHTTPアクセスとSSHアクセスだけ受け入れてくれれば良いので、
gncs-ipv4-web
、 gncs-ipv4-ssh
を使用します。
FTPで使用する20番や21番が不要な場合、 カスタムしたセキュリティグループを作成する こともできるようです。
VM追加
必要な情報が揃ったので、
VM追加APIへ向けてリクエストを行います。
curl https://compute.tyo1.conoha.io/v2/【API情報/テナント情報/テナントID】/servers \
--data '{
"imageRef": "ce13c434-fa6f-43b0-a7e5-7ad8f600c370",
"flavorRef": "7eea7469-0d85-4f82-8050-6ae742394681",
"adminPass": "【ルートユーザー用パスワード】",
"security_groups": [
{ "name": "gncs-ipv4-web" },
{ "name": "gncs-ipv4-ssh" }
],
"metadata": {
"instance_name_tag": "20221219"
}
}' \
--header 'Accept: application/json' \
--header 'X-Auth-Token: 【トークンID】' \
--request POST
500 Internal Server Error
は?
どうもドキュメントの例を見ると、リクエストデータは server
キーの下にまとめる必要があるようです。3
curl https://compute.tyo1.conoha.io/v2/【API情報/テナント情報/テナントID】/servers \
--data '{
"server": {
"imageRef": "ce13c434-fa6f-43b0-a7e5-7ad8f600c370",
"flavorRef": "7eea7469-0d85-4f82-8050-6ae742394681",
"adminPass": "【ルートユーザー用パスワード】",
"security_groups": [
{ "name": "gncs-ipv4-web" },
{ "name": "gncs-ipv4-ssh" }
],
"metadata": {
"instance_name_tag": "20221219"
}
}
}' \
--header 'Accept: application/json' \
--header 'X-Auth-Token: 【トークンID】' \
--request POST
{"badRequest":{"message":"Invalid characters combination found in password. Admin password must include lower, upper case, numeric, symbolic characters.","code":400}}
これについてはドキュメントに記載がありますね。
vmのrootパスワードについて
vmのrootパスワードは“adminPass”パラメータを利用します。
adminPassはOptionalですが、指定するimageによって動作が変わります。Publicイメージを指定した場合、パスワードが入力されなかったらランダムなパスワードが設定されます。
Privateイメージ(自身のVPSの保存イメージ)を指定した場合、パスワードが入力されなかったら元イメージのパスワードが設定されます。(※レスポンスのadminPassには““と表示されます)
文字種:半角英大文字と、半角英小文字と、半角数字または記号の組み合わせ以外はエラー。文字数:9文字以上~70文字以内
使用可能の記号 ⇒ ! # $ % & ? ” ' = + - _ { } [ ] ^ ~ : ; ( ) . , / | \ * @
パスワード部分を修正して再度リクエストを投げると、
{
"server": {
"security_groups": [
{
"name": "gncs-ipv4-web"
},
{
"name": "gncs-ipv4-ssh"
}
],
"OS-DCF:diskConfig": "MANUAL",
"id": "【なんらかのUUID】",
"links": [
{
"href": "https://compute.tyo1.conoha.io/v2/【API情報/テナント情報/テナントID】/servers/【なんらかのUUID】",
"rel": "self"
},
{
"href": "https://compute.tyo1.conoha.io/【API情報/テナント情報/テナントID】/servers/【なんらかのUUID】",
"rel": "bookmark"
}
],
"adminPass": "【ルートユーザー用パスワード】"
}
}
無事作成されたようなレスポンスが返りました。
作成されたVMを確認
コントロールパネルから作成されたVMを確認してみると、下のスクリーンショットのような状態でした。
んん?イメージは vmi-centos-stream9-amd64-20gb
を使用したはずですが、 SSD 50GB
となっています。
イメージ名のサフィックス ( -20gb
) はストレージの大きさではないのでしょうか、、、?
メモリは期待通り 1GB
になっていて、ネームタグも指定通り、接続許可ポートも Web
、 SSH
のみになっていてもんだいなさそうです。
作成したVMを削除して、イメージ名のサフィックスを vmi-centos-stream9-amd64-100gb
( 642d1a41-5a32-490c-8fac-a4229363dd76
) へ変更してみました。
curl https://compute.tyo1.conoha.io/v2/【API情報/テナント情報/テナントID】/servers \
--data '{
"server": {
"imageRef": "642d1a41-5a32-490c-8fac-a4229363dd76",
...
}
}' \
...
{"badRequest":{"message":"Flavor's disk is too small for requested image.","code":400}}
んんん?どういうことでしょう、、、???
Flavor (vmi-centos-stream9-amd64-100gb
) のディスクが要求されたイメージ ( g-1gb
) に対して小さすぎます、、、?
さっき成功した vmi-centos-stream9-amd64-20gb
の方が小さいのでは、、、?
vmi-centos-stream9-amd64-30gb
を試す
vmi-centos-stream9-amd64-30gb
はどうでしょう?
{
"server": {
...
}
}
リクエストは成功しましたが、
コントロールパネルで確認すると変わらず SSD 50GB
となっています。
vmi-centos-stream9-amd64
を試す
最後に vmi-centos-stream9-amd64
を試してみます。
リクエストは成功、 しかしまたしても SSD 50GB
が設定されていました。。
flavor を変えてみる
あれ、もしかして、Flavorのところで出てきた g-c2m1d100
って、
- cpu: 2 core
- memory: 1 GB
- disk: 100 GB
ということでは、、、?
ということは、 flavorRef
の部分を g-c2m1d100
( ab7b9b6d-108c-4487-90a4-2da604ad6a92
) に変更すると、
SSD 100GB
になりました。
結局イメージ名についてる ( -20gb
) これ何、、、?
まとめ
初見でドキュメントをパッと見た感じではスムーズに作成できるかと思ったのですが、
意外と手間がかかったように思います。
また、謎が残ったままになってしまいました。
よく考えてみると image の指定でディスク容量まで決められるのはちょっと違うよね、って感じではありますが。
あのサフィックスは何だったんでしょうか。
Flavor's disk is too small for requested image
のエラーはなぜ発生したのでしょうか。
最終的に flavor を g-c2m1d100
に指定することで期待したものが出来ましたが、
ドキュメントに記載がないので「ほんまか、、、?」という疑いが晴れず、この状態で課金され続けるのは怖いです。
とはいえ課金は1時間単位なので、
色々試してみてもそんなにコストはかからない気がします4。
API経由だとコントロールパネル経由より詳細な設定が出来るようですので、
必要に応じて使っていければより便利に、効果的に運用ができそうです。
が、コントロールパネルからできる操作はコントロールパネルからやってしまう方が現状個人的には安心できそうです56。
ConoHa APIのSDKがあればより便利になる気がするのでこのはちゃん頑張ってください!!!!!!!!!7
-
imageやらflavorやらのリストをドキュメントのどこかに一覧作っていただければ基本API叩く必要ないのでは、、、 ↩
-
server.imageRef
みたいな書き方してほしいですね、、、 ↩ -
そういえばメモリ 1GB ストレージ SSD 50GB で出来ちゃったVMって料金どうなるんでしょう?そんなプランないですよね? ↩
-
本来はヒューマンエラーを避けるためにスクリプト書いてAPI経由のほうが安心なはずですが。ドキュメント、、、 ↩
-
まあでもドキュメントって更新されないものですよね。OpenAPIでドキュメント作成しつつ自動テストまでできるような感じがイケてるんでしょうか? ↩
-
あと卓上カレンダーください!!! ↩