Skip to content

Pulumiを使用したワークロードの管理

プレミアム機能

Workload APIはプレミアム機能です。 この機能を有効にする方法については、DataRobotの担当者または管理者にお問い合わせください。

DataRobot Pulumiプロバイダーは、ワークロードアーティファクトとワークロードをネイティブのリソースとして公開します。コードでアーティファクトとワークロードを宣言し、pulumi upを実行すると、Pulumiはプラットフォームを宣言した状態に調整します。

リソース基盤全体(すべての引数、すべての出力)については、Pulumiレジストリリファレンスを参照してください。このページでは、Pulumiを使用するタイミング、リソースがWorkload APIの概念にどのようにマッピングされるか、何が依然として命令的であるかなど、フレームワークについて説明します。

Pulumiを使用するケース

信頼できるビルドおよびロックされたアーティファクトがあり、それを本番インフラストラクチャとしてロールアウトする場合(リージョン間、ステージ間で、レプリカ数と重要度をコードレビューの対象とする場合)に、Pulumiを使用します。REST APIは動詞(buildpromotestop)を実行し、Pulumiは状態を調整します。

Pulumi管理のアーティファクトは常にロックされます

すべてのdatarobot.Artifactリソースは、pulumi upの終了までにlockedアーティファクトに解決されます。プロバイダーは1回の呼び出しでアーティファクトを直接lockedとして作成する(POST /artifactsstatus: lockedを渡す)ため、新しく適用されたアーティファクトは、適用の完了時にすでにロックされています。アーティファクトをドラフト状態に保つには、REST APIまたはコンソールを使用してアーティファクトを作成し、ロックされてからPulumiの管理下に置きます。

