Commit becb48e
Resolve cross-compute-environment endpoint references for Foundry hosted agents (#17756)
* Resolve cross-compute-environment endpoint references to Foundry hosted agents
Fixes #17749. When a resource deployed to App Service, Azure Container
Apps, or Kubernetes used WithReference() to reference a Foundry hosted
agent, publishing failed because the publisher resolved the endpoint
against its own local endpoint map, which does not contain the agent
(deployed to the Foundry project compute environment).
Introduce a shared ComputeEnvironmentEndpointResolver that, when an
endpoint's owning resource is deployed to a different compute environment
than the current publisher, delegates resolution to that owning
environment's GetEndpointPropertyExpression. The three compute-environment
publishers now call it in both the EndpointReference and
EndpointReferenceExpression branches. Azure Front Door and the Foundry
hosted-agent resolver are refactored onto the same shared lookup.
AzureCognitiveServicesProjectResource gets a GetEndpointPropertyExpression
override because the agent address is already a full https URL; the
default scheme://host composition would produce a malformed double-scheme
value.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Add branch tests for ComputeEnvironmentEndpointResolver and correct misleading comment
Add direct unit tests covering each branch of TryGetCrossEnvironmentEndpointExpression:
cross-environment delegation, same-environment deployment target, WithComputeEnvironment
binding backstop, no-compute-environment, bound multi-target (no throw), and unbound
multi-target (throws). Correct the comment on the fast-path loop which incorrectly claimed
it never throws on multi-target resources.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Remove redundant fast-path loop from ComputeEnvironmentEndpointResolver
The first foreach loop using GetDeploymentTargetAnnotation(current) was redundant with
TryGetEffectiveComputeEnvironment + the ReferenceEquals backstop for all well-formed inputs,
and did not provide multi-target throw-safety. Remove it and keep the simpler resolve-then-
compare flow. All six branch tests continue to pass.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Drop params and move out parameter last in cross-env endpoint resolver
Replace the params IComputeEnvironmentResource?[] with an explicit
IReadOnlyList parameter placed before the out, so the out parameter
comes last per convention. Kubernetes still passes two current
environments (its environment plus OwningComputeEnvironment) via a
collection expression; ACA and AppService pass a single-element list.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Add EndpointReference overload for cross-env endpoint resolver
Add an overload taking EndpointReference that uses ep.Property(EndpointProperty.Url)
internally, so the three EndpointReference call sites (ACA, AppService, Kubernetes)
pass the endpoint directly instead of repeating the .Property(Url) projection.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Use hosted-agent deployment name in cross-env Foundry agent URL
Hosted-agent deployment creates the Foundry agent version using the
wrapper AzureHostedAgentResource.Name (e.g. "agent-ha" for a target
named "agent"). The published cross-environment endpoint path was built
from the bare resource name, producing /agents/agent which does not match
the deployed /agents/agent-ha. Resolve the hosted-agent deployment target
and use its name when present, falling back to the resource name for
non-hosted agents.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Auto-wire Azure AI User role for hosted-agent consumers
When a compute resource references a Foundry hosted agent's node app via
WithReference, automatically grant the consumer the Azure AI User role on the
owning Foundry account and provision a managed identity, removing the two manual
post-deploy `az role assignment create` steps.
Introduces a public, experimental ReferenceRoleAssignmentAnnotation in
Aspire.Hosting.Azure. A resource that "fronts" an Azure resource (without being
an IAzureResource itself) carries this annotation; AzureResourcePreparer folds
its (Target, Roles) into the same role-assignment path used for direct Azure
references. Foundry's AsHostedAgent stamps the annotation on the agent's node
app granting only the least-privilege Azure AI User role; account defaults and
explicit WithRoleAssignments suppression remain owned by the preparer and are
not reintroduced. GetAllRoleAssignments now dedupes roles per target to avoid
colliding bicep role-assignment identifiers.
Adds preparer end-to-end tests (suppression preserved, defaults preserved,
dedup) and Foundry stamp tests.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Regenerate cross-env Foundry snapshots for RBAC auto-wiring
The cross-compute-environment Foundry hosted-agent snapshots were committed
before the RBAC auto-wiring change and never regenerated. With the consumer
now receiving a managed identity (web-identity) plus AZURE_CLIENT_ID and
AZURE_TOKEN_CREDENTIALS env vars, the generated bicep/json changed. CI failed
because the verified baselines were stale; local runs masked it because Verify
auto-accepts on developer machines.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>1 parent e138509 commit becb48e
26 files changed
Lines changed: 1264 additions & 25 deletions
File tree
- src
- Aspire.Hosting.Azure.AppContainers
- Aspire.Hosting.Azure.AppService
- Aspire.Hosting.Azure.FrontDoor
- Aspire.Hosting.Azure
- Aspire.Hosting.Foundry
- HostedAgent
- Project
- Aspire.Hosting.Kubernetes
- tests
- Aspire.Hosting.Azure.Kubernetes.Tests
- Aspire.Hosting.Azure.Tests
- Snapshots
- Aspire.Hosting.Foundry.Tests
- Aspire.Hosting.Tests
Lines changed: 1 addition & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
| 14 | + | |
14 | 15 | | |
15 | 16 | | |
16 | 17 | | |
| |||
Lines changed: 15 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
222 | 222 | | |
223 | 223 | | |
224 | 224 | | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
225 | 234 | | |
226 | 235 | | |
227 | 236 | | |
| |||
274 | 283 | | |
275 | 284 | | |
276 | 285 | | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
277 | 292 | | |
278 | 293 | | |
279 | 294 | | |
| |||
Lines changed: 1 addition & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
| 16 | + | |
16 | 17 | | |
17 | 18 | | |
18 | 19 | | |
| |||
Lines changed: 15 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
167 | 167 | | |
168 | 168 | | |
169 | 169 | | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
170 | 179 | | |
171 | 180 | | |
172 | 181 | | |
| |||
206 | 215 | | |
207 | 216 | | |
208 | 217 | | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
209 | 224 | | |
210 | 225 | | |
211 | 226 | | |
| |||
Lines changed: 4 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
15 | 15 | | |
16 | 16 | | |
17 | 17 | | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
18 | 22 | | |
19 | 23 | | |
20 | 24 | | |
| |||
Lines changed: 1 addition & 6 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
201 | 201 | | |
202 | 202 | | |
203 | 203 | | |
204 | | - | |
| 204 | + | |
205 | 205 | | |
206 | 206 | | |
207 | 207 | | |
208 | 208 | | |
209 | | - | |
210 | | - | |
211 | | - | |
212 | | - | |
213 | | - | |
214 | 209 | | |
215 | 210 | | |
216 | 211 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
133 | 133 | | |
134 | 134 | | |
135 | 135 | | |
136 | | - | |
| 136 | + | |
| 137 | + | |
137 | 138 | | |
138 | 139 | | |
139 | 140 | | |
| |||
184 | 185 | | |
185 | 186 | | |
186 | 187 | | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
187 | 224 | | |
188 | 225 | | |
189 | 226 | | |
| |||
250 | 287 | | |
251 | 288 | | |
252 | 289 | | |
253 | | - | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
254 | 296 | | |
255 | 297 | | |
256 | 298 | | |
| |||
359 | 401 | | |
360 | 402 | | |
361 | 403 | | |
362 | | - | |
363 | | - | |
364 | | - | |
365 | | - | |
366 | | - | |
367 | | - | |
368 | | - | |
369 | | - | |
370 | | - | |
371 | | - | |
372 | | - | |
373 | | - | |
374 | | - | |
375 | 404 | | |
376 | 405 | | |
377 | 406 | | |
| |||
Lines changed: 43 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
23 | 23 | | |
24 | 24 | | |
25 | 25 | | |
| 26 | + | |
26 | 27 | | |
27 | 28 | | |
28 | 29 | | |
| |||
Lines changed: 5 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
25 | 25 | | |
26 | 26 | | |
27 | 27 | | |
28 | | - | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
29 | 32 | | |
30 | 33 | | |
31 | 34 | | |
| |||
429 | 432 | | |
430 | 433 | | |
431 | 434 | | |
432 | | - | |
433 | | - | |
| 435 | + | |
434 | 436 | | |
435 | 437 | | |
436 | 438 | | |
| |||
0 commit comments