Skip to content

{App Service} az webapp deploy: cache SCM URL and headers within a …#33560

Open
naveedaz wants to merge 1 commit into
Azure:devfrom
naveedaz:fix/appservice-cache-scm-headers-onedeploy
Open

{App Service} az webapp deploy: cache SCM URL and headers within a …#33560
naveedaz wants to merge 1 commit into
Azure:devfrom
naveedaz:fix/appservice-cache-scm-headers-onedeploy

Conversation

@naveedaz

@naveedaz naveedaz commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Related command

az webapp deploy, az functionapp deploy

Description

az webapp deploy and az functionapp deploy issue ~12 redundant ARM calls per invocation. Most duplication comes from helpers that independently fetch the same Site model, SCM URL, publishing credentials, and is_flex status:

  • _get_scm_url fetches GET /sites to resolve the SCM hostname — called twice (publish URL + status URL).
  • get_scm_site_headers runs is_flex_functionapp + basic_auth_supported + _get_site_credential — called twice (publish POST + status poll), wasting 3+ ARM calls each time.

This PR hoists per-invocation state onto OneDeployParams:

  1. Eager Site fetch — fetch the Site model once, cache on _cached_site. Derive SCM URL (from host_name_ssl_states), is_linux (from reserved), is_flex (from sku), and visit URL (from enabled_host_names) — zero additional ARM calls.
  2. SCM headers cache — cache get_scm_site_headers result on _cached_scm_headers. Reused by status poller, Kudu warmup, and _get_latest_deployment_id. On HTTP 401 the cache is dropped and headers are refetched once.
  3. Security_cached_scm_headers is cleared in a finally block so basic-auth credentials cannot outlive the invocation.
  4. Case-insensitive auth keyurllib3.util.make_headers(basic_auth=...) returns lowercase 'authorization'; AAD uses 'Authorization'. Cache population handles both via case-insensitive key matching.

ARM call reduction (verified via E2E)

Scenario Before After
Linux webapp (AAD) ~12 3 (GET /sites, GET basicPub/scm, GET instances)
Consumption function app ~8 2 (GET /sites, GET basicPub/scm)
Flex function app ~6 1 (GET /sites)

Testing Guide

Deploy with --debug and count Request URL:.*management.azure.com lines (excluding deploymentStatus polling):

az webapp deploy -g <rg> -n <app> --src-path <zip> --type zip --debug

Unit tests: 160 tests covering cache lifecycle, SCM URL derivation from host_name_ssl_states, slot awareness, is_flex hint from cached SKU, header caching, and cache cleanup on success/exception.

History Notes

[App Service] az webapp deploy/az functionapp deploy: Reduce per-deploy ARM calls from ~12 to ~3 by caching the Site model, SCM URL, and SCM authentication headers for the lifetime of a single deploy invocation

@azure-client-tools-bot-prd

azure-client-tools-bot-prd Bot commented Jun 16, 2026

