Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 50 additions & 26 deletions HostedAgents/Author/azure.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,54 @@

name: blogwriter-hosted-agent-author
metadata:
template: blogwriter-hosted-agent
template: blogwriter-hosted-agent
services:
ai-project:
host: azure.ai.project
blogwriter-author:
project: .
host: azure.ai.agent
language: csharp
uses:
- ai-project
description: Drafts and revises blog posts.
codeConfiguration:
dependencyResolution: remote_build
entryPoint: BlogWriter.HostedAgents.Author.dll
runtime: dotnet_10
container:
resources:
cpu: "0.5"
memory: 1Gi
kind: hosted
name: blogwriter-author
environmentVariables:
- name: AZURE_AI_MODEL_DEPLOYMENT_NAME
value: ${AZURE_AI_MODEL_DEPLOYMENT_NAME}
protocols:
- protocol: responses
version: 2.0.0
ai-project:
host: azure.ai.project
endpoint: https://AgentFrameworkJesseLiberty.services.ai.azure.com/api/projects/AgentFramework
Comment on lines +7 to +9
author:
project: .
host: azure.ai.agent
language: csharp
uses:
- ai-project
env:
AZURE_AI_MODEL_DEPLOYMENT_NAME: ${AZURE_AI_MODEL_DEPLOYMENT_NAME}
Comment on lines +10 to +17
codeConfiguration:
dependencyResolution: remote_build
entryPoint: BlogWriter.HostedAgents.Author.dll
runtime: dotnet_10
container:
resources:
cpu: "0.5"
memory: 1Gi
kind: hosted
name: author
protocols:
- protocol: responses
version: 2.0.0
blogwriter-author:
project: .
host: azure.ai.agent
language: csharp
uses:
- ai-project
codeConfiguration:
dependencyResolution: remote_build
entryPoint: BlogWriter.HostedAgents.Author.dll
runtime: dotnet_10
container:
resources:
cpu: "0.5"
memory: 1Gi
description: Drafts and revises blog posts.
environmentVariables:
- name: AZURE_AI_MODEL_DEPLOYMENT_NAME
value: ${AZURE_AI_MODEL_DEPLOYMENT_NAME}
kind: hosted
name: blogwriter-author
protocols:
- protocol: responses
version: 2.0.0
infra:
provider: microsoft.foundry
4 changes: 4 additions & 0 deletions HostedAgents/Author/infra/abbreviations.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"cognitiveServicesAccounts": "cog-",
"containerRegistryRegistries": "cr"
}
176 changes: 176 additions & 0 deletions HostedAgents/Author/infra/main.bicep
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
// Provisioning template for a Foundry project service.
//
// Inputs are derived from the host: azure.ai.project service body in
// azure.yaml by internal/synthesis. This entry point creates a new Foundry
// account and project; existing projects use the separate editable entry point.
//
// Subscription-scoped so the resource group is part of the deployment. This
// keeps `azd provision --preview` side-effect free: the resource group shows
// up as a previewed Create instead of being created up front to satisfy a
// resource-group-scoped what-if.

targetScope = 'subscription'

// User-defined types

@description('Shape of one model deployment entry in azure.yaml.')
type deploymentsType = deploymentType[]

@description('Shape of a single model deployment.')
type deploymentType = {
name: string
model: {
name: string
format: string
version: string
}
sku: {
name: string
capacity: int
}
}

@description('Shape of a list of Foundry project connections.')
type connectionsType = connectionType[]

@description('Shape of one Foundry project connection (a host: azure.ai.connection service).')
type connectionType = {
name: string
category: string
target: string
authType: string
metadata: object?
}

// Parameters

@description('Azure region for all resources.')
param location string

@description('Name of the resource group to create and deploy resources into.')
@minLength(1)
@maxLength(90)
param resourceGroupName string

@description('Tags applied to all resources.')
param tags object = {}

@description('Optional salt to vary resource names across re-provisions.')
param resourceTokenSalt string = ''

@description('Foundry project name. 3-32 alphanumeric/hyphen chars.')
@minLength(3)
@maxLength(32)
param foundryProjectName string

@description('Model deployments to provision on the Foundry account.')
param deployments deploymentsType = []

@description('Include an Azure Container Registry. Set true when any agent uses docker:.')
param includeAcr bool = false

@description('Foundry project connections to create (host: azure.ai.connection services).')
param connections connectionsType = []

@description('Credentials keyed by Foundry project connection name.')
@secure()
param connectionCredentials object = {}

@description('Object id of the developer running azd. When set, grants Cognitive Services User on the project. Empty disables the role assignment so headless / CI runs do not fail.')
param principalId string = ''

@description('Principal type used in the developer role assignment.')
param principalType string = 'User'

// Network isolation parameters (see modules/resources.bicep for semantics).
// All default off so an absent network: block yields a public account.

@description('Master switch: when true the account is VNet-bound (private).')
param enableNetworkIsolation bool = false

@description('When true (and isolation on), the agent runtime uses the Microsoft-managed network instead of injecting into a customer subnet.')
param useManagedEgress bool = false

@description('ARM id of the existing customer VNet (byo mode).')
param vnetId string = ''

@description('Agent (delegated) subnet name.')
param agentSubnetName string = 'agent-subnet'

@description('Agent subnet CIDR. Empty derives a /24 from the VNet space.')
param agentSubnetPrefix string = ''

@description('When true, create the agent subnet; when false, reference it.')
param createAgentSubnet bool = false

@description('Private-endpoint subnet name.')
param peSubnetName string = 'pe-subnet'

@description('Private-endpoint subnet CIDR. Empty derives a /24 from the VNet space.')
param peSubnetPrefix string = ''

@description('When true, create the PE subnet; when false, reference it.')
param createPESubnet bool = false

@description('Managed-network isolation mode (managed mode).')
param managedIsolationMode string = ''

@description('Resource group holding existing private DNS zones. Empty creates new zones.')
param dnsZonesResourceGroup string = ''

@description('Subscription holding existing private DNS zones. Empty defaults to this subscription.')
param dnsZonesSubscription string = ''

// Resources

resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = {
name: resourceGroupName
location: location
tags: tags
}

module resources 'modules/resources.bicep' = {
name: 'foundry-resources'
scope: resourceGroup
params: {
location: location
tags: tags
resourceTokenSalt: resourceTokenSalt
foundryProjectName: foundryProjectName
deployments: deployments
includeAcr: includeAcr
connections: connections
connectionCredentials: connectionCredentials
principalId: principalId
principalType: principalType
enableNetworkIsolation: enableNetworkIsolation
useManagedEgress: useManagedEgress
vnetId: vnetId
agentSubnetName: agentSubnetName
agentSubnetPrefix: agentSubnetPrefix
createAgentSubnet: createAgentSubnet
peSubnetName: peSubnetName
peSubnetPrefix: peSubnetPrefix
createPESubnet: createPESubnet
managedIsolationMode: managedIsolationMode
dnsZonesResourceGroup: dnsZonesResourceGroup
dnsZonesSubscription: dnsZonesSubscription
}
}

// Outputs

output AZURE_RESOURCE_GROUP string = resourceGroupName
output AZURE_FOUNDRY_RESOURCE_GROUP string = resourceGroupName
output AZURE_AI_PROJECT_ID string = resources.outputs.AZURE_AI_PROJECT_ID
output AZURE_AI_ACCOUNT_NAME string = resources.outputs.AZURE_AI_ACCOUNT_NAME
output AZURE_AI_PROJECT_NAME string = resources.outputs.AZURE_AI_PROJECT_NAME
output AZURE_OPENAI_ENDPOINT string = resources.outputs.AZURE_OPENAI_ENDPOINT
output FOUNDRY_PROJECT_ENDPOINT string = resources.outputs.FOUNDRY_PROJECT_ENDPOINT
output AZURE_CONTAINER_REGISTRY_ENDPOINT string = resources.outputs.AZURE_CONTAINER_REGISTRY_ENDPOINT
output AZURE_CONTAINER_REGISTRY_RESOURCE_ID string = resources.outputs.AZURE_CONTAINER_REGISTRY_RESOURCE_ID
output AZURE_AI_PROJECT_ACR_CONNECTION_NAME string = resources.outputs.AZURE_AI_PROJECT_ACR_CONNECTION_NAME
output AZURE_AI_PROJECT_CONNECTION_NAMES string = resources.outputs.AZURE_AI_PROJECT_CONNECTION_NAMES
output AZURE_AI_PROJECT_CONNECTIONS_PROJECT_ENDPOINT string = resources.outputs.FOUNDRY_PROJECT_ENDPOINT
output AZURE_FOUNDRY_NETWORK_MODE string = resources.outputs.AZURE_FOUNDRY_NETWORK_MODE
output AZURE_FOUNDRY_MANAGED_ISOLATION_MODE string = resources.outputs.AZURE_FOUNDRY_MANAGED_ISOLATION_MODE
54 changes: 54 additions & 0 deletions HostedAgents/Author/infra/main.parameters.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"agentSubnetName": {
"value": "agent-subnet"
},
"agentSubnetPrefix": {
"value": ""
},
"connectionCredentials": {
"value": {}
},
"connections": {
"value": []
},
"createAgentSubnet": {
"value": false
},
"createPESubnet": {
"value": false
},
"deployments": {
"value": []
},
"dnsZonesResourceGroup": {
"value": ""
},
"dnsZonesSubscription": {
"value": ""
},
"enableNetworkIsolation": {
"value": false
},
"includeAcr": {
"value": false
},
"managedIsolationMode": {
"value": ""
},
"peSubnetName": {
"value": "pe-subnet"
},
"peSubnetPrefix": {
"value": ""
},
"useManagedEgress": {
"value": false
},
"vnetId": {
"value": ""
}
}
}
24 changes: 24 additions & 0 deletions HostedAgents/Author/infra/modules/acr-pull-role-assignment.bicep
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
targetScope = 'resourceGroup'

@description('Name of the Azure Container Registry.')
param registryName string

@description('Principal receiving AcrPull on the registry.')
param principalId string

@description('AcrPull role definition resource ID.')
param roleDefinitionId string

resource registry 'Microsoft.ContainerRegistry/registries@2023-07-01' existing = {
name: registryName
}

resource acrPull 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(registry.id, principalId, roleDefinitionId)
scope: registry
properties: {
principalId: principalId
principalType: 'ServicePrincipal'
roleDefinitionId: roleDefinitionId
}
}
Loading