はじめに
「SAP AI Core技術連載」第4回。
SAP AI Coreの管理作業のうち、Gitリポジトリ管理(6.1節)とアプリケーション管理(6.2節)を扱う。前回(#3)は初期セットアップ(Cloud Foundry/Kyma)を扱った。次回(#5)は管理②(リソースグループ・各種シークレット管理)を扱う。
管理作業の位置づけ
SAP AI Coreで使う外部プログラム・ツール用のシークレットを作成することで、認証情報を漏らすことなくそれらを接続できる。
GitHub・Docker・Amazon Web Services S3ストレージといった外部ツールをSAP AI Coreと併用することで、バージョン管理・コンテナ化・クラウドストレージの利点を活用できる。安定したインターネット接続があれば、コンテンツはリモートから利用可能になる。
管理作業は基本的に一度きりの手順である。ただしツールの追加・削除など、必要に応じて手順を繰り返し実行できる。
Note: SAP AI Coreインスタンスを設定する前に、初期セットアップのタスクを完了しておく必要がある(#3参照)
なお、GitOpsによるテンプレート同期の仕組み自体は#2「内部動作:同期とプロセスフロー」で解説済み。本記事では、その設定を実際に行うAPI手順を扱う。
以降のcurl例で使う$AI_API_URL・$TOKENの環境変数設定は#3を参照。
6.1 Gitリポジトリ管理
自身のGitリポジトリを使って、SAP AI Coreのテンプレートをバージョン管理できる。SAP AI CoreインスタンスへのGitOpsオンボーディングは、Gitリポジトリのセットアップとコンテンツの同期からなる。
Gitリポジトリは、パーソナルアクセストークン(PAT)を作成してSAP AI Coreに登録することで管理する。PATは、認証情報を漏らすことなくGitHubリポジトリへの接続を許可・制御する手段である。
Remember: BTP内のSAP AI Coreアクセス認証情報・証明書のローテーションは、リージョンポリシーに従いユーザー自身の責任で行う
6.1.1 Gitリポジトリの追加
前提条件
- 初期セットアップが完了していること
- インターネット経由でGitリポジトリにアクセスできること
- Gitリポジトリのパーソナルアクセストークンを生成済みであること
- GitLabホストのリポジトリをオンボードする場合、リポジトリURLに
.gitサフィックスが含まれていること - リポジトリ内にシークレットが存在しないこと(シークレットが使われている場合、コンテンツを同期できない)
シークレットを含むリポジトリが同期できないのは、単なる技術制約ではない。認証情報をGit管理下に置かせず、シークレットはSAP AI Core側の仕組み(#5で扱う)で管理させるための設計である。回避策を探すのではなく、シークレットをリポジトリから分離する前提で構成を設計する。
Note: リソースを同期する際は、特に1テナント内で複数のリポジトリまたはアプリケーションを使う場合、名前の衝突がないことを確認する。同期で問題が発生する場合は、1テナントにつきリポジトリまたはアプリケーションを1つだけ使うことが推奨される
この推奨は、#2で解説したリソースの範囲と関係する。テンプレート(Executable)はテナントレベルのリソースであり、テナント内の全リソースグループで共有される。つまりリソースグループを分けてもテンプレートの名前空間は分かれないため、複数リポジトリを同一テナントに登録すると名前衝突が起きやすい。
以下のリポジトリURLは、すべて同一のリポジトリとみなされる。
https://github.com/user/repo
https://github.com/user/repo/
https://github.com/user/REPO/
手順
{{apiurl}}/v2/admin/repositoriesエンドポイントにPOSTリクエストを送信し、認証情報を含める。
curl --location --request POST "$AI_API_URL/v2/admin/repositories" \
--header "Authorization: Bearer $TOKEN" \
--header 'Content-Type: application/json' \
--data-raw '{
"url": "https://github.com/john/examplerepo",
"username": "john",
"password": "<GIT_PAT_USER_TOKEN>"
}'
パラメータは以下の通り。
-
url:GitリポジトリのURL -
username:Gitリポジトリにアクセスする(サービス)ユーザー -
password:Gitのパーソナルアクセストークン
Tip: 2つのテナント間でリポジトリを共有する場合、各テナントで個別にリポジトリを追加し、同じusernameとpasswordを指定する
サードパーティAPIプラットフォームを使う場合も、同じエンドポイントにJSON形式のボディでPOSTリクエストを送信する。
6.1.2 Gitリポジトリの編集
{{apiurl}}/v2/admin/repositoriesエンドポイントにPATCHリクエストを送信し、変更内容を含める。
curl --location --request PATCH "$AI_API_URL/v2/admin/repositories" \
--header "Authorization: Bearer $TOKEN" \
--header 'Content-Type: application/json' \
--data-raw '{
"url": "https://github.com/john/examplerepo",
"username": "john",
"password": "<GIT_PAT_USER_TOKEN>"
}'
指定するパラメータは追加時と同じ(url・username・password)。
Note: 公式ドキュメントでは、Curlの例は
/v2/admin/repositories、サードパーティAPIプラットフォームの例は/v2/admin/repositories/{{repositoryName}}と、エンドポイントの記載が異なる(後述の「公式ドキュメントの記載不整合」参照)
6.1.3 Gitリポジトリの削除
URLが無効・誤りを含む場合、またはリポジトリが不要になった場合に、接続からGitリポジトリを削除する。
削除後はそのリポジトリをアプリケーションのソースリポジトリとして選択できなくなる。
curl --location --request DELETE "{{apiurl}}/v2/admin/repositories/{{repositoryName}}" \
サードパーティAPIプラットフォームを使う場合も、同じエンドポイントにリポジトリ名を含めてDELETEリクエストを送信する。
6.2 アプリケーション管理
6.2.1 アプリケーションの作成
Gitリポジトリを追加した後、リポジトリ内のテンプレートを同期するためにアプリケーションを作成する。
- 初回の同期には時間がかかる。完了タイミングはアプリケーションのステータスで確認できる
- 初回同期後は、システムが約3分ごとに自動でテンプレートを同期する
- 手動での同期リクエストも可能
Note: 同一のソースを同期しようとするアプリケーションを重複して作成しないこと。2つのアプリが同じ
repositoryURL・revision・pathを持つ場合、同期は失敗する
手順
{{apiurl}}/v2/admin/applicationsエンドポイントにPOSTリクエストを送信し、アプリケーションの詳細を含める。
curl --location --request POST "$AI_API_URL/v2/admin/applications" \
--header "Authorization: Bearer $TOKEN" \
--header 'Content-Type: application/json' \
--data-raw '{
"applicationName": "my-app",
"repositoryUrl": "https://github.com/john/examplerepo",
"revision": "HEAD",
"path": "workflows"
}'
パラメータの制約は以下の通り。
-
applicationName:アプリケーション名。3〜64文字で、[A-Za-z0-9\-\_]+に一致する必要がある(使えるのは英数字・ハイフン・アンダースコアのみで、ピリオドやスラッシュは含められない。リポジトリのフォルダ構成をそのまま命名に流用する場合は変換ルールが必要になる) -
repositoryUrl:登録済みGitリポジトリのURL。大文字小文字を区別し、登録済みリポジトリのURLと完全一致する必要がある -
revision:対象とするリビジョン。HEADは最新リビジョンを指す -
path:同期対象のテンプレートを含むフォルダへのパス
各アプリケーションはリポジトリ内の特定のパスとリビジョンを参照するため、同じrepositoryUrlに対して複数のアプリケーションを作成できる。
結果
GitOpsのセットアップ完了後、Gitリポジトリ内のテンプレートはSAP AI Coreへ自動同期される。同期は約3分ごとに実行される。
同期ステータスの確認
{{apiurl}}/v2/admin/applications/{{appName}}/statusエンドポイントにGETリクエストを送信する。appNameには、アプリケーション作成時に指定した名前を入力する。
curl --location --request GET "$AI_API_URL/v2/admin/applications/{{appName}}/status" \
--header "Authorization: Bearer $TOKEN" \
--header 'Content-Type: application/json'
出力例は以下の通り。
{
"healthStatus": "Healthy",
"message": "successfully synced (all tasks run)",
"reconciledAt": "2021-11-23T10:27:49Z",
"source": {
"path": "workflows",
"repoURL": "https://github.com/username/examplerepo",
"revision": "db611bb28be3c853d08867c08b52b8f733b4f7bf"
},
"syncFinishedAt": "2021-11-23T10:27:49Z",
"syncResourceStatus": [
{
"kind": "ServingTemplate",
"message": "servingtemplate.ai.sap.com/text-clf-infer-tutorial configured",
"name": "text-clf-infer-tutorial",
"status": "Synced"
}
],
"syncStartedAt": "2021-11-23T10:27:48Z",
"syncStatus": "Synced"
}
※公式ドキュメントの出力例には表記の誤り(ServingTemaplateという綴り、およびsyncedStartedAtの値の引用符の不整合)が含まれている。上記は誤りを補正した形で掲載している。
手動同期
アプリケーションは約3分間隔でGitHubリポジトリと自動同期される。手動で同期をリクエストする場合は、以下のエンドポイントを使う。
{{apiurl}}/admin/applications/{{appName}}/refresh
Note: 公式ドキュメントでは、このエンドポイントのみ
/v2のパスが記載されていない(後述の「公式ドキュメントの記載不整合」参照)
6.2.2 アプリケーションの一覧取得
{{apiurl}}/v2/admin/applicationsエンドポイントにGETリクエストを送信する。
6.2.3 アプリケーションの編集
{{apiurl}}/v2/admin/applications/{{appName}}エンドポイントにPATCHリクエストを送信し、変更内容をボディに含める。
6.2.4 アプリケーションの削除
{{apiurl}}/v2/admin/applications/{{appName}}エンドポイントにDELETEリクエストを送信する。
エンドポイント一覧
Gitリポジトリ管理・アプリケーション管理のエンドポイントをまとめる。
Gitリポジトリ
- 追加:
POST /v2/admin/repositories - 編集:
PATCH /v2/admin/repositories - 削除:
DELETE /v2/admin/repositories/{{repositoryName}}
アプリケーション
- 作成:
POST /v2/admin/applications - 一覧:
GET /v2/admin/applications - 編集:
PATCH /v2/admin/applications/{{appName}} - 削除:
DELETE /v2/admin/applications/{{appName}} - ステータス確認:
GET /v2/admin/applications/{{appName}}/status - 手動同期:
{{apiurl}}/admin/applications/{{appName}}/refresh
公式ドキュメントの記載不整合
本記事の対象範囲では、公式ドキュメントに以下の記載不整合が確認できた。実装時は最新の公式APIリファレンスで確認することを推奨する。
-
6.1.2 リポジトリ編集のエンドポイント:Curlの例は
/v2/admin/repositories、サードパーティAPIプラットフォームの例は/v2/admin/repositories/{{repositoryName}}と記載が異なる -
手動同期のエンドポイント:このエンドポイントのみ
/v2のパスが記載されていない -
ステータス確認のJSON出力例:
ServingTemaplateという綴りの誤り、およびsyncedStartedAtの値の引用符の不整合が含まれている
参考:チュートリアル(5章)
公式ドキュメントの5章には、SAP AI Core関連のミッション・チュートリアル一覧が掲載されている。
- Getting Started:Boosterを使ったFreeプランでのSAP AI Core・SAP AI Launchpadのプロビジョニング
- Generative AI:Setup(BTP環境の構築)、Orchestration(複数ベンダーのLLMを使った生成AIワークフロー、生成AI SDKでのプロンプト・embeddingの基礎)、Foundation Models(SAP AI Coreに含まれる基盤LLMの各種ユースケース探索)
- Predictive AI:SAP AI Coreの基礎、最初の予測AIワークフロー作成、機械学習コードの本番クラウドへの移行
まとめ
- Gitリポジトリの登録はPAT(パーソナルアクセストークン)を用いて行い、
/v2/admin/repositoriesエンドポイントで追加・編集・削除する - リポジトリ内にシークレットが存在するとコンテンツを同期できない
- 名前の衝突を避けるため、1テナントにつきリポジトリ・アプリケーションは1つずつが推奨される
- アプリケーションは
repositoryUrl・revision・pathの組み合わせでテンプレートの同期対象を指定する。同一の組み合わせを持つアプリを重複作成すると同期に失敗する - 同一リポジトリに対しては、パス・リビジョンが異なれば複数のアプリケーションを作成できる
- 初回同期後は約3分間隔で自動同期され、
/refreshエンドポイントで手動同期もできる - 次回(#5)は管理②(リソースグループ・各種シークレット管理)を扱う
用語解説
- パーソナルアクセストークン(PAT):認証情報そのものを渡さずにGitリポジトリへの接続を許可・制御するためのトークン
- アプリケーション:SAP AI Coreにおいて、Gitリポジトリ内の特定パス・リビジョンのテンプレートを同期する単位
-
revision:同期対象とするGitのリビジョン。
HEADは最新リビジョンを指す - GitOps:Gitリポジトリを唯一の正とし、その内容を実行環境へ自動同期する運用方式