0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

WebARENA Indigo APIでVPSを作る(curl/Python+cloud-init)

Posted at

検証環境

  • macOS 13 / Ubuntu 24.04
  • curl 8+, jq 1.6+, Python 3.11+, OpenSSH 9+

やること / やらないこと

  • やる: APIでVPS作成 → cloud-initで初期設定 → IP取得 → SSH接続 → 削除まで
  • やらない: 料金最適化や本番の権限設計、監視/バックアップの詳細

APIを使ったVPSインスタンス作成の流れ



TL;DR(要約)

  • Indigo APIで インスタンス作成 → 初期状態は STOP
  • statusupdate APIで start に変更して起動。
  • インスタンス一覧から IPを取得 → SSH接続。
  • (任意)起動後に NoCloud方式でcloud-initを適用。
  • 料金(1GB Linux): 0.70円/時間(税込み)、月額上限449円(税込み)、最低利用料55円(税込み)。IP/ディスク/転送量の追加課金なし

対象読者

  • WebARENA Indigo をこれからAPIで触ってみたい人
  • 手動GUIではなく Infrastructure as Code 的にVPSを作成・破棄したい人
  • Qiita/社内Confluence/自社ブログ向けに記事を書きたい人

前提条件

  • NTTPC WebARENA Indigoサービスを契約済みであること
  • IndigoでSSH鍵を作成済みであること
  • macOS / Linux / WSL 環境
  • インストール済み:curl, jq, ssh, ssh-keygen
  • (任意)DNSのA/AAAAレコードを編集可能

注意: 本記事では
$INDIGO_API_BASE=https://api.customer.jp/webarenaIndigo/v1 を前提
としています。


この記事で作るもの

  • OS/インスタンスタイプ/リージョン/SSH鍵 一覧API を呼ぶ
  • createinstance でVM作成(初期状態 STOP)
  • statusupdate で起動
  • getinstancelist でIP確認 → SSH
  • (任意)SSH後に NoCloud seed でcloud-init適用

ステップ1:APIトークンの取得(ポータル)

IndigoのAPIを叩くには Bearerトークン が必要です。
まずはIndigoコントロールパネルでAPI鍵を発行します。

  1. WebARENA Indigoのコントロールパネルにログイン
  2. 左側メニュー → API鍵の管理、API鍵を選択し、API鍵の管理画面へ
  3. API鍵の管理画面で画面右上の[+API鍵の作成]ボタンを押して実行、表示されたAPI鍵API秘密鍵を安全な場所に控える(再表示できないので注意!)
  4. この鍵を使って以下のようにBearer トークンを取得する
curl -X POST \
  https://api.customer.jp/oauth/v1/accesstokens\
  -H 'Content-Type: application/json' \
  -d '{
    "grantType": "client_credentials",
    "clientId": "[API鍵]",
    "clientSecret": "[API秘密鍵]",
    "code": ""
}'
以下のようなレスポンスが表示される
{"accessToken": "[トークン]", "tokenType": "BearerToken", "expiresIn": "3599" , "scope": "" , "issuedAt": "*************"}

[API鍵],[API秘密鍵]はあなたの環境の値に置き換えてください。
ここで取得した[トークン]は有効期限が60分未満ですので注意が必要です


ステップ2:環境変数をセット

エンドポイントやトークンは環境変数で扱うと安全・便利です。

# Indigo APIのベースとなるエンドポイントを環境変数化する
export INDIGO_API_BASE="https://api.customer.jp/webarenaIndigo/v1"

# 認証トークン(Bearer)を環境変数に設定
export INDIGO_TOKEN="[取得したトークン]"

#SSH鍵一覧を取得する
# 200 OK が返れば認証成功。401 が返る場合はトークンを確認
curl -i -X GET "$INDIGO_API_BASE/vm/sshkey" \
  -H "Authorization: Bearer $INDIGO_TOKEN"

[取得したトークン]はあなたの環境の値に置き換えてください。

SSH鍵一覧取得に成功するとレスポンスに[SSH鍵のID]が表示されるので控えておく

以下のように変数を設定する

# VMインスタンス作成時に使うパラメータ
export INDIGO_REGION=1      # リージョン 東京
export INDIGO_PLAN=1        # VMプラン 1vCPU1GB20GB
export INDIGO_IMAGE=25      # OSイメージ Ubuntu 24.04
export INDIGO_SSH_KEY_ID="[SSH鍵のID]"   # 登録済みのSSH鍵から選択
export INDIGO_INSTANCE_NAME="api-demo-ubuntu2404-1C1G20G" # 任意の名前をつけよう

[SSH鍵のID]はあなたの環境の値に置き換えてください。
.env に保存して source .env で読み込むのもおすすめです。Git管理下に置く場合は トークンを含めない よう注意!


ステップ3:VMインスタンス(VPS)を作成(初期状態STOP)

Indigoの createinstance エンドポイントに必要な引数をJSONで渡します。

curl -X POST \
  "$INDIGO_API_BASE/vm/createinstance" \
  -H "Authorization: Bearer $INDIGO_TOKEN" \
  -H "Content-Type: application/json" \
  -d "{
  \"sshKeyId\": $INDIGO_SSH_KEY_ID,
  \"regionId\": $INDIGO_REGION_ID,
  \"osId\": $INDIGO_OS_ID,
  \"instancePlan\": $INDIGO_INSTANCE_PLAN,
  \"instanceName\": \"$INDIGO_INSTANCE_NAME\"
}"

レスポンスに含まれるVMのidを控えておきます。


ステップ4:作成済みVMの一覧を取得

curl -X GET \
  "$INDIGO_API_BASE/vm/getinstancelist" \
  -H "Authorization: Bearer $INDIGO_TOKEN" | jq

ここで新規作成したVMインスタンスのidと現在のステータス(STOPなど)を確認します。


ステップ5:ステータス変更(start)でVMインスタンスを起動

作成直後は STOP なので、statusupdate で start に変更します

curl -X POST \
  "$INDIGO_API_BASE/vm/instance/statusupdate" \
  -H "Authorization: Bearer $INDIGO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"instanceId":"[VMインスタンスのid]","status":"start"}'

[VMインスタンスのid]はあなたの環境の値に置き換えてください。


ステップ6:IP確認 → SSH接続 →(任意)cloud-init 適用

①IPアドレスを確認

一覧のレスポンスからPublic IPv4アドレスを取り出します。

#INDIGO_INSTANCE_NAMEを指定
export INDIGO_INSTANCE_NAME="api-demo-ubuntu2404-1C1G20G"

curl -s -X GET "$INDIGO_API_BASE/vm/getinstancelist" -H "Authorization: Bearer $INDIGO_TOKEN" \
 | jq -r --arg name "$INDIGO_INSTANCE_NAME" '
  .[]
  | select((.instance_name|tostring|gsub("\\s+$";"")|ascii_downcase)
           == ($name|gsub("\\s+$";"")|ascii_downcase))
  | select(.instancestatus=="Running")
  | (.ip // .ipaddress) // empty
'

VMインスタンス一覧が表示されるのでIPアドレスを確認する

②SSH接続を行う(ubuntu想定)

SSH接続を確認します

sudo ssh -i [SSH鍵] ubuntu@[IPアドレス]

[SSH鍵],[IPアドレス ]はあなたの環境の値に置き換えてください。

③(任意)NoCloud方式で cloud-init を後付け適用

IndigoのAPIで userdata を渡せないため、起動後に NoCloud でシードする方法です(Ubuntu想定)。
1)NoCloud をローカル seed に固定(CD-ROM を無視させる)※Indigo固有の対策

sudo tee /etc/cloud/cloud.cfg.d/90_nocloud_seed.cfg >/dev/null <<'EOF'
datasource_list: [ NoCloud ]
datasource:
  NoCloud:
    seedfrom: /var/lib/cloud/seed/nocloud-net/
EOF

2)まず、以下の cloud-init を使います(Ubuntu 24.04 最小構成+セキュリティ強化)
cloud-init.yaml

cloud-init.yaml
#cloud-config
package_update: true
package_upgrade: true
manage_etc_hosts: true
ssh_pwauth: false
disable_root: true
timezone: Asia/Tokyo

packages:
  - ufw
  - fail2ban
  - nginx
  - jq
  - git
  - unattended-upgrades

write_files:
  - path: /etc/fail2ban/jail.d/sshd.local
    owner: root:root
    permissions: '0644'
    content: |
      [sshd]
      enabled = true
      port    = ssh
      banaction = iptables-multiport
      bantime  = 10m
      findtime = 10m
      maxretry = 5
  - path: /etc/apt/apt.conf.d/51unattended-upgrades-local
    owner: root:root
    permissions: '0644'
    content: |
      Unattended-Upgrade::Automatic-Reboot "true";
      Unattended-Upgrade::Automatic-Reboot-Time "03:30";
  - path: /var/www/html/index.nginx-debian.html
    owner: www-data:www-data
    permissions: '0644'
    content: |
      <!doctype html>
      <html lang="ja"><head><meta charset="utf-8"><title>Indigo API Demo</title></head>
      <body><h1>It works 🎉</h1><p>Provisioned by cloud-init.</p></body>
      </html>

runcmd:
  - [ bash, -lc, 'ufw default deny incoming' ]
  - [ bash, -lc, 'ufw default allow outgoing' ]
  - [ bash, -lc, 'ufw allow 22/tcp' ]
  - [ bash, -lc, 'ufw allow 80/tcp' ]
  - [ bash, -lc, 'ufw allow 443/tcp' ]
  - [ bash, -lc, 'ufw --force enable' ]
  - [ systemctl, enable, --now, nginx ]
  - [ systemctl, enable, --now, fail2ban ]
  - [ systemctl, enable, --now, unattended-upgrades ]
  - [ bash, -lc, 'test -f /swapfile || (fallocate -l 1G /swapfile && chmod 600 /swapfile && mkswap /swapfile && echo "/swapfile none swap sw 0 0" | tee -a /etc/fstab && swapon -a)' ]

final_message: "Indigo server configured via cloud-init."

3)NoCloud seed の配置と実行

# seed を用意(instance-id は毎回ユニーク)
sudo mkdir -p /var/lib/cloud/seed/nocloud-net
sudo tee /var/lib/cloud/seed/nocloud-net/meta-data >/dev/null <<EOF
instance-id: iid-$(uuidgen)
local-hostname: $HOSTNAME
EOF

# 上の cloud-init.yaml を user-data として設置
sudo tee /var/lib/cloud/seed/nocloud-net/user-data > /dev/null <<'EOF'
#cloud-config
# (ここに cloud-init.yaml の中身を貼り付け)
EOF

# cloud-init を再実行
sudo cloud-init clean
sudo cloud-init init
sudo cloud-init modules --mode=config
sudo cloud-init modules --mode=final

ステップ7:クリーンアップ

①VMインスタンスの停止

VMインスタンスのステータスをstatusupdateでStopへ変更

curl -X POST \
  "$INDIGO_API_BASE/vm/instance/statusupdate" \
  -H "Authorization: Bearer $INDIGO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"instanceId":"[VMインスタンスのid]","status":"stop"}'

[VMインスタンスのid]はあなたの環境の値に置き換えてください。
VMインスタンスをstopしても課金が続きます。

②VMインスタンスの削除

VMインスタンスのステータスをstatusupdateでdestroyへ変更

curl -X POST \
  "$INDIGO_API_BASE/vm/instance/statusupdate" \
  -H "Authorization: Bearer $INDIGO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"instanceId":"[VMインスタンスのid]","status":"destroy"}'

[VMインスタンスのid]はあなたの環境の値に置き換えてください。
VMインスタンスを削除で課金が止まります。

ディストリにより cloud-init の導入が必要な場合は sudo apt-get update && sudo apt-get install -y cloud-init を先に実行してください。
ディスク・IPの課金体系に応じて 削除前のスナップショット を検討してください。


付録A:Bashワンショット(作成→待機→接続)

create_and_connect.sh(雛形)

create_and_connect.sh
#!/usr/bin/env bash
set -euo pipefail
: "${INDIGO_API_BASE:?}" "${INDIGO_TOKEN:?}" "${INDIGO_REGION_ID:?}" \
  "${INDIGO_OS_ID:?}" "${INDIGO_INSTANCE_PLAN:?}" "${INDIGO_SSH_KEY_ID:?}" "${INDIGO_INSTANCE_NAME:?}"

h=( -H "Authorization: Bearer $INDIGO_TOKEN" -H "Content-Type: application/json" )

# 1) createinstance (STOPで作成)
curl -s -X POST "${INDIGO_API_BASE}/vm/createinstance" "${h[@]}" \
  -d "{
  \"sshKeyId\": ${INDIGO_SSH_KEY_ID},
  \"regionId\": ${INDIGO_REGION_ID},
  \"osId\": ${INDIGO_OS_ID},
  \"instancePlan\": ${INDIGO_INSTANCE_PLAN},
  \"instanceName\": \"${INDIGO_INSTANCE_NAME}\"
}" | tee /tmp/indigo_create.json >/dev/null

# 返却から instanceId を取得(キー名は環境に合わせて変更)
INSTANCE_ID=$(jq -r '.instanceId // .id' /tmp/indigo_create.json)
[ -n "$INSTANCE_ID" ] || { echo "instanceId を取得できませんでした"; exit 1; }

# 2) start
curl -s -X POST "${INDIGO_API_BASE}/vm/instance/statusupdate" "${h[@]}" \
  -d "{\"instanceId\":\"${INSTANCE_ID}\",\"status\":\"start\"}" >/dev/null

# 3) IP取得(スキーマに合わせてパスを調整)
for i in {1..60}; do
  ip=$(curl -s -X GET "${INDIGO_API_BASE}/vm/getinstancelist" -H "Authorization: Bearer $INDIGO_TOKEN" \
    | jq -r --arg id "$INSTANCE_ID" '.[] | select((.id|tostring)==$id and .instancestatus=="Running") | (.ip // .ipaddress)')
  if [[ -n "$ip" && "$ip" != "null" ]]; then echo "IP=$ip"; break; fi
  sleep 5
  echo "waiting IP..."
done

# 4) SSH
exec ssh -i ~/.ssh/indigo_demo_ed25519 ubuntu@"$ip"

付録B:Python(requests)サンプル

provision.py(雛形)

provision.py
import os, time, json, requests
API=os.environ['INDIGO_API_BASE']
TOKEN=os.environ['INDIGO_TOKEN']
REGION_ID=int(os.environ['INDIGO_REGION_ID'])
OS_ID=int(os.environ['INDIGO_OS_ID'])
PLAN=int(os.environ['INDIGO_INSTANCE_PLAN'])
SSH_KEY_ID=int(os.environ['INDIGO_SSH_KEY_ID'])
NAME=os.environ['INDIGO_INSTANCE_NAME']

H={"Authorization":f"Bearer {TOKEN}","Content-Type":"application/json"}

# createinstance (STOP)
body={
    "sshKeyId": SSH_KEY_ID,
    "regionId": REGION_ID,
    "osId": OS_ID,
    "instancePlan": PLAN,
    "instanceName": NAME
}
resp=requests.post(f"{API}/vm/createinstance", headers=H, data=json.dumps(body))
resp.raise_for_status()
crt=resp.json()
instance_id = crt.get("instanceId") or crt.get("id")
assert instance_id, f"createinstance response missing id: {crt}"

# start
requests.post(f"{API}/vm/instance/statusupdate", headers=H,
              data=json.dumps({"instanceId": str(instance_id), "status":"start"})
             ).raise_for_status()

# poll IP
ip=None
for _ in range(60):
    li = requests.get(f"{API}/vm/getinstancelist", headers={"Authorization":f"Bearer {TOKEN}"}).json()
    assert isinstance(li, list), f"unexpected list API shape: {type(li)}"
    for inst in li:
        if str(inst.get("id")) == str(instance_id) or inst.get("instance_name") == NAME:
            if inst.get("instancestatus") != "Running":
                break
            ip = inst.get("ip") or inst.get("ipaddress")
            ipv6 = inst.get("secondary_ip")
            break
            break
    if ip: break
    time.sleep(5)

print("PUBLIC_IP:", ip or "<not-found>")

セキュリティ & 運用のヒント

  • 鍵認証+パスワードログイン無効化(上記cloud-initで対応)
  • UFW/iptables で最小限のポートのみ開放
  • Fail2ban を有効化
  • 監査ログ(auth.log, SSHログ)を中央集約(例:Fluent Bit → Loki/Cloud Logging)
  • APIトークンのローテーション、リポジトリに置かない
  • Terraform/Ansible への移行:API実験→本番運用の自然な次の一歩

トラブルシュート

  • 401/403:トークン不正・権限不足 → 再発行/権限確認
  • 429:APIレート超過 → バックオフ・再試行
  • 400:パラメータ不正(plan/image/regionなどIDのタイプミス)
  • IP未付与/SSHできない:cloud-init の完了待ち、セキュリティグループ/Firewallを確認
  • キー形式エラー:ssh-ed25519 など正しい形式か再確認

参考の置換ポイント(あなたの環境に合わせる)

  • INDIGO_API_BASE:公式ドキュメントの 実際のベースURL に変更
  • INDIGO_REGION / INDIGO_PLAN / INDIGO_IMAGE:提供中のIDに変更
  • レスポンスのJSONパス(network.public_ipv4 など)は 実際のスキーマ に合わせて修正
  • cloud-init の内容は要件に応じて拡張(Docker/Podman, WireGuard, Prometheus Node Exporter等)

コストの目安(1GB Linuxプラン・税込み)

価格は 税込み で表記します。実額・最新は公式サイトをご確認ください。

1GB Linuxプランの料金(プランに含まれるもの)

  • 時間従量:0.70円/時間(税込み)

  • 月額上限:449円/月(税込み)

  • 月の最低利用料:55円/月(税込み)(当月に料金が発生した場合のみ適用)

  • 含まれるリソース:IPv4/IPv6 各1個(追加料金なし)、SSD 20GB(追加料金なし)、転送量(課金なし)

試験利用の目安(例)

  • 2時間だけ試す → 0.70×2 = **1.40円(税込み)**ですが、**最低利用料 55円(税込み)**が適用 → 請求は 55円(税込み)

  • インスタンスを作成しなかった月 → 最低利用料は適用されない

1ヶ月フル稼働の目安(例)

*24時間×30日 = 720時間 → 0.70×720 = **504円(税込み)**ですが、**月額上限 449円(税込み)**が適用 → 請求は 449円(税込み)

オプションで費用がかかるもの(必要時のみ)

  • スナップショット:0.0088円/GB・時間(税込み) / 月額上限 5.5円/GB(税込み)

  • DNS:550円/ゾーン・月(税込み)

  • 契約譲渡手数料:2,200円(税込み)

備考:VPSインスタンスが存在するとVPS停止中も課金、計算期間はUTCの当月1日〜末日。転送量は課金なしですが、運用の目安値は別途ドキュメントに記載があります。

まとめ

  • APIベースのVPS作成は 再現性・自動化・監査性 が強み。
  • 雛形を土台にして、TerraformやCI/CD、監視まで一気通貫で仕上げましょう。

参考リンク


変更履歴(記事メンテ用)

  • 初版:2025-08-12
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?