ワークフロー 推奨ツール
ビルドをトリガーし、ドラフトを昇格させる REST API
ステージ全体にロックされたアーティファクトをスタンプする Pulumi
本番フリートを新しいアーティファクトバージョンに調整する Pulumi
共有の管理(/sharedRoles RESTまたはコンソール
依然として命令的であるもの

Pulumiを使用している場合でも、いくつかの操作は状態ではなく動詞のままであり、プロバイダーによってモデル化されません:

操作 存在する場所
イメージの構築(POST /artifacts/{id}/builds RESTまたはコンソール
ドラフトを本番環境に昇格(POST /workloads/{id}/promote RESTまたはコンソール
共有(PATCH /workloads/{id}/sharedRoles RESTまたはコンソール
可観測性(イベント、統計、OTel) 読み取り専用。プラットフォームによって管理されます

パターン:シェルまたはCIから動詞を実行し、結果のロックされたアーティファクトに対してPulumiに本番フリートを調整させます。

Pulumiのセットアップ

Pulumiの使用を開始するには、まず、DataRobot Pulumiプロバイダーをインストールします:

pip install "pulumi-datarobot>=0.10.38" 
npm install "@datarobot/pulumi-datarobot@>=0.10.38" 

プロバイダーはPulumiスタック設定からDataRobotの認証情報を読み取ります:datarobot:endpointおよびdatarobot:apikey。スタックごとに1回設定します:

pulumi config set datarobot:endpoint [https://app.datarobot.com/api/v2](https://app.datarobot.com/api/v2)
pulumi config set datarobot:apikey <your-api-token> --secret


サポートされている設定パスの完全なリストについては、[Pulumiレジストリのインストールガイド](https://www.pulumi.com/registry/packages/datarobot/installation-configuration/){ target=_blank }を参照してください。

### `ApiTokenCredential`を使用した資格情報の管理 {: #managing-credentials-with-apitokencredential }

プロバイダーの`ApiTokenCredential`リソースは、Pulumiのステートから管理されたDataRobotの資格情報レコードを作成します。これにより、資格情報のライフサイクルが、それが機能するアーティファクトやワークロードとともに宣言的に保持されます。

``` python
import pulumi
import pulumi_datarobot as datarobot

# コンテナ側のトークン。Pulumiシークレットとして保持されるため、ソースに残ることはありません。
container_token = pulumi.Config().require_secret("datarobotToken")

credential = datarobot.ApiTokenCredential(
    "agent-service-token",
    name="agent-service-token",
    description="agent-serviceワークロードが使用するAPIトークン",
    api_token=container_token,
)

プロバイダー独自の認証(上記の datarobot:endpoint および datarobot:apikey)は、ApiTokenCredential とは独立しています。資格情報リソースは、プラットフォーム上で管理されるレコードを生成します。ワークロードがその資格情報をどのように利用するか(たとえば、アーティファクト仕様の環境変数を介して)は、ワークロード自体で設定されます。Workload における資格情報関連の引数の現在の構成については、Pulumiレジストリのリファレンス を参照してください。

簡単な例

次の例は、Pulumiを使用したワークロードへの最短パス(インラインのドラフトアーティファクトによって裏付けられたドラフトワークロード)を示しています。

import pulumi
import pulumi_datarobot as datarobot

artifact = datarobot.Artifact(
    "whoami-artifact",
    name="whoami-artifact",
    type="service",
    spec={
        "container_groups": [{
            "name": "default",
            "containers": [{
                "name": "whoami",
                "image_uri": "containous/whoami:latest",
                "port": 8080,
                "primary": True,
                "entrypoint": ["/whoami", "--port", "8080"],
                "readiness_probe": {"path": "/", "port": 8080, "initial_delay_seconds": 5},
            }]
        }]
    },
)

workload = datarobot.Workload(
    "hello-whoami",
    name="hello-whoami",
    artifact_id=artifact.artifact_id,
    runtime={
        "container_groups": [{
            "name": "default",
            "replica_count": 1,
            "containers": [{
                "name": "whoami",
                "resource_allocation": {"cpu": 1, "memory": "512MB"},
            }],
        }]
    },
)

pulumi.export("endpoint", workload.endpoint)

本番環境の例

本番環境レベルのワークロードでは通常、管理された資格情報、明示的な importance、スタック間のパラメーター化、およびアーティファクトが変更された場合の明確なポリシーが必要になります。

"""Pulumi program that stands up a service workload."""
import pulumi
import pulumi_datarobot as datarobot

# Third-party credential (for example, a model provider API key). Held as a Pulumi
# secret so it never lands in source. The DataRobot API token the container needs
# to call DataRobot's own APIs doesn't need this treatment -- see environment_vars below.
third_party_token = pulumi.Config().require_secret("modelProviderToken")

credential = datarobot.ApiTokenCredential(
    "model-provider-token",
    name="model-provider-token",
    description="Third-party model provider API token used by the agent-service workload",
    api_token=third_party_token,
)

artifact = datarobot.Artifact(
    "agent-service-artifact",
    name="agent-service-artifact",
    description="Agent service container artifact",
    type="service",
    spec={
        "container_groups": [{
            "containers": [{
                "name": "main",
                "image_uri": "ghcr.io/example/agent-service:0e90773",
                "port": 8000,
                "primary": True,
                "environment_vars": [
                    # Per-Workload DataRobot API token, resolved and injected automatically;
                    # no value is supplied here, and DATAROBOT_ENDPOINT needs no entry at
                    # all -- both are platform-managed. See Environment variable types.
                    {"source": "api-key"},
                    # Third-party credential, looked up from the managed credential record above.
                    {
                        "source": "dr-credential",
                        "name": "MODEL_PROVIDER_API_KEY",
                        "dr_credential_id": credential.id,
                        "key": "apiToken",
                    },
                ],
            }],
        }],
    },
)

workload = datarobot.Workload(
    "agent-service",
    name="agent-service",
    description="Agent service workload",
    importance="low",
    artifact_id=artifact.artifact_id,
    runtime={
        "container_groups": [{
            "replica_count": 1,
            "containers": [{
                "name": "main",
                "resource_allocation": {
                    "cpu": 2.0,
                    "memory": 5096 * 1024 * 1024,
                },
            }],
        }],
    },
    opts=pulumi.ResourceOptions(replace_on_changes=["artifact_id"]),
)

pulumi.export("credentialId", credential.id)
pulumi.export("artifactId", artifact.artifact_id)
pulumi.export("workloadId", workload.id)
pulumi.export("endpoint", workload.endpoint) 

以下のパターンは注目に値します:

  • {"source": "api-key"} は、ワークロードごとのDataRobot APIトークンを自動的に注入します。コンテナがDataRobot独自のAPIを呼び出すために、Pulumiのシークレット、資格情報リソース、または明示的な DATAROBOT_ENDPOINT エントリーは必要ありません。環境変数のタイプ を参照してください。
  • pulumi.Config().require_secret(...) は、サードパーティの資格情報をソースから除外し、Pulumiの状態にプレーンテキストとして保存されないようにします。その後、dr_credential_id=credential.id がその管理された資格情報をコンテナに組み込むため、シークレットがアーティファクトの仕様に表示されることはありません。
  • replace_on_changes=["artifact_id"] は、ワークロードが新しいアーティファクトを指すようになったときに、インプレースの更新ではなく完全な置換をトリガーし、Pulumiの差分にアーティファクトの交換を表面化させます。
  • バイト単位の memory (5096 * 1024 * 1024) は、プロバイダーのリソース割り当てスキーマと一致します。

ここから、Pulumiスタック (devstageprod) ごとに namereplica_count、および importance をパラメーター化することで、同じワークロードを複数のステージにわたってデプロイできます。また、同じロックされた artifact_id に裏付けられた複数の Workload リソースを宣言することでカナリアを追加したり、PulumiをCIに統合して、昇格のたびに pulumi up を実行し、宣言した本番環境のフリートを新しいアーティファクトバージョンに調整したりすることができます。

このプロセスは、以下のRESTフローにマッピングされます:

RESTのステップ Pulumi
インラインアーティファクトを使用してワークロードを作成する (POST /workloads) datarobot.Artifact + datarobot.Workload
APIトークンの資格情報を管理する (コンソール または REST) datarobot.ApiTokenCredential
running を待つ pulumi up は準備ができるまでブロックします。
呼び出し pulumi stack output endpoint
importance を上げる (PATCH /workloads/{id}) 宣言的な importance="critical"
ワークロードの背後にあるアーティファクトを置き換える artifact_id を変更します。replace_on_changes は管理された置換をトリガーします。
/sharedRoles 経由で共有する RESTまたはコンソール経由で管理します。
イベント / 統計情報を読み取る 変更なし。可観測性は読み取り側です。

リファレンス

詳細については、Pulumiプロバイダーのレジストリとリファレンスを参照してください: