Skip to content

fix: Resolve existing resource symbolic references to malformed mocks - #3921

Open
Jerome Brown (oWretch) wants to merge 3 commits into
Azure:mainfrom
oWretch:owretch-improved-couscous
Open

Jerome Brown (oWretch) wants to merge 3 commits into
Azure:mainfrom
oWretch:owretch-improved-couscous

Conversation

@oWretch

Copy link
Copy Markdown
Contributor

Summary

  • Fixes cross-scope existing resource references via symbolic names in ARM JSON generated from Bicep languageVersion 2.0 templates.
  • Allows unresolved/mock arrays to flow through concat() consistently with map() and union() during pre-flight expansion.
  • Adds regression coverage for both symbolic-name and resolved resource ID reference forms.

Fixes #3920.

Base

This PR is based on #3908 (fix: Add typed CIDR placeholders for unresolved address prefixes) for clarity. Until #3908 is merged, GitHub may show those underlying changes in this PR because the #3908 source branch lives on the fork and cannot be selected as the base branch for an upstream PR.

Validation

  • Full test suite passed locally: 404/404 tests.

@oWretch
Jerome Brown (oWretch) requested a review from a team as a code owner September 16, 2026 00:43
When address prefixes are allocated at deployment time, such as by Azure
Virtual Network Manager IPAM pools, `reference()` cannot resolve them
during Bicep expansion. The empty result was then passed to `cidrHost()`
and `cidrSubnet()`, which failed with "The specified CIDR '' is not valid".

Add a source-aware placeholder table keyed on resource type and normalized
property path, so unresolved properties return a typed mock value instead
of an empty one. Placeholders use RFC 5737 TEST-NET-1 (192.0.2.0/24) so
they are obvious in output and cannot collide with real address space.

Covered today:

- `Microsoft.Network/virtualNetworks` - `addressSpace.addressPrefixes`
- `Microsoft.Network/virtualNetworks/subnets` - `addressPrefix`, `addressPrefixes`
- `Microsoft.Network/networkManagers/ipamPools` - `addressPrefixes`

The table is the extension point, so additional resource properties can be
added without further changes to the expansion code.

The `cidr*()` functions are deliberately left strict. Only indexed access
into a placeholder array yields a CIDR string, so genuine authoring
mistakes, such as passing `id` or an unindexed `addressPrefixes`, still
fail as before.

Fixes Azure#3907

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Cross-scope `existing` resources referenced via symbolic name
(languageVersion 2.0) were resolved to a malformed mock because they
were only registered via context.AddSymbol() and never via
context.AddResource(), so TemplateContext.TryGetResource fell through
to a fallback that used the raw unresolved symbolic name instead of
the resolved resource ID.

Retain the actual IResourceValue on ObjectDeploymentSymbol and
ArrayDeploymentSymbol via a new IDeploymentSymbol.GetResource(index),
and have TryGetResource resolve existing resources directly from the
retained value instead of the resourceId lookup table.

Also fixes a related bug in Functions.Concat that prevented mock
array properties (Mock.MockUnknownObject) from being consumed like
Map/Union already do via ExpressionHelpers.TryArray, and a
double-mutation bug introduced while fixing that, where Concat called
TryArray twice on the same argument, causing the underlying JToken to
be detached by the first Replace() and then fail on the second with
"The parent is missing".

Fixes Azure#3920

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant