Summary
When I deploy my Azure Functions app to a Flex Consumption plan using Azure/functions-action, Azure Portal only displays WarmUp in the Functions list on the overview blade. I have to click Refresh in order to see my actual functions.
Environment
- Action version:
Azure/functions-action@v1.5.6 (pinned to bc63708cc6539760eea18d8a7de4ce8ef5fdf593)
- Plan: Azure Functions Flex Consumption
- Runtime: .NET 10, isolated worker model, self-contained,
linux-x64
- Deploy method: zip package built via
dotnet publish, uploaded via the action's package input (see workflow excerpt below)
- CI: GitHub Actions (
ubuntu-latest), authenticating via OIDC (azure/login)
Expected Behavior
After a successful deployment, in Azure Portal, I see a list of my functions, available and ready to run.
Actual Behavior
After a successful deployment, in Azure Portal, I see only WarmUp, which is not one of my functions. I have to click Refresh, after which I see my functions, and they're available and ready to run.
What I have tried
With Claude's help, I tried the following:
- Baseline: rely solely on
Azure/functions-action's built-in deployment + Kudu sync. It almost always results in only WarmUp being display in Azure Portal.
az functionapp restart immediately after deploy. Theory: force re-specialization of a worker so it picks up the new package. Did not reliably resolve it (and risks restarting mid-async-deployment-pipeline, since Kudu's pipeline can still be finishing up to ~60s after the "Finished deployment pipeline" log line).
- Call the ARM
host/default/sync endpoint (the same one the Portal's Refresh button calls) after a fixed Start-Sleep -Seconds 90:
az rest --method post --url "https://management.azure.com/subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.Web/sites/<app>/host/default/sync?api-version=2018-11-01"
This worked on the very next deployment after adding it, then reverted to showing WarmUp on a subsequent deployment with no other changes — suggesting the fixed 90s delay is a race rather than a real fix: Flex Consumption instance specialization time (cold start, loading the app + native dependencies) is variable, and a single fire-and-forget sync call issued too early has nothing real to report yet.
- Current workaround: replaced the single sync call with a poll loop — call
host/default/sync, then GET .../functions and check for a known function name, retrying with backoff (up to ~10 attempts / ~7 minutes) before failing the CI job loudly if it never resolves. This makes the failure visible in CI instead of silently leaving a stale Portal, but it's a workaround for what still looks like a platform/action reliability gap, not a fix.
Relevant workflow excerpt with workaround
So far, this workaround has resulted in the expected behavior after every deployment:
- name: Deploy ZIPped Function with the Azure Functions Action
uses: Azure/functions-action@bc63708cc6539760eea18d8a7de4ce8ef5fdf593 # v1.5.6
with:
app-name: ${{env.FUNCTION_APP_NAME}}
package: ${{env.PUBLISH_ZIP_FILE_NAME}}
# Kudu's own SyncTriggerStep (visible in App Insights) calls hostruntime/admin/host/synctriggers,
# which isn't reliably picked up by the Portal/runtime on Flex Consumption. The Portal's Refresh
# button, which does work, calls the ARM-level host/default/sync endpoint instead - call that
# same endpoint here.
#
# A single sync call on a fixed delay is a race: on Flex Consumption an instance has to cold-start
# and specialize with the new package (including native Magick.NET/SkiaSharp deps) before sync has
# anything real to report, and that takes a variable amount of time. Until it does, sync/Portal keep
# showing the placeholder WarmUp function. So poll: call sync, then check whether CheckAlertsScheduled
# is actually registered, and retry with backoff until it is (or we give up and fail the job loudly
# instead of silently leaving WarmUp behind).
- name: Sync triggers and verify the deployment took effect
run: |
$resourceGroup = az functionapp list --query "[?name=='${{env.FUNCTION_APP_NAME}}'].resourceGroup" -o tsv
$syncUrl = "https://management.azure.com/subscriptions/${{vars.AZURE_SUBSCRIPTION_ID}}/resourceGroups/$resourceGroup/providers/Microsoft.Web/sites/${{env.FUNCTION_APP_NAME}}/host/default/sync?api-version=2018-11-01"
$listUrl = "https://management.azure.com/subscriptions/${{vars.AZURE_SUBSCRIPTION_ID}}/resourceGroups/$resourceGroup/providers/Microsoft.Web/sites/${{env.FUNCTION_APP_NAME}}/functions?api-version=2023-12-01"
$maxAttempts = 10
$delaySeconds = 30
$verified = $false
for ($attempt = 1; $attempt -le $maxAttempts; $attempt++) {
Write-Output "Attempt $attempt/$maxAttempts - waiting ${delaySeconds}s before syncing triggers..."
Start-Sleep -Seconds $delaySeconds
az rest --method post --url $syncUrl | Out-Null
# Give the sync call a moment to propagate before checking what it reported.
Start-Sleep -Seconds 10
$functionNames = az rest --method get --url $listUrl --query "value[].name" -o tsv
Write-Output "Functions currently known to the runtime:`n$functionNames"
if ($functionNames -match 'CheckAlertsScheduled') {
Write-Output "Verified CheckAlertsScheduled is registered - deployment took effect."
$verified = $true
break
}
}
if (-not $verified) {
Write-Error "Trigger sync did not pick up CheckAlertsScheduled after $maxAttempts attempts (~$($maxAttempts * ($delaySeconds + 10))s). The Function App may still be serving the WarmUp placeholder - check the Portal and consider a manual restart."
exit 1
}
Related issue
It looks like this was fixed for Consumption plans in #135 ("triggers not synced after deployment," classic Consumption plan, closed August 2022) by pull request #148.
Question
- Is it possible for this action to handle this polling and checking internally?
- Claude suggests that perhaps the fix from #135 for Consumption plans can also be applied for
One Deploy deployments to Flex Consumption plans. Is that possible?
Note
This also happens with the stock Azure DevOps Pipelines AzureFunctionsApp@v2: microsoft/azure-pipelines-tasks#22354
Summary
When I deploy my Azure Functions app to a Flex Consumption plan using
Azure/functions-action, Azure Portal only displaysWarmUpin the Functions list on the overview blade. I have to clickRefreshin order to see my actual functions.Environment
Azure/functions-action@v1.5.6(pinned tobc63708cc6539760eea18d8a7de4ce8ef5fdf593)linux-x64dotnet publish, uploaded via the action'spackageinput (see workflow excerpt below)ubuntu-latest), authenticating via OIDC (azure/login)Expected Behavior
After a successful deployment, in Azure Portal, I see a list of my functions, available and ready to run.
Actual Behavior
After a successful deployment, in Azure Portal, I see only
WarmUp, which is not one of my functions. I have to clickRefresh, after which I see my functions, and they're available and ready to run.What I have tried
With Claude's help, I tried the following:
Azure/functions-action's built-in deployment + Kudu sync. It almost always results in onlyWarmUpbeing display in Azure Portal.az functionapp restartimmediately after deploy. Theory: force re-specialization of a worker so it picks up the new package. Did not reliably resolve it (and risks restarting mid-async-deployment-pipeline, since Kudu's pipeline can still be finishing up to ~60s after the "Finished deployment pipeline" log line).host/default/syncendpoint (the same one the Portal's Refresh button calls) after a fixedStart-Sleep -Seconds 90:WarmUpon a subsequent deployment with no other changes — suggesting the fixed 90s delay is a race rather than a real fix: Flex Consumption instance specialization time (cold start, loading the app + native dependencies) is variable, and a single fire-and-forget sync call issued too early has nothing real to report yet.host/default/sync, thenGET .../functionsand check for a known function name, retrying with backoff (up to ~10 attempts / ~7 minutes) before failing the CI job loudly if it never resolves. This makes the failure visible in CI instead of silently leaving a stale Portal, but it's a workaround for what still looks like a platform/action reliability gap, not a fix.Relevant workflow excerpt with workaround
So far, this workaround has resulted in the expected behavior after every deployment:
Related issue
It looks like this was fixed for
Consumptionplans in #135 ("triggers not synced after deployment," classic Consumption plan, closed August 2022) by pull request #148.Question
One Deploydeployments to Flex Consumption plans. Is that possible?Note
This also happens with the stock Azure DevOps Pipelines
AzureFunctionsApp@v2: microsoft/azure-pipelines-tasks#22354