Copy link
Copy Markdown
️✔️AzureCLI-FullTest
️✔️acr
️✔️latest
️✔️3.12
️✔️3.14
️✔️acs
️✔️latest
️✔️3.12
️✔️3.14
️✔️advisor
️✔️latest
️✔️3.12
️✔️3.14
️✔️ams
️✔️latest
️✔️3.12
️✔️3.14
️✔️apim
️✔️latest
️✔️3.12
️✔️3.14
️✔️appconfig
️✔️latest
️✔️3.12
️✔️3.14
️✔️appservice
️✔️latest
️✔️3.12
️✔️3.14
️✔️aro
️✔️latest
️✔️3.12
️✔️3.14
️✔️backup
️✔️latest
️✔️3.12
️✔️3.14
️✔️batch
️✔️latest
️✔️3.12
️✔️3.14
️✔️batchai
️✔️latest
️✔️3.12
️✔️3.14
️✔️billing
️✔️latest
️✔️3.12
️✔️3.14
️✔️botservice
️✔️latest
️✔️3.12
️✔️3.14
️✔️cdn
️✔️latest
️✔️3.12
️✔️3.14
️✔️cloud
️✔️latest
️✔️3.12
️✔️3.14
️✔️cognitiveservices
️✔️latest
️✔️3.12
️✔️3.14
️✔️compute_recommender
️✔️latest
️✔️3.12
️✔️3.14
️✔️computefleet
️✔️latest
️✔️3.12
️✔️3.14
️✔️config
️✔️latest
️✔️3.12
️✔️3.14
️✔️configure
️✔️latest
️✔️3.12
️✔️3.14
️✔️consumption
️✔️latest
️✔️3.12
️✔️3.14
️✔️container
️✔️latest
️✔️3.12
️✔️3.14
️✔️containerapp
️✔️latest
️✔️3.12
️✔️3.14
️✔️core
️✔️latest
️✔️3.12
️✔️3.14
️✔️cosmosdb
️✔️latest
️✔️3.12
️✔️3.14
️✔️databoxedge
️✔️latest
️✔️3.12
️✔️3.14
️✔️dls
️✔️latest
️✔️3.12
️✔️3.14
️✔️dms
️✔️latest
️✔️3.12
️✔️3.14
️✔️eventgrid
️✔️latest
️✔️3.12
️✔️3.14
️✔️eventhubs
️✔️latest
️✔️3.12
️✔️3.14
️✔️feedback
️✔️latest
️✔️3.12
️✔️3.14
️✔️find
️✔️latest
️✔️3.12
️✔️3.14
️✔️hdinsight
️✔️latest
️✔️3.12
️✔️3.14
️✔️identity
️✔️latest
️✔️3.12
️✔️3.14
️✔️iot
️✔️latest
️✔️3.12
️✔️3.14
️✔️keyvault
️✔️latest
️✔️3.12
️✔️3.14
️✔️lab
️✔️latest
️✔️3.12
️✔️3.14
️✔️managedservices
️✔️latest
️✔️3.12
️✔️3.14
️✔️maps
️✔️latest
️✔️3.12
️✔️3.14
️✔️marketplaceordering
️✔️latest
️✔️3.12
️✔️3.14
️✔️monitor
️✔️latest
️✔️3.12
️✔️3.14
️✔️mysql
️✔️latest
️✔️3.12
️✔️3.14
️✔️netappfiles
️✔️latest
️✔️3.12
️✔️3.14
️✔️network
️✔️latest
️✔️3.12
️✔️3.14
️✔️policyinsights
️✔️latest
️✔️3.12
️✔️3.14
️✔️postgresql
️✔️latest
️✔️3.12
️✔️3.14
️✔️privatedns
️✔️latest
️✔️3.12
️✔️3.14
️✔️profile
️✔️latest
️✔️3.12
️✔️3.14
️✔️rdbms
️✔️latest
️✔️3.12
️✔️3.14
️✔️redis
️✔️latest
️✔️3.12
️✔️3.14
️✔️relay
️✔️latest
️✔️3.12
️✔️3.14
️✔️resource
️✔️latest
️✔️3.12
️✔️3.14
️✔️role
️✔️latest
️✔️3.12
️✔️3.14
️✔️search
️✔️latest
️✔️3.12
️✔️3.14
️✔️security
️✔️latest
️✔️3.12
️✔️3.14
️✔️servicebus
️✔️latest
️✔️3.12
️✔️3.14
️✔️serviceconnector
️✔️latest
️✔️3.12
️✔️3.14
️✔️servicefabric
️✔️latest
️✔️3.12
️✔️3.14
️✔️signalr
️✔️latest
️✔️3.12
️✔️3.14
️✔️sql
️✔️latest
️✔️3.12
️✔️3.14
️✔️sqlvm
️✔️latest
️✔️3.12
️✔️3.14
️✔️storage
️✔️latest
️✔️3.12
️✔️3.14
️✔️synapse
️✔️latest
️✔️3.12
️✔️3.14
️✔️telemetry
️✔️latest
️✔️3.12
️✔️3.14
️✔️util
️✔️latest
️✔️3.12
️✔️3.14
️✔️vm
️✔️latest
️✔️3.12
️✔️3.14

