インスタンス管理に IBM Cloud Resource Controller API を使用する
IBM Cloud® Resource Controller REST API を使用すると、プログラムからインスタンスを取得、作成、更新できます。
すべての Resource Controller エンドポイントでは、Authorization というヘッダーにベアラートークンを渡して認証する必要があります。REST API セットアップガイドを参照してください。
インスタンスの取得
特定のインスタンスに関する情報を取得するには、GET /v2/resource_instances/{crn} エンドポイントを使用します。パス内の CRN は URL エンコードする必要があります。
標準の Resource Controller フィールドに加えて、レスポンスには parameters と extensions の両方に量子固有のフィールドが含まれます。extensions にはインスタンスの正規化されたメタデータが保存されますが、parameters にはインスタンスを変更する最新のリクエストのみが保存されます。そのため、parameters ではなく extensions から読み取る必要があります。
extensions オブジェクトには次のフィールドが含まれます。
-
instance_limit_seconds— 整数またはnull。インスタンスの使用時間制限です。インスタンスの割り当て制限の設定を参照してください。 -
usage_allocation_seconds— 整数またはnull。このインスタンスに割り当てられた時間で、フェアシェアスケジューラーがキューの優先順位を決定するために使用します。インスタンスの割り当て制限の設定を参照してください。 -
backends— 文字列の配列。このインスタンスで利用可能な Backend 名の許可リストです。["ANY"]は、プランで利用可能なすべての Backend が利用可能であることを意味します(デフォルト)。[]は Backend が利用できないことを意味します。
extensions オブジェクト内の backends フィールドは古くなっている可能性があります。これは、IBM Quantum サポートがインスタンスに影響を与える形でアカウントを変更した場合に発生することがあります。たとえば、アカウントから Backend が削除されると、そのインスタンスの backends は更新されますが、その変更は現在のところ Resource Controller API にはまだ反映されていません。
代わりに、現在の回避策として、IBM Quantum Compute Service REST API の GET /v1/backends エンドポイントを使用してください。(Service-CRN ヘッダーにインスタンスの CRN を設定してください。)
- cURL
- Python
パス内の CRN は URL エンコードする必要があります。各 : を %3A に、各 / を %2F に置き換えてください。たとえば、crn:v1:bluemix:... は crn%3Av1%3Abluemix%3A... になります。
curl \
--request GET \
--url 'https://resource-controller.cloud.ibm.com/v2/resource_instances/<YOUR_INSTANCE_CRN_URL_ENCODED>' \
--header 'Authorization: Bearer <YOUR_BEARER_TOKEN>'
import urllib.parse
import requests
crn = "<YOUR_INSTANCE_CRN>"
# We use urllib.parse.quote to URL-encode the CRN.
url = (
"https://resource-controller.cloud.ibm.com/v2/resource_instances/"
+ urllib.parse.quote(crn, safe="")
)
resp = requests.get(
url,
headers={"Authorization": f"Bearer {token}"},
timeout=30,
)
resp.raise_for_status()
print(resp.json())
すべてのインスタンスの一覧を取得する
すべてのインスタンスの一覧を取得するには、GET /v2/resource_instances エンドポイントを使用します。IBM Quantum® インスタンスに絞り込むには、resource_id クエリパラメーターを b6049020-80f4-11eb-a0f7-e35ec9b4054f に設定します。
アカウントに複数のプランがあり、プランで絞り込みたい場合は、resource_plan_id クエリパラメーターを次のいずれかの値に設定します。
| プラン | resource_plan_id |
|---|---|
| Premium | 7f666d17-7893-47d8-bf9d-2b2389fc4dfc |
| Flex | 53bde9d3-cdbb-46f5-a98f-60ebcadf7260 |
| Pay-As-You-Go | 5304b575-3cff-4455-90dc-ae4367762093 |
| Open | 850b21a7-71de-4e53-9441-1abdd202f35d |
各結果には、インスタンスの取得で説明されているものと同じ extensions フィールドが含まれます。
- cURL
- Python
curl \
--request GET \
--url 'https://resource-controller.cloud.ibm.com/v2/resource_instances?resource_id=b6049020-80f4-11eb-a0f7-e35ec9b4054f' \
--header 'Authorization: Bearer <YOUR_BEARER_TOKEN>'
import requests
resp = requests.get(
"https://resource-controller.cloud.ibm.com/v2/resource_instances?resource_id=b6049020-80f4-11eb-a0f7-e35ec9b4054f",
headers={"Authorization": f"Bearer {token}"},
timeout=30,
)
resp.raise_for_status()
print(resp.json())
インスタンスの更新
インスタンスの制限、割り当て、許可された Backend を更新するには、PATCH /v2/resource_instances/{crn} エンドポイントを使用します。パス内の CRN は URL エンコードする必要があります。
変更したいフィールドを含む parameters JSON オブジェクトを、"Content-Type: application/json" ヘッダーとともにリクエストボディに渡します。省略されたフィールドは変更されません。
-
instance_limit_seconds— 整数またはnull。インスタンスの使用時間制限です。インスタンスの割り当て制限の設定を参照してください。 -
usage_allocation_seconds— 整数またはnull。このインスタンスに割り当てられた時間で、フェアシェアスケジューラーがキューの優先順位を決定するために使用します。インスタンスの割り当て制限の設定を参照してください。Pay-As-You-Go インスタンスには適用されません。 -
backends— 文字列の配列。このインスタンスで利用可能な Backend 名の許可リストです。["ANY"]は、プランで利用可能なすべての Backend が利用可能であることを意味します。[]は Backend が利用できないことを意味します。
parameters が直前のリクエストと同一の場合、API はそのリクエストを黙って無視します。各リクエストが一意として扱われるように、parameters オブジェクトには常に現在時刻を設定した timestamp フィールドを含めてください。
このエンドポイントのレスポンスは、extensions オブジェクトの扱い方も含めて、インスタンスの取得と似ています。
- cURL
- Python
パス内の CRN は URL エンコードする必要があります。各 : を %3A に、各 / を %2F に置き換えてください。たとえば、crn:v1:bluemix:... は crn%3Av1%3Abluemix%3A... になります。
curl \
--request PATCH \
--url 'https://resource-controller.cloud.ibm.com/v2/resource_instances/<YOUR_INSTANCE_CRN_URL_ENCODED>' \
--header 'Authorization: Bearer <YOUR_BEARER_TOKEN>' \
--header 'Content-Type: application/json' \
--data "{
\"parameters\": {
\"timestamp\": \"$(date -u +"%Y-%m-%dT%H:%M:%SZ")\",
\"usage_allocation_seconds\": 220
}
}"
import urllib.parse
import datetime
import requests
crn = "<YOUR_INSTANCE_CRN>"
# We use urllib.parse.quote to URL-encode the CRN.
url = (
"https://resource-controller.cloud.ibm.com/v2/resource_instances/"
+ urllib.parse.quote(crn, safe="")
)
timestamp = datetime.datetime.now(datetime.timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
body = {
"parameters": {
"timestamp": timestamp,
"usage_allocation_seconds": 220,
}
}
resp = requests.patch(
url,
headers={
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
},
json=body,
timeout=30,
)
resp.raise_for_status()
print(resp.json())
新しいインスタンスの作成
新しいインスタンスを作成(プロビジョニング)するには、POST /v2/resource_instances エンドポイントを使用します。"Content-Type: application/json" ヘッダーとともに JSON ボディを渡します。
必須フィールド:
-
name— インスタンスの名前(人が読める形式)です。 -
target—us-eastやeu-deなどのリージョンです。 -
resource_plan_id— このインスタンスのプランです。プラン ID の表を参照してください。 -
resource_group— 使用するリソースグループです。
量子固有の値を設定するために parameters オブジェクトを含めることもできます。
-
instance_limit_seconds— 整数またはnull。インスタンスの使用時間制限です。インスタンスの割り当て制限の設定を参照してください。 -
usage_allocation_seconds— 整数またはnull。このインスタンスに割り当てられた時間で、フェアシェアスケジューラーがキューの優先順位を決定するために使用します。インスタンスの割り当て制限の設定を参照してください。Pay-As-You-Go インスタンスには適用されません。 -
backends— 文字列の配列。このインスタンスで利用可能な Backend 名の許可リストです。["ANY"]は、プランで利用可能なすべての Backend が利用可能であることを意味します。[]は Backend が利用できないことを意味します。
- cURL
- Python
curl \
--request POST \
--url 'https://resource-controller.cloud.ibm.com/v2/resource_instances' \
--header 'Authorization: Bearer <YOUR_BEARER_TOKEN>' \
--header 'Content-Type: application/json' \
--data '{
"name": "my-new-instance",
"target": "us-east",
"resource_plan_id": "7f666d17-7893-47d8-bf9d-2b2389fc4dfc",
"resource_group": "<YOUR_RESOURCE_GROUP_ID>",
"parameters": {
"instance_limit_seconds": 300,
"usage_allocation_seconds": 220
}
}'
import requests
body = {
"name": "my-new-instance",
"target": "us-east",
"resource_plan_id": "7f666d17-7893-47d8-bf9d-2b2389fc4dfc",
"resource_group": "<YOUR_RESOURCE_GROUP_ID>",
"parameters": {
"instance_limit_seconds": 300,
"usage_allocation_seconds": 220,
},
}
resp = requests.post(
"https://resource-controller.cloud.ibm.com/v2/resource_instances",
headers={
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
},
json=body,
timeout=30,
)
resp.raise_for_status()
print(resp.json())
インスタンスで Qiskit Functions アクセスを構成する
ここでは、IBM Cloud Resource Controller API を使用して、既存の IBM Quantum Compute Service インスタンスに Qiskit Functions へのアクセスを構成する手順を説明します。コマンドは互いに依存しているため、手順は順番に実行してください。たとえば、トークンや URL などの変数は 1 つのステップで設定され、後のステップで再利用されます。
前提条件
-
IBM Cloud API キー(トークンとも呼ばれます)。必要に応じて、ダッシュボードで API キーを作成してください。
-
構成したいインスタンスの CRN。インスタンスの CRN は Instances ページに記載されています。
ステップ 1: ベアラートークンを取得する
API キーをベアラートークンと交換します。このトークンは、すべての Resource Controller リクエストの authorization ヘッダーに渡します。次のコードを実行してベアラートークンを生成します。
- cURL
- Python
curl --request POST \
--url 'https://iam.cloud.ibm.com/identity/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data 'apikey=<YOUR_API_KEY>&grant_type=urn%3Aibm%3Aparams%3Aoauth%3Agrant-type%3Aapikey'
--silent | jq .
import requests
api_key = "<YOUR_API_KEY>"
resp = requests.post(
"https://iam.cloud.ibm.com/identity/token",
headers={"Content-Type": "application/x-www-form-urlencoded"},
params={
"apikey": api_key,
"grant_type": "urn:ibm:params:oauth:grant-type:apikey",
},
timeout=30,
)
resp.raise_for_status()
token = resp.json()["access_token"]
print(token)
レスポンスには access_token フィールドが含まれており、これがベアラートークンです。この値をコピーしてください。
ステップ 2: アクセスを確認する
変更を加える前に、トークンが有効であることを確かめ、現在のインスタンス構成を確認してください。
- cURL
- Python
パス内の CRN は手動で URL エンコードする必要があります。各 : を %3A に、各 / を %2F に置き換えてください。たとえば、crn:v1:bluemix:... は crn%3Av1%3Abluemix%3A... になります。
curl --request GET \
--url 'https://resource-controller.cloud.ibm.com/v2/resource_instances/<YOUR_INSTANCE_CRN_URL_ENCODED>' \
--header 'Authorization: Bearer <YOUR_BEARER_TOKEN>'
import urllib.parse
crn = "<YOUR_INSTANCE_CRN>"
# CRN はパスに URL エンコードされます。
instance_url = (
"https://resource-controller.cloud.ibm.com/v2/resource_instances/"
+ urllib.parse.quote(crn, safe="")
)
headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"}
resp = requests.get(instance_url, headers=headers, timeout=30)
resp.raise_for_status()
print(resp.json()["extensions"])
200 OK レスポンスは、トークンが有効であることを示します。現在のインスタンス構成は、レスポンスの extensions フィールドにあります。古くなっている可能性がある parameters ではなく、こちらを使用してください。
ステップ 3: アカウントレベルの Functions 構成を確認する
インスタンスには、アカウントが権限を持つ範囲でのみアクセスを付与できます。インスタンスを構成する前に、アカウントの構成を確認して、どの functions、ビジネスモデル、権限を付与できるかを把握してください。これは、ステップ 4 で送信する値の信頼できる情報源となります。
API キーを使用して、Qiskit Runtime API の GET /accounts/{id} を呼び出します。{id} は a/ プレフィックスを除いたアカウント ID です。これは、インスタンスの CRN(crn:v1:bluemix:public:quantum-computing:...:a/<ACCOUNT_ID>:...)から確認できます。
- cURL
- Python
curl --request GET \
--url 'https://quantum.cloud.ibm.com/api/v1/accounts/<ACCOUNT_ID>' \
--header 'Authorization: apikey <YOUR_API_KEY>'
account_id = "<ACCOUNT_ID>" # from the CRN: crn:...:a/<ACCOUNT_ID>:...
resp = requests.get(
f"https://quantum.cloud.ibm.com/api/v1/accounts/{account_id}",
headers={"Authorization": f"apikey {api_key}"},
timeout=30,
)
resp.raise_for_status()
for plan in resp.json()["plans"]:
print(plan["plan_id"], plan.get("functions"), plan.get("custom_functions"))
レスポンス内の各プランには functions 配列が含まれ、構成されている場合は custom_functions オブジェクトも含まれます。これらには、そのプランでインスタンスに付与できる正確な name、provider、business model、permissions の値が一覧表示されます。
GET /accounts/{id} はアカウントレベルで付与可能な内容を示します。GET /functions(結果の確認を参照)は、特定のインスタンスに既に付与されている内容を示します。有効な値を確認するには account エンドポイントを使用し、結果を確認するには functions エンドポイントを使用してください。
ステップ 4: functions アクセスを構成する
インスタンスを更新して、Catalog Functions と Custom Functions へのアクセスを付与します。
- functions 内の
name、provider、business_modelの値は、アカウントレベルで構成されたエントリと完全に一致している必要があります(前のステップを参照)。permissions は、その function に対するアカウントの permissions の空でない部分集合である必要があります。同様に、custom_functions.permissionsは、アカウントのcustom_functionsの permissions の空でない部分集合である必要があります。 - すべての PATCH で parameters にタイムスタンプを含めてください。Resource Controller は、受信した parameters を最後に保存した値と比較することで、PATCH リクエストを重複排除します。一致する場合、リクエストはサービスに到達することなく
200 OKで黙って破棄されます。これを防ぐには、変化するタイムスタンプの値を含めてください。
- cURL
- Python
curl --request PATCH \
--url 'https://resource-controller.cloud.ibm.com/v2/resource_instances/<YOUR_INSTANCE_CRN_URL_ENCODED>' \
--header 'Authorization: Bearer <YOUR_BEARER_TOKEN>' \
--header 'Content-Type: application/json' \
--data '{
"parameters": {
"timestamp": "2026-06-30T00:00:00Z",
"functions": [
{
"name": "<FUNCTION_NAME>",
"provider": "<PROVIDER>",
"business_model": "<BUSINESS_MODEL>",
"permissions": [
"function.read",
"function.run",
"function-files.read",
"function-files.write"
]
}
],
"custom_functions": {
"permissions": [
"function-custom.write",
"function-custom.run"
]
}
}
}'
from datetime import datetime, timezone
# 変化するタイムスタンプにより、Resource Controller がリクエストを重複排除するのを防ぎます。
_now = datetime.now(timezone.utc)
timestamp = _now.strftime("%Y-%m-%dT%H:%M:%S.") + f"{_now.microsecond:06d}000Z"
body = {
"parameters": {
"timestamp": timestamp,
"functions": [
{
"name": "<FUNCTION_NAME>",
"provider": "<PROVIDER>",
"business_model": "<BUSINESS_MODEL>",
"permissions": [
"function.read",
"function.run",
"function-files.read",
"function-files.write",
],
}
],
"custom_functions": {
"permissions": ["function-custom.write", "function-custom.run"],
},
}
}
resp = requests.patch(instance_url, headers=headers, json=body, timeout=30)
resp.raise_for_status()
print(resp.json()["extensions"])
200 OK レスポンスは成功を示します。更新された構成は、レスポンスの extensions フィールドに表示されます。
functions アクセスを削除する
Catalog Functions
インスタンスから Catalog Functions を削除するには、"functions": null を指定して PATCH を送信します。
- cURL
- Python
--data '{
"parameters": {
"timestamp": "2026-06-30T00:00:01Z",
"functions": null
}
}'
body = {"parameters": {"timestamp": timestamp, "functions": None}}
resp = requests.patch(instance_url, headers=headers, json=body, timeout=30)
resp.raise_for_status()
"functions": [](空の配列)を設定することでも、同様に Catalog Functions をクリアできます。null が正規の形式です。
Custom Functions
インスタンスから Custom Functions を削除するには、"custom_functions": null を指定して PATCH を送信します。
- cURL
- Python
--data '{
"parameters": {
"timestamp": "2026-06-30T00:00:02Z",
"custom_functions": null
}
}'
body = {"parameters": {"timestamp": timestamp, "custom_functions": None}}
resp = requests.patch(instance_url, headers=headers, json=body, timeout=30)
resp.raise_for_status()
"custom_functions": {"permissions": []} を設定することでも、同様に custom functions をクリアできます。null が正規の形式です。
結果を確認する
インスタンスが正しい Qiskit Functions 構成を持っていることを確認するには、Resource Controller ではなく Qiskit Runtime API の GET /functions を使用してください。アカウントレベルの変更が Resource Controller の外部でインスタンスを更新した場合、Resource Controller に保存されている状態は古くなっている可能性があります。
- cURL
- Python
curl --request GET \
--url 'https://quantum.cloud.ibm.com/api/v1/functions' \
--header 'Authorization: apikey <YOUR_API_KEY>' \
--header 'Service-CRN: <YOUR_INSTANCE_CRN>'
# Service-CRN ヘッダーには、URL エンコードされた形式ではなく、生の CRN を指定します。
resp = requests.get(
"https://quantum.cloud.ibm.com/api/v1/functions",
headers={"Authorization": f"apikey {api_key}", "Service-CRN": crn},
timeout=30,
)
resp.raise_for_status()
print(resp.json())
レスポンスには、そのインスタンスが現在アクセスできる functions が一覧表示されます。