Skip to content

Commit 7919a20

Browse files
meerakurupfoundry-samples automationbalapv
authored andcommitted
Update template 18 and added new connection for BYO Models (#510)
* Updates to READMEs of all major networking templates (bicep mainly, also some TF) Updates to READMEs of all major networking templates(bicep mainly, also some TF) * Automatic fixes * More managed network updates more managed network updates * Automatic fixes * small updates to cli.md file * Add CLI version to update to * Update 18-managed-network and added new connection sample Update 18-managed-network and added new connection sample * Remove gpt-5.3-codex from staticModels array Removed gpt-5.3-codex from the list of static models. * Fix paths for architecture diagram and post-deploy script Updated the path for the architecture diagram and clarified the location of the post-deploy.sh script in the README. * Remove output suppression in post-deploy.sh Removed unnecessary output suppression for outbound PE rule submission. * Update setup-jumpbox-access.sh --------- Co-authored-by: foundry-samples automation <foundry-samples@noreply.github.com> Co-authored-by: Bala P V <33712765+balapv@users.noreply.github.com>
1 parent 4581b52 commit 7919a20

8 files changed

Lines changed: 967 additions & 41 deletions

File tree

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
/*
2+
Creates a ModelGateway connection on a Foundry project.
3+
4+
What this does:
5+
Adds a connection (of category 'ModelGateway') to a project on your LOCAL
6+
Foundry account. The connection points at the OpenAI-compatible endpoint
7+
of a REMOTE Foundry account, so model calls made against the local project
8+
are routed to model deployments hosted on the remote account.
9+
10+
Authentication uses the remote account's API key (looked up at deploy time
11+
via listKeys() — no key needs to be passed in).
12+
13+
Terminology used below:
14+
- local = the account/project where this connection resource is created
15+
(also the deployment resource group, unless overridden).
16+
- remote = the account whose model deployments will be called through
17+
the connection.
18+
19+
Deploy:
20+
az deployment group create \
21+
--subscription <subscription-id> \
22+
--resource-group <rg-of-local-account> \
23+
--template-file foundry-modelgateway-connection-apikey.bicep \
24+
--parameters \
25+
connectionName=<connection-name> \
26+
localAccountName=<local-account> \
27+
localProjectName=<local-project> \
28+
remoteAccountName=<remote-account> \
29+
remoteAccountResourceGroup=<rg-of-remote-account> # only needed if the remote account lives in a different RG than the deployment
30+
*/
31+
32+
@description('Name of the new ModelGateway connection to create on the local project. This is the name that will appear in the Foundry portal.')
33+
param connectionName string
34+
35+
@description('Name of the local Foundry (AIServices) account that hosts the project where this connection will be created. Must already exist in the deployment resource group.')
36+
param localAccountName string
37+
38+
@description('Name of the project (under the local account) that this connection will be attached to. Must already exist.')
39+
param localProjectName string
40+
41+
@description('Name of the remote Foundry (AIServices) account whose model deployments will be invoked through this connection. The connection target URL and API key are both derived from this account.')
42+
param remoteAccountName string
43+
44+
@description('Resource group of the remote Foundry account. Defaults to the deployment resource group (i.e. assumes the remote account is in the same RG as the local account). Set this explicitly only if the remote account is in a different RG — otherwise the deployment fails with ResourceNotFound when it tries to listKeys() on the remote account.')
45+
param remoteAccountResourceGroup string = resourceGroup().name
46+
47+
@description('If true, the connection is visible to every project on the local account (and shows up in the Foundry portal\'s "Admin-connected models" picker). If false, only the local project listed above can use it. Default: true.')
48+
param isSharedToAll bool = true
49+
50+
// List of Models: Edit this list of models based on what you need to expose. These models should be available on the remote account
51+
@description('List of model deployments available on the remote account that should be exposed through this connection. Each entry must match a real deployment on the remote account (same name, model name, and version). Embedding the list here lets clients resolve "<connection-name>/<deployment-name>" without an extra service lookup. Override the default to match the deployments on YOUR remote account.')
52+
param staticModels array = [
53+
{ name: 'gpt-4.1-mini' , properties: { model: { name: 'gpt-4.1-mini' , version: '2025-04-14', format: 'OpenAI' } } }
54+
{ name: 'gpt-4.1' , properties: { model: { name: 'gpt-4.1' , version: '2025-04-14', format: 'OpenAI' } } }
55+
{ name: 'gpt-5' , properties: { model: { name: 'gpt-5' , version: '2025-08-07', format: 'OpenAI' } } }
56+
{ name: 'gpt-5.1' , properties: { model: { name: 'gpt-5.1' , version: '2025-11-13', format: 'OpenAI' } } }
57+
{ name: 'gpt-5.2' , properties: { model: { name: 'gpt-5.2' , version: '2025-12-11', format: 'OpenAI' } } }
58+
{ name: 'gpt-5.2-chat' , properties: { model: { name: 'gpt-5.2-chat' , version: '2025-12-11', format: 'OpenAI' } } }
59+
{ name: 'DeepSeek-V3-0324', properties: { model: { name: 'DeepSeek-V3-0324', version: '1' , format: 'OpenAI' } } }
60+
]
61+
62+
// Target URL: the OpenAI-compatible (/openai/v1) endpoint on the remote
63+
// Foundry account. This is the same URL the Foundry portal uses when it
64+
// creates a ModelGateway connection through its UI wizard.
65+
var targetUrl = 'https://${remoteAccountName}.services.ai.azure.com/openai/v1'
66+
67+
resource localAccount 'Microsoft.CognitiveServices/accounts@2025-04-01-preview' existing = {
68+
name: localAccountName
69+
}
70+
resource localProject 'Microsoft.CognitiveServices/accounts/projects@2025-04-01-preview' existing = {
71+
name: localProjectName
72+
parent: localAccount
73+
}
74+
resource remoteAccount 'Microsoft.CognitiveServices/accounts@2025-04-01-preview' existing = {
75+
name: remoteAccountName
76+
scope: resourceGroup(remoteAccountResourceGroup)
77+
}
78+
79+
// Connection metadata. These five fields are required by the ModelGateway
80+
// connection contract — the portal wizard sets the exact same values, so do
81+
// NOT omit any of them or substitute your own without a strong reason:
82+
// - models : stringified JSON of the deployment list above; lets
83+
// the portal render the model picker and lets the
84+
// runtime resolve "<connection>/<deployment>" locally.
85+
// - deploymentInPath : 'false' = deployment name is sent in the request
86+
// body (OpenAI-style), not in the URL path.
87+
// - authHeaderName : header used to pass the API key on every call.
88+
// - authHeaderFormat : token format placed in that header. '{api_key}'
89+
// means the raw key, with no "Bearer " prefix.
90+
// - customHeaders : extra static headers to add per request. Empty by
91+
// default; must still be present as '{}' .
92+
var metadata = {
93+
models: string(staticModels)
94+
deploymentInPath: 'false'
95+
authHeaderFormat: '{api_key}'
96+
authHeaderName: 'x-api-key'
97+
customHeaders: '{}'
98+
}
99+
100+
resource connection 'Microsoft.CognitiveServices/accounts/projects/connections@2025-04-01-preview' = {
101+
name: connectionName
102+
parent: localProject
103+
properties: {
104+
category: 'ModelGateway'
105+
target: targetUrl
106+
authType: 'ApiKey'
107+
isSharedToAll: isSharedToAll
108+
credentials: {
109+
key: remoteAccount.listKeys().key1
110+
}
111+
metadata: metadata
112+
}
113+
}
114+
115+
output connectionId string = connection.id
116+
output connectionName string = connection.name
117+
output targetUrl string = targetUrl
118+
output deploymentCount int = length(staticModels)
119+
output isSharedToAll bool = isSharedToAll

0 commit comments

Comments
 (0)