@@ -22,23 +22,14 @@ var appServicePlanName = 'az-${resourcePrefix}-plan-${resourceToken}'
2222// App Service name
2323var appServiceName = 'az-${resourcePrefix }-app-${resourceToken }'
2424
25- // Azure AI Hub name
26- var aiHubName = 'az-${resourcePrefix }-hub -${resourceToken }'
25+ // Azure AI Foundry resource name
26+ var aiFoundryResourceName = 'az-${resourcePrefix }-foundry -${resourceToken }'
2727
28- // Azure AI Project name
29- var aiProjectName = 'az-${resourcePrefix }-project-${resourceToken }'
30-
31- // Azure OpenAI account name
32- var openAIAccountName = 'az-${resourcePrefix }-openai-${resourceToken }'
33-
34- // Storage account name (required for AI Hub)
35- var storageAccountName = 'az${resourcePrefix }st${take (resourceToken , 8 )}'
36-
37- // Key Vault name (required for AI Hub)
38- var keyVaultName = 'az-${resourcePrefix }-kv-${take (resourceToken , 8 )}'
28+ // Azure AI Foundry project name
29+ var aiFoundryProjectName = 'az-${resourcePrefix }-project-${resourceToken }'
3930
4031// Create App Service Plan (P0V3 Linux)
41- resource appServicePlan 'Microsoft.Web/serverfarms@2024-04 -01' = {
32+ resource appServicePlan 'Microsoft.Web/serverfarms@2023-12 -01' = {
4233 name : appServicePlanName
4334 location : location
4435 tags : {
@@ -57,8 +48,64 @@ resource appServicePlan 'Microsoft.Web/serverfarms@2024-04-01' = {
5748 kind : 'linux'
5849}
5950
51+ // Create Azure AI Foundry resource
52+ resource aiFoundryResource 'Microsoft.CognitiveServices/accounts@2025-04-01-preview' = {
53+ name : aiFoundryResourceName
54+ location : location
55+ tags : {
56+ 'azd-env-name' : environmentName
57+ }
58+ kind : 'AIServices'
59+ sku : {
60+ name : 'S0'
61+ }
62+ identity : {
63+ type : 'SystemAssigned'
64+ }
65+ properties : {
66+ // Required to work in AI Foundry
67+ allowProjectManagement : true
68+ customSubDomainName : aiFoundryResourceName
69+ publicNetworkAccess : 'Enabled'
70+ disableLocalAuth : false
71+ }
72+ }
73+
74+ // Create Azure AI Foundry project
75+ resource aiFoundryProject 'Microsoft.CognitiveServices/accounts/projects@2025-04-01-preview' = {
76+ parent : aiFoundryResource
77+ name : aiFoundryProjectName
78+ location : location
79+ tags : {
80+ 'azd-env-name' : environmentName
81+ }
82+ identity : {
83+ type : 'SystemAssigned'
84+ }
85+ properties : {}
86+ }
87+
88+ // Create GPT-4o deployment on the AI Foundry resource
89+ resource gpt4oDeployment 'Microsoft.CognitiveServices/accounts/deployments@2024-06-01-preview' = {
90+ parent : aiFoundryResource
91+ name : 'gpt-4o'
92+ sku : {
93+ name : 'GlobalStandard'
94+ capacity : 50
95+ }
96+ properties : {
97+ model : {
98+ format : 'OpenAI'
99+ name : 'gpt-4o'
100+ version : '2024-11-20'
101+ }
102+ versionUpgradeOption : 'OnceCurrentVersionExpired'
103+ raiPolicyName : 'Microsoft.DefaultV2'
104+ }
105+ }
106+
60107// Create App Service
61- resource appService 'Microsoft.Web/sites@2024-04 -01' = {
108+ resource appService 'Microsoft.Web/sites@2023-12 -01' = {
62109 name : appServiceName
63110 location : location
64111 tags : {
@@ -100,19 +147,19 @@ resource appService 'Microsoft.Web/sites@2024-04-01' = {
100147 }
101148 {
102149 name : 'AZURE_OPENAI_ENDPOINT'
103- value : openAIAccount .properties .endpoint
150+ value : aiFoundryResource .properties .endpoint
104151 }
105152 {
106153 name : 'AZURE_OPENAI_DEPLOYMENT_NAME'
107- value : gpt41MiniDeployment .name
154+ value : gpt4oDeployment .name
108155 }
109156 {
110157 name : 'AZURE_AI_MODEL_DEPLOYMENT_NAME'
111- value : gpt41MiniDeployment .name
158+ value : gpt4oDeployment .name
112159 }
113160 {
114161 name : 'AZURE_AI_PROJECT_ENDPOINT'
115- value : '${ location }.api.azureml.ms;${ subscription (). subscriptionId };${ resourceGroup (). name };${ aiProject . name }'
162+ value : aiFoundryResource . properties . endpoint
116163 }
117164 {
118165 name : 'AZURE_APP_SERVICE_URL'
@@ -128,190 +175,27 @@ resource appService 'Microsoft.Web/sites@2024-04-01' = {
128175 }
129176}
130177
131- // Create Storage Account (required for AI Hub)
132- resource storageAccount 'Microsoft.Storage/storageAccounts@2023-05-01' = {
133- name : storageAccountName
134- location : location
135- tags : {
136- 'azd-env-name' : environmentName
137- }
138- sku : {
139- name : 'Standard_LRS'
140- }
141- kind : 'StorageV2'
142- properties : {
143- accessTier : 'Hot'
144- allowBlobPublicAccess : false
145- allowSharedKeyAccess : false
146- minimumTlsVersion : 'TLS1_2'
147- }
148- }
149-
150- // Create Key Vault (required for AI Hub)
151- resource keyVault 'Microsoft.KeyVault/vaults@2023-07-01' = {
152- name : keyVaultName
153- location : location
154- tags : {
155- 'azd-env-name' : environmentName
156- }
157- properties : {
158- sku : {
159- family : 'A'
160- name : 'standard'
161- }
162- tenantId : tenant ().tenantId
163- enableRbacAuthorization : true
164- enableSoftDelete : true
165- enablePurgeProtection : true
166- accessPolicies : []
167- }
168- }
169-
170- // Create Azure OpenAI Account
171- resource openAIAccount 'Microsoft.CognitiveServices/accounts@2024-10-01' = {
172- name : openAIAccountName
173- location : location
174- tags : {
175- 'azd-env-name' : environmentName
176- }
177- kind : 'OpenAI'
178- sku : {
179- name : 'S0'
180- }
181- identity : {
182- type : 'SystemAssigned'
183- }
184- properties : {
185- customSubDomainName : openAIAccountName
186- publicNetworkAccess : 'Enabled'
187- disableLocalAuth : false
188- }
189- }
190-
191- // Create GPT-4.1-mini deployment
192- resource gpt41MiniDeployment 'Microsoft.CognitiveServices/accounts/deployments@2024-10-01' = {
193- parent : openAIAccount
194- name : 'gpt-4-1-mini'
195- sku : {
196- name : 'GlobalStandard'
197- capacity : 150
198- }
199- properties : {
200- model : {
201- format : 'OpenAI'
202- name : 'gpt-4.1-mini'
203- version : '2025-04-14'
204- }
205- versionUpgradeOption : 'OnceCurrentVersionExpired'
206- raiPolicyName : 'Microsoft.DefaultV2'
207- }
208- }
209-
210- // Create Azure AI Hub (workspace)
211- resource aiHub 'Microsoft.MachineLearningServices/workspaces@2024-10-01' = {
212- name : aiHubName
213- location : location
214- tags : {
215- 'azd-env-name' : environmentName
216- }
217- identity : {
218- type : 'SystemAssigned'
219- }
220- sku : {
221- name : 'Basic'
222- }
223- kind : 'Hub'
224- properties : {
225- friendlyName : 'Todo MCP AI Hub'
226- description : 'AI Hub for Todo MCP Agent chat functionality'
227- keyVault : keyVault .id
228- storageAccount : storageAccount .id
229- hbiWorkspace : false
230- publicNetworkAccess : 'Enabled'
231- }
232- }
233-
234- // Create Azure AI Project
235- resource aiProject 'Microsoft.MachineLearningServices/workspaces@2024-10-01' = {
236- name : aiProjectName
237- location : location
238- tags : {
239- 'azd-env-name' : environmentName
240- }
241- identity : {
242- type : 'SystemAssigned'
243- }
244- sku : {
245- name : 'Basic'
246- }
247- kind : 'Project'
248- properties : {
249- friendlyName : 'Todo MCP AI Project'
250- description : 'AI Project for Todo MCP Agent chat functionality'
251- hubResourceId : aiHub .id
252- publicNetworkAccess : 'Enabled'
253- }
254- }
255-
256- // Create AI Hub connection to Azure OpenAI
257- resource aiHubOpenAIConnection 'Microsoft.MachineLearningServices/workspaces/connections@2024-10-01' = {
258- parent : aiHub
259- name : 'openai-connection'
260- properties : {
261- authType : 'AAD'
262- category : 'AzureOpenAI'
263- target : openAIAccount .properties .endpoint
264- metadata : {
265- ApiType : 'Azure'
266- ResourceId : openAIAccount .id
267- }
268- }
269- }
270-
271- // Grant App Service access to OpenAI
272- resource appServiceOpenAIRole 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
273- name : guid (subscription ().id , appService .id , openAIAccount .id , 'CognitiveServicesOpenAIUser' )
274- scope : openAIAccount
178+ // Grant App Service access to Azure AI Foundry
179+ resource appServiceAIFoundryRole 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
180+ name : guid (subscription ().id , appService .id , aiFoundryResource .id , 'CognitiveServicesOpenAIUser' )
181+ scope : aiFoundryResource
275182 properties : {
276183 roleDefinitionId : subscriptionResourceId ('Microsoft.Authorization/roleDefinitions' , '5e0bd9bd-7b93-4f28-af87-19fc36ad61bd' ) // Cognitive Services OpenAI User
277184 principalId : appService .identity .principalId
278185 principalType : 'ServicePrincipal'
279186 }
280187}
281188
282- // Grant App Service access to AI Project
283- resource appServiceAIProjectRole 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
284- name : guid (subscription ().id , appService .id , aiProject .id , 'AzureMLDataScientist' )
285- scope : aiProject
189+ // Grant App Service Azure AI Developer role (required for Agents)
190+ resource appServiceAIDeveloperRole 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
191+ name : guid (subscription ().id , appService .id , 'AzureAIDeveloper' )
286192 properties : {
287- roleDefinitionId : subscriptionResourceId ('Microsoft.Authorization/roleDefinitions' , 'f6c7c914-8db3-469d-8ca1-694a8f32e121 ' ) // AzureML Data Scientist
193+ roleDefinitionId : subscriptionResourceId ('Microsoft.Authorization/roleDefinitions' , '64702f94-c441-49e6-a78b-ef80e0188fee ' ) // Azure AI Developer
288194 principalId : appService .identity .principalId
289195 principalType : 'ServicePrincipal'
290196 }
291197}
292198
293- // Grant AI Hub access to OpenAI (for Azure AI Foundry integration)
294- resource aiHubOpenAIRole 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
295- name : guid (subscription ().id , aiHub .id , openAIAccount .id , 'CognitiveServicesOpenAIContributor' )
296- scope : openAIAccount
297- properties : {
298- roleDefinitionId : subscriptionResourceId ('Microsoft.Authorization/roleDefinitions' , 'a001fd3d-188f-4b5d-821b-7da978bf7442' ) // Cognitive Services OpenAI Contributor
299- principalId : aiHub .identity .principalId
300- principalType : 'ServicePrincipal'
301- }
302- }
303-
304- // Grant AI Project access to OpenAI (for Azure AI Foundry integration)
305- resource aiProjectOpenAIRole 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
306- name : guid (subscription ().id , aiProject .id , openAIAccount .id , 'CognitiveServicesOpenAIContributor' )
307- scope : openAIAccount
308- properties : {
309- roleDefinitionId : subscriptionResourceId ('Microsoft.Authorization/roleDefinitions' , 'a001fd3d-188f-4b5d-821b-7da978bf7442' ) // Cognitive Services OpenAI Contributor
310- principalId : aiProject .identity .principalId
311- principalType : 'ServicePrincipal'
312- }
313- }
314-
315199// Outputs
316200output RESOURCE_GROUP_ID string = resourceGroup ().id
317201output AZURE_LOCATION string = location
@@ -320,9 +204,8 @@ output AZURE_RESOURCE_GROUP string = resourceGroup().name
320204output SERVICE_WEB_NAME string = appService .name
321205output SERVICE_WEB_URI string = 'https://${appService .properties .defaultHostName }'
322206output SERVICE_TODO_APP_IDENTITY_PRINCIPAL_ID string = appService .identity .principalId
323- output AZURE_OPENAI_ENDPOINT string = openAIAccount .properties .endpoint
324- output AZURE_OPENAI_NAME string = openAIAccount .name
325- output AZURE_AI_PROJECT_ENDPOINT string = '${location }.api.azureml.ms;${subscription ().subscriptionId };${resourceGroup ().name };${aiProject .name }'
326- output AZURE_AI_PROJECT_NAME string = aiProject .name
327- output AZURE_AI_HUB_NAME string = aiHub .name
328- output AZURE_OPENAI_DEPLOYMENT_NAME string = gpt41MiniDeployment .name
207+ output AZURE_OPENAI_ENDPOINT string = aiFoundryResource .properties .endpoint
208+ output AZURE_OPENAI_NAME string = aiFoundryResource .name
209+ output AZURE_AI_PROJECT_ENDPOINT string = aiFoundryResource .properties .endpoint
210+ output AZURE_AI_FOUNDRY_RESOURCE_NAME string = aiFoundryResource .name
211+ output AZURE_OPENAI_DEPLOYMENT_NAME string = gpt4oDeployment .name
0 commit comments