Skip to content

Commit 7d5f4fd

Browse files
committed
[aks-preview] subcommand to provision foundry and deploy openclaw
1 parent 55f041f commit 7d5f4fd

9 files changed

Lines changed: 1075 additions & 0 deletions

File tree

src/aks-preview/azext_aks_preview/_help.py

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4453,3 +4453,94 @@
44534453
- name: Show a specific JWT authenticator configuration
44544454
text: az aks jwtauthenticator show -g MyResourceGroup --cluster-name MyCluster --name myjwt
44554455
"""
4456+
4457+
helps['aks openclaw'] = """
4458+
type: group
4459+
short-summary: Commands to deploy and manage OpenClaw on an AKS cluster.
4460+
"""
4461+
4462+
helps['aks openclaw deploy'] = """
4463+
type: command
4464+
short-summary: Deploy OpenClaw with Azure AI Foundry on an AKS cluster.
4465+
long-summary: |
4466+
Provisions Azure AI Foundry resources (or uses an existing one), deploys the
4467+
openclaw-kubernetes Helm chart with LiteLLM proxy, and configures the web UI.
4468+
By default, a new AIServices account is created using the resource group's location
4469+
and an auto-generated name. Use --ai-foundry-resource-id or --ai-foundry-endpoint
4470+
to bring your own AI Foundry resource instead.
4471+
parameters:
4472+
- name: --cluster-name
4473+
type: string
4474+
short-summary: Name of the AKS cluster.
4475+
- name: --ai-foundry-resource-id
4476+
type: string
4477+
short-summary: Full ARM resource ID of an existing AIServices account (BYO mode).
4478+
- name: --ai-foundry-endpoint
4479+
type: string
4480+
short-summary: Endpoint URL of an existing AI Foundry resource (BYO mode). Requires --ai-foundry-api-key.
4481+
- name: --ai-foundry-api-key
4482+
type: string
4483+
short-summary: API key for the AI Foundry endpoint. Required with --ai-foundry-endpoint.
4484+
- name: --ai-foundry-location
4485+
type: string
4486+
short-summary: Azure region for provisioning a new AIServices account. Defaults to the resource group's location.
4487+
- name: --model
4488+
type: string
4489+
short-summary: Model name to deploy. Default is gpt-5.1-chat.
4490+
- name: --model-version
4491+
type: string
4492+
short-summary: Model version to deploy. Default is 2025-11-13. Only used when provisioning new resources.
4493+
- name: --deployment-name
4494+
type: string
4495+
short-summary: Azure model deployment name. Auto-generated if not specified.
4496+
- name: --capacity
4497+
type: int
4498+
short-summary: Tokens-per-minute capacity for the model deployment. Default is 50. Only used when provisioning new resources.
4499+
- name: --namespace
4500+
type: string
4501+
short-summary: Kubernetes namespace for OpenClaw. Default is openclaw.
4502+
examples:
4503+
- name: Deploy OpenClaw with auto-provisioned AI Foundry (simplest)
4504+
text: az aks openclaw deploy -g MyResourceGroup --cluster-name MyCluster
4505+
- name: Deploy with a specific model and region override
4506+
text: az aks openclaw deploy -g MyResourceGroup --cluster-name MyCluster --model gpt-4o --ai-foundry-location westus
4507+
- name: Deploy using an existing AI Foundry resource (BYO by resource ID)
4508+
text: az aks openclaw deploy -g MyResourceGroup --cluster-name MyCluster --ai-foundry-resource-id /subscriptions/SUB_ID/resourceGroups/RG/providers/Microsoft.CognitiveServices/accounts/myaccount
4509+
- name: Deploy using a raw endpoint and API key (BYO by endpoint)
4510+
text: az aks openclaw deploy -g MyResourceGroup --cluster-name MyCluster --ai-foundry-endpoint https://eastus.api.cognitive.microsoft.com --ai-foundry-api-key MY_KEY --deployment-name gpt51chat
4511+
"""
4512+
4513+
helps['aks openclaw delete'] = """
4514+
type: command
4515+
short-summary: Delete OpenClaw deployment from an AKS cluster.
4516+
parameters:
4517+
- name: --cluster-name
4518+
type: string
4519+
short-summary: Name of the AKS cluster.
4520+
- name: --namespace
4521+
type: string
4522+
short-summary: Kubernetes namespace where OpenClaw is deployed. Default is openclaw.
4523+
- name: --delete-ai-resources
4524+
type: bool
4525+
short-summary: Also delete the auto-provisioned AIServices account. Default is false.
4526+
examples:
4527+
- name: Delete OpenClaw deployment
4528+
text: az aks openclaw delete -g MyResourceGroup --cluster-name MyCluster --yes
4529+
- name: Delete OpenClaw and the provisioned AI Foundry resources
4530+
text: az aks openclaw delete -g MyResourceGroup --cluster-name MyCluster --delete-ai-resources --yes
4531+
"""
4532+
4533+
helps['aks openclaw show'] = """
4534+
type: command
4535+
short-summary: Show OpenClaw deployment status on an AKS cluster.
4536+
parameters:
4537+
- name: --cluster-name
4538+
type: string
4539+
short-summary: Name of the AKS cluster.
4540+
- name: --namespace
4541+
type: string
4542+
short-summary: Kubernetes namespace where OpenClaw is deployed. Default is openclaw.
4543+
examples:
4544+
- name: Show OpenClaw status
4545+
text: az aks openclaw show -g MyResourceGroup --cluster-name MyCluster
4546+
"""

src/aks-preview/azext_aks_preview/_params.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3149,6 +3149,62 @@ def load_arguments(self, _):
31493149
c.argument('config_file', options_list=['--config-file'], type=file_type, completer=FilesCompleter(),
31503150
help='Path to the JSON configuration file containing JWT authenticator properties.')
31513151

3152+
# OpenClaw commands
3153+
with self.argument_context("aks openclaw") as c:
3154+
c.argument("cluster_name", options_list=["--cluster-name"], help="The AKS cluster name.")
3155+
c.argument("namespace", help="Kubernetes namespace for OpenClaw. Default is openclaw.")
3156+
3157+
with self.argument_context("aks openclaw deploy") as c:
3158+
c.argument(
3159+
"ai_foundry_resource_id",
3160+
options_list=["--ai-foundry-resource-id"],
3161+
help="Full ARM resource ID of an existing AIServices account (BYO mode).",
3162+
)
3163+
c.argument(
3164+
"ai_foundry_endpoint",
3165+
options_list=["--ai-foundry-endpoint"],
3166+
help="Endpoint URL of an existing AI Foundry resource (BYO mode). Requires --ai-foundry-api-key.",
3167+
)
3168+
c.argument(
3169+
"ai_foundry_api_key",
3170+
options_list=["--ai-foundry-api-key"],
3171+
help="API key for the AI Foundry endpoint. Required with --ai-foundry-endpoint.",
3172+
)
3173+
c.argument(
3174+
"ai_foundry_location",
3175+
options_list=["--ai-foundry-location"],
3176+
help="Azure region for provisioning a new AIServices account. Defaults to the resource group's location.",
3177+
)
3178+
c.argument(
3179+
"model",
3180+
options_list=["--model"],
3181+
help="Model name to deploy. Default is gpt-5.1-chat.",
3182+
)
3183+
c.argument(
3184+
"model_version",
3185+
options_list=["--model-version"],
3186+
help="Model version to deploy. Default is 2025-11-13. Only used when provisioning new resources.",
3187+
)
3188+
c.argument(
3189+
"deployment_name",
3190+
options_list=["--deployment-name"],
3191+
help="Azure model deployment name. Auto-generated from model name if not specified.",
3192+
)
3193+
c.argument(
3194+
"capacity",
3195+
options_list=["--capacity"],
3196+
type=int,
3197+
help="Tokens-per-minute capacity for the model deployment. Default is 50.",
3198+
)
3199+
3200+
with self.argument_context("aks openclaw delete") as c:
3201+
c.argument(
3202+
"delete_ai_resources",
3203+
options_list=["--delete-ai-resources"],
3204+
action="store_true",
3205+
help="Also delete the auto-provisioned AIServices account.",
3206+
)
3207+
31523208

31533209
def _get_default_install_location(exe_name):
31543210
system = platform.system()

src/aks-preview/azext_aks_preview/commands.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,3 +603,13 @@ def load_command_table(self, _):
603603
self.command_table["aks safeguards delete"] = Delete(loader=self)
604604
self.command_table["aks safeguards list"] = List(loader=self)
605605
self.command_table["aks safeguards wait"] = Wait(loader=self)
606+
607+
# AKS openclaw commands
608+
with self.command_group(
609+
"aks openclaw",
610+
managed_clusters_sdk,
611+
client_factory=cf_managed_clusters,
612+
) as g:
613+
g.custom_command("deploy", "aks_openclaw_deploy")
614+
g.custom_command("delete", "aks_openclaw_delete", confirmation=True)
615+
g.custom_show_command("show", "aks_openclaw_show")

src/aks-preview/azext_aks_preview/custom.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5375,3 +5375,49 @@ def aks_jwtauthenticator_list(cmd, client, resource_group_name, cluster_name, ak
53755375
def aks_jwtauthenticator_show(cmd, client, resource_group_name, cluster_name, name, aks_custom_headers=None):
53765376
headers = get_aks_custom_headers(aks_custom_headers)
53775377
return client.get(resource_group_name, cluster_name, name, headers=headers)
5378+
5379+
5380+
# openclaw commands
5381+
def aks_openclaw_deploy(cmd, client, resource_group_name, cluster_name,
5382+
ai_foundry_resource_id=None,
5383+
ai_foundry_endpoint=None,
5384+
ai_foundry_api_key=None,
5385+
ai_foundry_location=None,
5386+
model=None,
5387+
model_version=None,
5388+
deployment_name=None,
5389+
capacity=None,
5390+
namespace=None):
5391+
from azext_aks_preview.openclaw.deploy import deploy_openclaw
5392+
return deploy_openclaw(
5393+
cmd, resource_group_name, cluster_name,
5394+
ai_foundry_resource_id=ai_foundry_resource_id,
5395+
ai_foundry_endpoint=ai_foundry_endpoint,
5396+
ai_foundry_api_key=ai_foundry_api_key,
5397+
ai_foundry_location=ai_foundry_location,
5398+
model=model,
5399+
model_version=model_version,
5400+
deployment_name=deployment_name,
5401+
capacity=capacity,
5402+
namespace=namespace,
5403+
)
5404+
5405+
5406+
def aks_openclaw_delete(cmd, client, resource_group_name, cluster_name,
5407+
namespace=None,
5408+
delete_ai_resources=False):
5409+
from azext_aks_preview.openclaw.deploy import delete_openclaw
5410+
return delete_openclaw(
5411+
cmd, resource_group_name, cluster_name,
5412+
namespace=namespace,
5413+
delete_ai_resources=delete_ai_resources,
5414+
)
5415+
5416+
5417+
def aks_openclaw_show(cmd, client, resource_group_name, cluster_name,
5418+
namespace=None):
5419+
from azext_aks_preview.openclaw.deploy import show_openclaw
5420+
return show_openclaw(
5421+
cmd, resource_group_name, cluster_name,
5422+
namespace=namespace,
5423+
)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# --------------------------------------------------------------------------------------------
2+
# Copyright (c) Microsoft Corporation. All rights reserved.
3+
# Licensed under the MIT License. See License.txt in the project root for license information.
4+
# --------------------------------------------------------------------------------------------
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# --------------------------------------------------------------------------------------------
2+
# Copyright (c) Microsoft Corporation. All rights reserved.
3+
# Licensed under the MIT License. See License.txt in the project root for license information.
4+
# --------------------------------------------------------------------------------------------
5+
6+
# Helm chart
7+
CONST_OPENCLAW_HELM_CHART_URL = "oci://ghcr.io/feiskyer/openclaw-kubernetes/openclaw"
8+
CONST_OPENCLAW_DEFAULT_NAMESPACE = "openclaw"
9+
10+
# Azure AI Foundry defaults
11+
CONST_OPENCLAW_DEFAULT_MODEL = "gpt-5.1-chat"
12+
CONST_OPENCLAW_DEFAULT_MODEL_VERSION = "2025-11-13"
13+
CONST_OPENCLAW_DEFAULT_CAPACITY = 50
14+
CONST_OPENCLAW_DEFAULT_SKU = "GlobalStandard"
15+
CONST_OPENCLAW_AI_SERVICES_KIND = "AIServices"
16+
CONST_OPENCLAW_AI_SERVICES_SKU = "S0"
17+
CONST_OPENCLAW_COGNITIVE_API_VERSION = "2024-10-01"
18+
19+
# Storage
20+
CONST_OPENCLAW_STORAGE_CLASS_NAME = "azurefile-openclaw"
21+
22+
# LiteLLM
23+
CONST_OPENCLAW_LITELLM_API_VERSION = "2024-10-01-preview"

0 commit comments

Comments
 (0)