02 - First Deploy (Dedicated)¶
Deploy your .NET 8 isolated worker app to a Dedicated (App Service Plan) B1 with long-form Azure CLI commands and validate your first production endpoint.
Prerequisites¶
| Tool | Version | Purpose |
|---|---|---|
| .NET SDK | 8.0 (LTS) | Build and run isolated worker functions |
| Azure Functions Core Tools | v4 | Start local host and publish artifacts |
| Azure CLI | 2.61+ | Provision Azure resources and inspect app state |
Dedicated plan basics
Dedicated (App Service Plan) runs on pre-provisioned compute with predictable cost. Always On keeps the host loaded for non-HTTP triggers. Supports VNet integration and deployment slots on eligible SKUs. No execution timeout limit.
Network Scenario Choices
This tutorial deploys with public networking on B1 (Basic tier). For VNet integration, use Standard (S1) or higher:
| Scenario | Description | Guide |
|---|---|---|
| Public Only | No VNet (this tutorial, B1) | Current page |
| Private Egress | VNet + Storage PE (S1+) | Private Egress |
| Private Ingress | + Site Private Endpoint (S1+) | Private Ingress |
| Fixed Outbound IP | + NAT Gateway (S1+) | Fixed Outbound |
What You'll Build¶
A Linux Dedicated Function App running the .NET 8 isolated worker on a B1 App Service Plan, deployed from your local project with Core Tools, then validated through all HTTP endpoints.
flowchart TD
A["az appservice plan create B1"] --> B[az functionapp create]
B --> C[dotnet publish]
C --> D[func azure functionapp publish]
D --> E[16 functions indexed]
E --> F[HTTP endpoint validation] | CLI element | Explanation |
|---|---|
| Command(s) | az appservice plan create B1"] |
| Key flags | None |
| Variables | None |
| Expected result | Azure CLI returns provisioning details; confirm the resource name and successful provisioning state before continuing. |
Steps¶
Step 1 - Set deployment variables¶
export RG="rg-func-dotnet-ded-demo"
export LOCATION="koreacentral"
export STORAGE_NAME="stdnetded0410"
export PLAN_NAME="plan-dnetded-04100301"
export APP_NAME="func-dnetded-04100301"
| Command/Parameter | Purpose |
|---|---|
RG | Resource group name |
LOCATION | Azure region |
STORAGE_NAME | Storage account name |
PLAN_NAME | App Service Plan name |
APP_NAME | Function app name |
Step 2 - Create resource group and storage account¶
az group create \
--name "$RG" \
--location "$LOCATION"
az storage account create \
--name "$STORAGE_NAME" \
--resource-group "$RG" \
--location "$LOCATION" \
--sku Standard_LRS
| Command/Parameter | Purpose |
|---|---|
az group create | Creates the resource group container |
az storage account create | Provision storage for app state and logs |
Step 3 - Create the Dedicated App Service Plan¶
az appservice plan create \
--name "$PLAN_NAME" \
--resource-group "$RG" \
--location "$LOCATION" \
--sku B1 \
--is-linux
| Command/Parameter | Purpose |
|---|---|
--sku B1 | Basic 1 (predictable compute for dev/test) |
--is-linux | Runs on Linux workers |
Dedicated plan uses az appservice plan create
Unlike Premium which uses az functionapp plan create, Dedicated plans use az appservice plan create. This creates a standard App Service Plan that can host both Function Apps and Web Apps.
Step 4 - Create the function app on the Dedicated plan¶
az functionapp create \
--name "$APP_NAME" \
--resource-group "$RG" \
--storage-account "$STORAGE_NAME" \
--plan "$PLAN_NAME" \
--runtime dotnet-isolated \
--runtime-version 8 \
--functions-version 4 \
--os-type Linux
| Command/Parameter | Purpose |
|---|---|
--plan "$PLAN_NAME" | Links the app to the pre-provisioned B1 plan |
--runtime dotnet-isolated | Targets .NET 8 isolated worker |
Step 5 - Create trigger resources¶
az storage queue create \
--name "incoming-orders" \
--account-name "$STORAGE_NAME"
az storage container create \
--name "uploads" \
--account-name "$STORAGE_NAME"
| Command/Parameter | Purpose |
|---|---|
az storage queue create | Creates the queue for order processing |
az storage container create | Creates the blob container for uploads |
Step 6 - Configure app settings¶
STORAGE_CONN=$(az storage account show-connection-string \
--name "$STORAGE_NAME" \
--resource-group "$RG" \
--query connectionString \
--output tsv)
az functionapp config appsettings set \
--name "$APP_NAME" \
--resource-group "$RG" \
--settings \
"QueueStorage=$STORAGE_CONN" \
"EventHubConnection=Endpoint=sb://placeholder.servicebus.windows.net/;SharedAccessKeyName=placeholder;SharedAccessKey=cGxhY2Vob2xkZXI=;EntityPath=events"
| Command/Parameter | Purpose |
|---|---|
az functionapp config appsettings set | Configures environment variables |
Step 7 - Build and publish¶
cd apps/dotnet
dotnet publish --configuration Release --output ./publish
cd publish
func azure functionapp publish "$APP_NAME" --dotnet-isolated
| Command/Parameter | Purpose |
|---|---|
dotnet publish | Compiles the project and dependencies |
func azure functionapp publish | Deploys the artifacts to Azure |
Must pass --dotnet-isolated flag
When publishing from the compiled output directory, Core Tools cannot detect the project language. Always pass --dotnet-isolated to specify the worker runtime explicitly.
Step 8 - Verify function list¶
az functionapp function list \
--name "$APP_NAME" \
--resource-group "$RG" \
--query "[].{name:name, language:language}" \
--output table
| Command/Parameter | Purpose |
|---|---|
az functionapp function list | Lists all indexed functions in the app |
Expected output (16 functions):
Name Language
-------------------------------------------- ---------------
func-dnetded-04100301/blobProcessor dotnet-isolated
func-dnetded-04100301/dnsResolve dotnet-isolated
func-dnetded-04100301/eventhubLagProcessor dotnet-isolated
func-dnetded-04100301/externalDependency dotnet-isolated
func-dnetded-04100301/health dotnet-isolated
func-dnetded-04100301/helloHttp dotnet-isolated
func-dnetded-04100301/identityProbe dotnet-isolated
func-dnetded-04100301/info dotnet-isolated
func-dnetded-04100301/logLevels dotnet-isolated
func-dnetded-04100301/queueProcessor dotnet-isolated
func-dnetded-04100301/scheduledCleanup dotnet-isolated
func-dnetded-04100301/slowResponse dotnet-isolated
func-dnetded-04100301/storageProbe dotnet-isolated
func-dnetded-04100301/testError dotnet-isolated
func-dnetded-04100301/timerLab dotnet-isolated
func-dnetded-04100301/unhandledError dotnet-isolated
Fast indexing on Dedicated
Unlike Premium and Consumption plans, Dedicated plans typically index all functions immediately after publish. You should see all 16 functions in the list without any delay.
Step 9 - Test HTTP endpoints¶
curl --request GET "https://$APP_NAME.azurewebsites.net/api/health"
curl --request GET "https://$APP_NAME.azurewebsites.net/api/hello/Dedicated"
curl --request GET "https://$APP_NAME.azurewebsites.net/api/info"
| Command/Parameter | Purpose |
|---|---|
curl --request GET | Sends validation requests to the app |
/api/health | Probes service health state |
/api/info | Inspects app configuration values |
Verification¶
Uploading 6.82 MB [-----------------------------------------------------------]
Upload completed successfully.
Deployment completed successfully.
Syncing triggers...
App state:
State DefaultHostName Kind
------- ----------------------------------------- -----------------
Running func-dnetded-04100301.azurewebsites.net functionapp,linux
Health endpoint response:
Hello endpoint response:
Info endpoint response:
{"name":"azure-functions-dotnet-guide","version":"1.0.0","dotnet":".NET 8.0.23","os":"Linux","environment":"production","functionApp":"func-dnetded-04100301"}
.NET upload size
The .NET isolated worker publish output is approximately 6.82 MB, larger than Java (~326 KB) because it includes the ASP.NET Core runtime dependencies.
Next Steps¶
Next: 03 - Configuration
See Also¶
- Tutorial Overview & Plan Chooser
- .NET Language Guide
- Platform: Hosting Plans
- Operations: Deployment
- Recipes Index