@azure-client-tools-bot-prd

azure-client-tools-bot-prd Bot commented Jun 16, 2026

Copy link
Copy Markdown
️✔️AzureCLI-BreakingChangeTest
️✔️Non Breaking Changes

@yonzhan

yonzhan commented Jun 16, 2026

Copy link
Copy Markdown
Collaborator

App Service

@naveedaz naveedaz force-pushed the fix/appservice-cache-scm-headers-onedeploy branch 3 times, most recently from bf34e57 to c79a930 Compare June 17, 2026 00:29
@naveedaz naveedaz marked this pull request as ready for review June 17, 2026 01:15
Copilot AI review requested due to automatic review settings June 17, 2026 01:15

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

This PR introduces per-invocation caching for OneDeploy to reduce redundant ARM calls during az webapp deploy / az functionapp deploy, while adding targeted unit tests and documenting the change.

Changes:

  • Cache the Site model, derived SCM URL, and stable SCM auth headers on OneDeployParams for the duration of a deploy invocation.
  • Thread cached parameters through status polling helpers to reuse headers/site and refresh credentials on 401.
  • Add comprehensive mock-based tests and update release notes.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
src/azure-cli/azure/cli/command_modules/appservice/custom.py Implements Site/SCM URL/SCM header caching and updates OneDeploy/status polling flow to reuse cached data.
src/azure-cli/azure/cli/command_modules/appservice/tests/latest/test_webapp_commands_thru_mock.py Adds unit tests validating cache behavior, 401 refresh, and non-leakage of credentials.
src/azure-cli/HISTORY.rst Documents the reduced ARM-call behavior for deploy commands.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/azure-cli/azure/cli/command_modules/appservice/custom.py Outdated
Comment on lines +11026 to +11030
# Eagerly fetch (and cache) the Site so downstream helpers
# (_get_or_fetch_scm_url, _get_visit_url, _get_or_fetch_is_linux_webapp)
# can derive answers from the cached model without issuing additional
# GET /sites calls. Also derive the is_flex hint here so
# get_scm_site_headers can skip the redundant is_flex_functionapp call.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

Comment thread src/azure-cli/azure/cli/command_modules/appservice/custom.py Outdated
…single deploy invocation

`az webapp deploy` currently issues ~12 ARM calls per invocation. Most of
the duplication comes from two helpers that are called twice each within a
single deploy:

* `_get_scm_url` is called from `_build_onedeploy_scm_url` (publish URL)
  and `_get_onedeploy_status_url` (status URL). The SCM hostname does not
  change between the two — 1 ARM call (`GET /sites`) is wasted.
* `get_scm_site_headers` is called from `_get_ondeploy_headers` (publish
  POST) and again ~20–60 s later from `_check_zip_deployment_status`
  (status poll). Each invocation runs `is_flex_functionapp` +
  `basic_auth_supported` + `_get_site_credential` — 3 wasted ARM calls.

Hoist both results onto `OneDeployParams` for the lifetime of one deploy,
reuse them on the status leg, and clear them in a `finally` block so a
basic-auth credential cannot outlive the invocation (and cannot be observed
by outer exception handlers or telemetry). On a HTTP 401 from the poll we
drop the cache and refetch once to handle credential rotation.

Net effect per invocation: 12 → 7 ARM calls (–42%), and the
`_get_site_credential` exposure (the call that has been observed to surface
sporadic `ConnectionResetError(10054)`) drops from 2 to 1.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@naveedaz naveedaz force-pushed the fix/appservice-cache-scm-headers-onedeploy branch from c79a930 to 6e5496b Compare June 17, 2026 17:35
@naveedaz

Copy link
Copy Markdown
Contributor Author

@yanzhudd Can you please review and merge?

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants