The azure-native:web:WebApp resource, part of the Pulumi Azure Native provider, defines an Azure web app, function app, or mobile backend: its hosting plan, runtime configuration, and deployment settings. This guide focuses on three capabilities: App Service plan association, Flex Consumption function app configuration, and app cloning across regions.
Web apps depend on App Service plans or Flex Consumption hosting for compute resources. Function apps reference storage accounts and Application Insights for deployment and monitoring. The examples are intentionally small. Combine them with your own hosting infrastructure, networking, and identity configuration.
Create a web app with an App Service plan
Most deployments link a web app to an existing App Service plan, which defines compute resources and pricing tier.
import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";
const webApp = new azure_native.web.WebApp("webApp", {
kind: "app",
location: "East US",
name: "sitef6141",
resourceGroupName: "testrg123",
serverFarmId: "/subscriptions/34adfa4f-cedf-4dc0-ba29-b6d1a69ab345/resourceGroups/testrg123/providers/Microsoft.Web/serverfarms/DefaultAsp",
});
import pulumi
import pulumi_azure_native as azure_native
web_app = azure_native.web.WebApp("webApp",
kind="app",
location="East US",
name="sitef6141",
resource_group_name="testrg123",
server_farm_id="/subscriptions/34adfa4f-cedf-4dc0-ba29-b6d1a69ab345/resourceGroups/testrg123/providers/Microsoft.Web/serverfarms/DefaultAsp")
package main
import (
web "github.com/pulumi/pulumi-azure-native-sdk/web/v3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := web.NewWebApp(ctx, "webApp", &web.WebAppArgs{
Kind: pulumi.String("app"),
Location: pulumi.String("East US"),
Name: pulumi.String("sitef6141"),
ResourceGroupName: pulumi.String("testrg123"),
ServerFarmId: pulumi.String("/subscriptions/34adfa4f-cedf-4dc0-ba29-b6d1a69ab345/resourceGroups/testrg123/providers/Microsoft.Web/serverfarms/DefaultAsp"),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;
return await Deployment.RunAsync(() =>
{
var webApp = new AzureNative.Web.WebApp("webApp", new()
{
Kind = "app",
Location = "East US",
Name = "sitef6141",
ResourceGroupName = "testrg123",
ServerFarmId = "/subscriptions/34adfa4f-cedf-4dc0-ba29-b6d1a69ab345/resourceGroups/testrg123/providers/Microsoft.Web/serverfarms/DefaultAsp",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.web.WebApp;
import com.pulumi.azurenative.web.WebAppArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var webApp = new WebApp("webApp", WebAppArgs.builder()
.kind("app")
.location("East US")
.name("sitef6141")
.resourceGroupName("testrg123")
.serverFarmId("/subscriptions/34adfa4f-cedf-4dc0-ba29-b6d1a69ab345/resourceGroups/testrg123/providers/Microsoft.Web/serverfarms/DefaultAsp")
.build());
}
}
resources:
webApp:
type: azure-native:web:WebApp
properties:
kind: app
location: East US
name: sitef6141
resourceGroupName: testrg123
serverFarmId: /subscriptions/34adfa4f-cedf-4dc0-ba29-b6d1a69ab345/resourceGroups/testrg123/providers/Microsoft.Web/serverfarms/DefaultAsp
The serverFarmId property connects the app to an App Service plan that controls scaling, pricing, and available features. The kind property identifies this as a standard web app rather than a function app or container. Without additional configuration, the app uses default settings for runtime, networking, and authentication.
Deploy a Flex Consumption function app with runtime configuration
Azure Functions on Flex Consumption provide event-driven compute with automatic scaling and pay-per-execution billing.
import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";
const webApp = new azure_native.web.WebApp("webApp", {
functionAppConfig: {
deployment: {
storage: {
authentication: {
storageAccountConnectionStringName: "TheAppSettingName",
type: azure_native.web.AuthenticationType.StorageAccountConnectionString,
},
type: azure_native.web.FunctionsDeploymentStorageType.BlobContainer,
value: "https://storageAccountName.blob.core.windows.net/containername",
},
},
runtime: {
name: azure_native.web.RuntimeName.Python,
version: "3.11",
},
scaleAndConcurrency: {
instanceMemoryMB: 2048,
maximumInstanceCount: 100,
},
},
kind: "functionapp,linux",
location: "East US",
name: "sitef6141",
resourceGroupName: "testrg123",
siteConfig: {
appSettings: [
{
name: "AzureWebJobsStorage",
value: "DefaultEndpointsProtocol=https;AccountName=StorageAccountName;AccountKey=Sanitized;EndpointSuffix=core.windows.net",
},
{
name: "APPLICATIONINSIGHTS_CONNECTION_STRING",
value: "InstrumentationKey=Sanitized;IngestionEndpoint=Sanitized;LiveEndpoint=Sanitized",
},
],
},
});
import pulumi
import pulumi_azure_native as azure_native
web_app = azure_native.web.WebApp("webApp",
function_app_config={
"deployment": {
"storage": {
"authentication": {
"storage_account_connection_string_name": "TheAppSettingName",
"type": azure_native.web.AuthenticationType.STORAGE_ACCOUNT_CONNECTION_STRING,
},
"type": azure_native.web.FunctionsDeploymentStorageType.BLOB_CONTAINER,
"value": "https://storageAccountName.blob.core.windows.net/containername",
},
},
"runtime": {
"name": azure_native.web.RuntimeName.PYTHON,
"version": "3.11",
},
"scale_and_concurrency": {
"instance_memory_mb": 2048,
"maximum_instance_count": 100,
},
},
kind="functionapp,linux",
location="East US",
name="sitef6141",
resource_group_name="testrg123",
site_config={
"app_settings": [
{
"name": "AzureWebJobsStorage",
"value": "DefaultEndpointsProtocol=https;AccountName=StorageAccountName;AccountKey=Sanitized;EndpointSuffix=core.windows.net",
},
{
"name": "APPLICATIONINSIGHTS_CONNECTION_STRING",
"value": "InstrumentationKey=Sanitized;IngestionEndpoint=Sanitized;LiveEndpoint=Sanitized",
},
],
})
package main
import (
web "github.com/pulumi/pulumi-azure-native-sdk/web/v3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := web.NewWebApp(ctx, "webApp", &web.WebAppArgs{
FunctionAppConfig: &web.FunctionAppConfigArgs{
Deployment: &web.FunctionsDeploymentArgs{
Storage: &web.FunctionsDeploymentStorageArgs{
Authentication: &web.FunctionsDeploymentAuthenticationArgs{
StorageAccountConnectionStringName: pulumi.String("TheAppSettingName"),
Type: pulumi.String(web.AuthenticationTypeStorageAccountConnectionString),
},
Type: pulumi.String(web.FunctionsDeploymentStorageTypeBlobContainer),
Value: pulumi.String("https://storageAccountName.blob.core.windows.net/containername"),
},
},
Runtime: &web.FunctionsRuntimeArgs{
Name: pulumi.String(web.RuntimeNamePython),
Version: pulumi.String("3.11"),
},
ScaleAndConcurrency: &web.FunctionsScaleAndConcurrencyArgs{
InstanceMemoryMB: pulumi.Int(2048),
MaximumInstanceCount: pulumi.Int(100),
},
},
Kind: pulumi.String("functionapp,linux"),
Location: pulumi.String("East US"),
Name: pulumi.String("sitef6141"),
ResourceGroupName: pulumi.String("testrg123"),
SiteConfig: &web.SiteConfigArgs{
AppSettings: web.NameValuePairArray{
&web.NameValuePairArgs{
Name: pulumi.String("AzureWebJobsStorage"),
Value: pulumi.String("DefaultEndpointsProtocol=https;AccountName=StorageAccountName;AccountKey=Sanitized;EndpointSuffix=core.windows.net"),
},
&web.NameValuePairArgs{
Name: pulumi.String("APPLICATIONINSIGHTS_CONNECTION_STRING"),
Value: pulumi.String("InstrumentationKey=Sanitized;IngestionEndpoint=Sanitized;LiveEndpoint=Sanitized"),
},
},
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;
return await Deployment.RunAsync(() =>
{
var webApp = new AzureNative.Web.WebApp("webApp", new()
{
FunctionAppConfig = new AzureNative.Web.Inputs.FunctionAppConfigArgs
{
Deployment = new AzureNative.Web.Inputs.FunctionsDeploymentArgs
{
Storage = new AzureNative.Web.Inputs.FunctionsDeploymentStorageArgs
{
Authentication = new AzureNative.Web.Inputs.FunctionsDeploymentAuthenticationArgs
{
StorageAccountConnectionStringName = "TheAppSettingName",
Type = AzureNative.Web.AuthenticationType.StorageAccountConnectionString,
},
Type = AzureNative.Web.FunctionsDeploymentStorageType.BlobContainer,
Value = "https://storageAccountName.blob.core.windows.net/containername",
},
},
Runtime = new AzureNative.Web.Inputs.FunctionsRuntimeArgs
{
Name = AzureNative.Web.RuntimeName.Python,
Version = "3.11",
},
ScaleAndConcurrency = new AzureNative.Web.Inputs.FunctionsScaleAndConcurrencyArgs
{
InstanceMemoryMB = 2048,
MaximumInstanceCount = 100,
},
},
Kind = "functionapp,linux",
Location = "East US",
Name = "sitef6141",
ResourceGroupName = "testrg123",
SiteConfig = new AzureNative.Web.Inputs.SiteConfigArgs
{
AppSettings = new[]
{
new AzureNative.Web.Inputs.NameValuePairArgs
{
Name = "AzureWebJobsStorage",
Value = "DefaultEndpointsProtocol=https;AccountName=StorageAccountName;AccountKey=Sanitized;EndpointSuffix=core.windows.net",
},
new AzureNative.Web.Inputs.NameValuePairArgs
{
Name = "APPLICATIONINSIGHTS_CONNECTION_STRING",
Value = "InstrumentationKey=Sanitized;IngestionEndpoint=Sanitized;LiveEndpoint=Sanitized",
},
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.web.WebApp;
import com.pulumi.azurenative.web.WebAppArgs;
import com.pulumi.azurenative.web.inputs.FunctionAppConfigArgs;
import com.pulumi.azurenative.web.inputs.FunctionsDeploymentArgs;
import com.pulumi.azurenative.web.inputs.FunctionsDeploymentStorageArgs;
import com.pulumi.azurenative.web.inputs.FunctionsDeploymentAuthenticationArgs;
import com.pulumi.azurenative.web.inputs.FunctionsRuntimeArgs;
import com.pulumi.azurenative.web.inputs.FunctionsScaleAndConcurrencyArgs;
import com.pulumi.azurenative.web.inputs.SiteConfigArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var webApp = new WebApp("webApp", WebAppArgs.builder()
.functionAppConfig(FunctionAppConfigArgs.builder()
.deployment(FunctionsDeploymentArgs.builder()
.storage(FunctionsDeploymentStorageArgs.builder()
.authentication(FunctionsDeploymentAuthenticationArgs.builder()
.storageAccountConnectionStringName("TheAppSettingName")
.type("StorageAccountConnectionString")
.build())
.type("blobContainer")
.value("https://storageAccountName.blob.core.windows.net/containername")
.build())
.build())
.runtime(FunctionsRuntimeArgs.builder()
.name("python")
.version("3.11")
.build())
.scaleAndConcurrency(FunctionsScaleAndConcurrencyArgs.builder()
.instanceMemoryMB(2048)
.maximumInstanceCount(100)
.build())
.build())
.kind("functionapp,linux")
.location("East US")
.name("sitef6141")
.resourceGroupName("testrg123")
.siteConfig(SiteConfigArgs.builder()
.appSettings(
NameValuePairArgs.builder()
.name("AzureWebJobsStorage")
.value("DefaultEndpointsProtocol=https;AccountName=StorageAccountName;AccountKey=Sanitized;EndpointSuffix=core.windows.net")
.build(),
NameValuePairArgs.builder()
.name("APPLICATIONINSIGHTS_CONNECTION_STRING")
.value("InstrumentationKey=Sanitized;IngestionEndpoint=Sanitized;LiveEndpoint=Sanitized")
.build())
.build())
.build());
}
}
resources:
webApp:
type: azure-native:web:WebApp
properties:
functionAppConfig:
deployment:
storage:
authentication:
storageAccountConnectionStringName: TheAppSettingName
type: StorageAccountConnectionString
type: blobContainer
value: https://storageAccountName.blob.core.windows.net/containername
runtime:
name: python
version: '3.11'
scaleAndConcurrency:
instanceMemoryMB: 2048
maximumInstanceCount: 100
kind: functionapp,linux
location: East US
name: sitef6141
resourceGroupName: testrg123
siteConfig:
appSettings:
- name: AzureWebJobsStorage
value: DefaultEndpointsProtocol=https;AccountName=StorageAccountName;AccountKey=Sanitized;EndpointSuffix=core.windows.net
- name: APPLICATIONINSIGHTS_CONNECTION_STRING
value: InstrumentationKey=Sanitized;IngestionEndpoint=Sanitized;LiveEndpoint=Sanitized
The functionAppConfig block defines the function app’s behavior. The runtime property sets the language and version (Python 3.11 here). The deployment.storage property points to a blob container for function code, authenticated via a connection string stored in app settings. The scaleAndConcurrency block sets memory per instance (2048 MB) and maximum instance count (100), controlling how the platform scales under load.
Configure always-ready instances and concurrency limits
Production function apps often maintain warm instances to avoid cold starts and set per-instance concurrency limits to control resource usage.
import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";
const webApp = new azure_native.web.WebApp("webApp", {
functionAppConfig: {
deployment: {
storage: {
authentication: {
storageAccountConnectionStringName: "TheAppSettingName",
type: azure_native.web.AuthenticationType.StorageAccountConnectionString,
},
type: azure_native.web.FunctionsDeploymentStorageType.BlobContainer,
value: "https://storageAccountName.blob.core.windows.net/containername",
},
},
runtime: {
name: azure_native.web.RuntimeName.Python,
version: "3.11",
},
scaleAndConcurrency: {
alwaysReady: [{
instanceCount: 2,
name: "http",
}],
instanceMemoryMB: 2048,
maximumInstanceCount: 100,
triggers: {
http: {
perInstanceConcurrency: 16,
},
},
},
},
kind: "functionapp,linux",
location: "East US",
name: "sitef6141",
resourceGroupName: "testrg123",
siteConfig: {
appSettings: [
{
name: "AzureWebJobsStorage",
value: "DefaultEndpointsProtocol=https;AccountName=StorageAccountName;AccountKey=Sanitized;EndpointSuffix=core.windows.net",
},
{
name: "APPLICATIONINSIGHTS_CONNECTION_STRING",
value: "InstrumentationKey=Sanitized;IngestionEndpoint=Sanitized;LiveEndpoint=Sanitized",
},
],
},
});
import pulumi
import pulumi_azure_native as azure_native
web_app = azure_native.web.WebApp("webApp",
function_app_config={
"deployment": {
"storage": {
"authentication": {
"storage_account_connection_string_name": "TheAppSettingName",
"type": azure_native.web.AuthenticationType.STORAGE_ACCOUNT_CONNECTION_STRING,
},
"type": azure_native.web.FunctionsDeploymentStorageType.BLOB_CONTAINER,
"value": "https://storageAccountName.blob.core.windows.net/containername",
},
},
"runtime": {
"name": azure_native.web.RuntimeName.PYTHON,
"version": "3.11",
},
"scale_and_concurrency": {
"always_ready": [{
"instance_count": 2,
"name": "http",
}],
"instance_memory_mb": 2048,
"maximum_instance_count": 100,
"triggers": {
"http": {
"per_instance_concurrency": 16,
},
},
},
},
kind="functionapp,linux",
location="East US",
name="sitef6141",
resource_group_name="testrg123",
site_config={
"app_settings": [
{
"name": "AzureWebJobsStorage",
"value": "DefaultEndpointsProtocol=https;AccountName=StorageAccountName;AccountKey=Sanitized;EndpointSuffix=core.windows.net",
},
{
"name": "APPLICATIONINSIGHTS_CONNECTION_STRING",
"value": "InstrumentationKey=Sanitized;IngestionEndpoint=Sanitized;LiveEndpoint=Sanitized",
},
],
})
package main
import (
web "github.com/pulumi/pulumi-azure-native-sdk/web/v3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := web.NewWebApp(ctx, "webApp", &web.WebAppArgs{
FunctionAppConfig: &web.FunctionAppConfigArgs{
Deployment: &web.FunctionsDeploymentArgs{
Storage: &web.FunctionsDeploymentStorageArgs{
Authentication: &web.FunctionsDeploymentAuthenticationArgs{
StorageAccountConnectionStringName: pulumi.String("TheAppSettingName"),
Type: pulumi.String(web.AuthenticationTypeStorageAccountConnectionString),
},
Type: pulumi.String(web.FunctionsDeploymentStorageTypeBlobContainer),
Value: pulumi.String("https://storageAccountName.blob.core.windows.net/containername"),
},
},
Runtime: &web.FunctionsRuntimeArgs{
Name: pulumi.String(web.RuntimeNamePython),
Version: pulumi.String("3.11"),
},
ScaleAndConcurrency: &web.FunctionsScaleAndConcurrencyArgs{
AlwaysReady: web.FunctionsAlwaysReadyConfigArray{
&web.FunctionsAlwaysReadyConfigArgs{
InstanceCount: pulumi.Int(2),
Name: pulumi.String("http"),
},
},
InstanceMemoryMB: pulumi.Int(2048),
MaximumInstanceCount: pulumi.Int(100),
Triggers: &web.FunctionsScaleAndConcurrencyTriggersArgs{
Http: &web.FunctionsScaleAndConcurrencyHttpArgs{
PerInstanceConcurrency: pulumi.Int(16),
},
},
},
},
Kind: pulumi.String("functionapp,linux"),
Location: pulumi.String("East US"),
Name: pulumi.String("sitef6141"),
ResourceGroupName: pulumi.String("testrg123"),
SiteConfig: &web.SiteConfigArgs{
AppSettings: web.NameValuePairArray{
&web.NameValuePairArgs{
Name: pulumi.String("AzureWebJobsStorage"),
Value: pulumi.String("DefaultEndpointsProtocol=https;AccountName=StorageAccountName;AccountKey=Sanitized;EndpointSuffix=core.windows.net"),
},
&web.NameValuePairArgs{
Name: pulumi.String("APPLICATIONINSIGHTS_CONNECTION_STRING"),
Value: pulumi.String("InstrumentationKey=Sanitized;IngestionEndpoint=Sanitized;LiveEndpoint=Sanitized"),
},
},
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;
return await Deployment.RunAsync(() =>
{
var webApp = new AzureNative.Web.WebApp("webApp", new()
{
FunctionAppConfig = new AzureNative.Web.Inputs.FunctionAppConfigArgs
{
Deployment = new AzureNative.Web.Inputs.FunctionsDeploymentArgs
{
Storage = new AzureNative.Web.Inputs.FunctionsDeploymentStorageArgs
{
Authentication = new AzureNative.Web.Inputs.FunctionsDeploymentAuthenticationArgs
{
StorageAccountConnectionStringName = "TheAppSettingName",
Type = AzureNative.Web.AuthenticationType.StorageAccountConnectionString,
},
Type = AzureNative.Web.FunctionsDeploymentStorageType.BlobContainer,
Value = "https://storageAccountName.blob.core.windows.net/containername",
},
},
Runtime = new AzureNative.Web.Inputs.FunctionsRuntimeArgs
{
Name = AzureNative.Web.RuntimeName.Python,
Version = "3.11",
},
ScaleAndConcurrency = new AzureNative.Web.Inputs.FunctionsScaleAndConcurrencyArgs
{
AlwaysReady = new[]
{
new AzureNative.Web.Inputs.FunctionsAlwaysReadyConfigArgs
{
InstanceCount = 2,
Name = "http",
},
},
InstanceMemoryMB = 2048,
MaximumInstanceCount = 100,
Triggers = new AzureNative.Web.Inputs.FunctionsScaleAndConcurrencyTriggersArgs
{
Http = new AzureNative.Web.Inputs.FunctionsScaleAndConcurrencyHttpArgs
{
PerInstanceConcurrency = 16,
},
},
},
},
Kind = "functionapp,linux",
Location = "East US",
Name = "sitef6141",
ResourceGroupName = "testrg123",
SiteConfig = new AzureNative.Web.Inputs.SiteConfigArgs
{
AppSettings = new[]
{
new AzureNative.Web.Inputs.NameValuePairArgs
{
Name = "AzureWebJobsStorage",
Value = "DefaultEndpointsProtocol=https;AccountName=StorageAccountName;AccountKey=Sanitized;EndpointSuffix=core.windows.net",
},
new AzureNative.Web.Inputs.NameValuePairArgs
{
Name = "APPLICATIONINSIGHTS_CONNECTION_STRING",
Value = "InstrumentationKey=Sanitized;IngestionEndpoint=Sanitized;LiveEndpoint=Sanitized",
},
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.web.WebApp;
import com.pulumi.azurenative.web.WebAppArgs;
import com.pulumi.azurenative.web.inputs.FunctionAppConfigArgs;
import com.pulumi.azurenative.web.inputs.FunctionsDeploymentArgs;
import com.pulumi.azurenative.web.inputs.FunctionsDeploymentStorageArgs;
import com.pulumi.azurenative.web.inputs.FunctionsDeploymentAuthenticationArgs;
import com.pulumi.azurenative.web.inputs.FunctionsRuntimeArgs;
import com.pulumi.azurenative.web.inputs.FunctionsScaleAndConcurrencyArgs;
import com.pulumi.azurenative.web.inputs.FunctionsScaleAndConcurrencyTriggersArgs;
import com.pulumi.azurenative.web.inputs.FunctionsScaleAndConcurrencyHttpArgs;
import com.pulumi.azurenative.web.inputs.SiteConfigArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var webApp = new WebApp("webApp", WebAppArgs.builder()
.functionAppConfig(FunctionAppConfigArgs.builder()
.deployment(FunctionsDeploymentArgs.builder()
.storage(FunctionsDeploymentStorageArgs.builder()
.authentication(FunctionsDeploymentAuthenticationArgs.builder()
.storageAccountConnectionStringName("TheAppSettingName")
.type("StorageAccountConnectionString")
.build())
.type("blobContainer")
.value("https://storageAccountName.blob.core.windows.net/containername")
.build())
.build())
.runtime(FunctionsRuntimeArgs.builder()
.name("python")
.version("3.11")
.build())
.scaleAndConcurrency(FunctionsScaleAndConcurrencyArgs.builder()
.alwaysReady(FunctionsAlwaysReadyConfigArgs.builder()
.instanceCount(2)
.name("http")
.build())
.instanceMemoryMB(2048)
.maximumInstanceCount(100)
.triggers(FunctionsScaleAndConcurrencyTriggersArgs.builder()
.http(FunctionsScaleAndConcurrencyHttpArgs.builder()
.perInstanceConcurrency(16)
.build())
.build())
.build())
.build())
.kind("functionapp,linux")
.location("East US")
.name("sitef6141")
.resourceGroupName("testrg123")
.siteConfig(SiteConfigArgs.builder()
.appSettings(
NameValuePairArgs.builder()
.name("AzureWebJobsStorage")
.value("DefaultEndpointsProtocol=https;AccountName=StorageAccountName;AccountKey=Sanitized;EndpointSuffix=core.windows.net")
.build(),
NameValuePairArgs.builder()
.name("APPLICATIONINSIGHTS_CONNECTION_STRING")
.value("InstrumentationKey=Sanitized;IngestionEndpoint=Sanitized;LiveEndpoint=Sanitized")
.build())
.build())
.build());
}
}
resources:
webApp:
type: azure-native:web:WebApp
properties:
functionAppConfig:
deployment:
storage:
authentication:
storageAccountConnectionStringName: TheAppSettingName
type: StorageAccountConnectionString
type: blobContainer
value: https://storageAccountName.blob.core.windows.net/containername
runtime:
name: python
version: '3.11'
scaleAndConcurrency:
alwaysReady:
- instanceCount: 2
name: http
instanceMemoryMB: 2048
maximumInstanceCount: 100
triggers:
http:
perInstanceConcurrency: 16
kind: functionapp,linux
location: East US
name: sitef6141
resourceGroupName: testrg123
siteConfig:
appSettings:
- name: AzureWebJobsStorage
value: DefaultEndpointsProtocol=https;AccountName=StorageAccountName;AccountKey=Sanitized;EndpointSuffix=core.windows.net
- name: APPLICATIONINSIGHTS_CONNECTION_STRING
value: InstrumentationKey=Sanitized;IngestionEndpoint=Sanitized;LiveEndpoint=Sanitized
The alwaysReady array keeps a minimum number of instances warm for specific trigger types (2 HTTP instances here). The triggers.http.perInstanceConcurrency property limits how many concurrent requests each instance handles (16 here), preventing resource exhaustion under sudden load spikes. This configuration extends the basic Flex Consumption setup with performance tuning for production workloads.
Clone an existing web app to a new region
Teams deploying across regions often clone existing apps rather than rebuilding configuration.
import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";
const webApp = new azure_native.web.WebApp("webApp", {
cloningInfo: {
appSettingsOverrides: {
Setting1: "NewValue1",
Setting3: "NewValue5",
},
cloneCustomHostNames: true,
cloneSourceControl: true,
configureLoadBalancing: false,
hostingEnvironment: "/subscriptions/34adfa4f-cedf-4dc0-ba29-b6d1a69ab345/resourceGroups/testrg456/providers/Microsoft.Web/hostingenvironments/aseforsites",
overwrite: false,
sourceWebAppId: "/subscriptions/34adfa4f-cedf-4dc0-ba29-b6d1a69ab345/resourceGroups/testrg456/providers/Microsoft.Web/sites/srcsiteg478",
sourceWebAppLocation: "West Europe",
},
kind: "app",
location: "East US",
name: "sitef6141",
resourceGroupName: "testrg123",
});
import pulumi
import pulumi_azure_native as azure_native
web_app = azure_native.web.WebApp("webApp",
cloning_info={
"app_settings_overrides": {
"Setting1": "NewValue1",
"Setting3": "NewValue5",
},
"clone_custom_host_names": True,
"clone_source_control": True,
"configure_load_balancing": False,
"hosting_environment": "/subscriptions/34adfa4f-cedf-4dc0-ba29-b6d1a69ab345/resourceGroups/testrg456/providers/Microsoft.Web/hostingenvironments/aseforsites",
"overwrite": False,
"source_web_app_id": "/subscriptions/34adfa4f-cedf-4dc0-ba29-b6d1a69ab345/resourceGroups/testrg456/providers/Microsoft.Web/sites/srcsiteg478",
"source_web_app_location": "West Europe",
},
kind="app",
location="East US",
name="sitef6141",
resource_group_name="testrg123")
package main
import (
web "github.com/pulumi/pulumi-azure-native-sdk/web/v3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := web.NewWebApp(ctx, "webApp", &web.WebAppArgs{
CloningInfo: &web.CloningInfoArgs{
AppSettingsOverrides: pulumi.StringMap{
"Setting1": pulumi.String("NewValue1"),
"Setting3": pulumi.String("NewValue5"),
},
CloneCustomHostNames: pulumi.Bool(true),
CloneSourceControl: pulumi.Bool(true),
ConfigureLoadBalancing: pulumi.Bool(false),
HostingEnvironment: pulumi.String("/subscriptions/34adfa4f-cedf-4dc0-ba29-b6d1a69ab345/resourceGroups/testrg456/providers/Microsoft.Web/hostingenvironments/aseforsites"),
Overwrite: pulumi.Bool(false),
SourceWebAppId: pulumi.String("/subscriptions/34adfa4f-cedf-4dc0-ba29-b6d1a69ab345/resourceGroups/testrg456/providers/Microsoft.Web/sites/srcsiteg478"),
SourceWebAppLocation: pulumi.String("West Europe"),
},
Kind: pulumi.String("app"),
Location: pulumi.String("East US"),
Name: pulumi.String("sitef6141"),
ResourceGroupName: pulumi.String("testrg123"),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;
return await Deployment.RunAsync(() =>
{
var webApp = new AzureNative.Web.WebApp("webApp", new()
{
CloningInfo = new AzureNative.Web.Inputs.CloningInfoArgs
{
AppSettingsOverrides =
{
{ "Setting1", "NewValue1" },
{ "Setting3", "NewValue5" },
},
CloneCustomHostNames = true,
CloneSourceControl = true,
ConfigureLoadBalancing = false,
HostingEnvironment = "/subscriptions/34adfa4f-cedf-4dc0-ba29-b6d1a69ab345/resourceGroups/testrg456/providers/Microsoft.Web/hostingenvironments/aseforsites",
Overwrite = false,
SourceWebAppId = "/subscriptions/34adfa4f-cedf-4dc0-ba29-b6d1a69ab345/resourceGroups/testrg456/providers/Microsoft.Web/sites/srcsiteg478",
SourceWebAppLocation = "West Europe",
},
Kind = "app",
Location = "East US",
Name = "sitef6141",
ResourceGroupName = "testrg123",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.web.WebApp;
import com.pulumi.azurenative.web.WebAppArgs;
import com.pulumi.azurenative.web.inputs.CloningInfoArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var webApp = new WebApp("webApp", WebAppArgs.builder()
.cloningInfo(CloningInfoArgs.builder()
.appSettingsOverrides(Map.ofEntries(
Map.entry("Setting1", "NewValue1"),
Map.entry("Setting3", "NewValue5")
))
.cloneCustomHostNames(true)
.cloneSourceControl(true)
.configureLoadBalancing(false)
.hostingEnvironment("/subscriptions/34adfa4f-cedf-4dc0-ba29-b6d1a69ab345/resourceGroups/testrg456/providers/Microsoft.Web/hostingenvironments/aseforsites")
.overwrite(false)
.sourceWebAppId("/subscriptions/34adfa4f-cedf-4dc0-ba29-b6d1a69ab345/resourceGroups/testrg456/providers/Microsoft.Web/sites/srcsiteg478")
.sourceWebAppLocation("West Europe")
.build())
.kind("app")
.location("East US")
.name("sitef6141")
.resourceGroupName("testrg123")
.build());
}
}
resources:
webApp:
type: azure-native:web:WebApp
properties:
cloningInfo:
appSettingsOverrides:
Setting1: NewValue1
Setting3: NewValue5
cloneCustomHostNames: true
cloneSourceControl: true
configureLoadBalancing: false
hostingEnvironment: /subscriptions/34adfa4f-cedf-4dc0-ba29-b6d1a69ab345/resourceGroups/testrg456/providers/Microsoft.Web/hostingenvironments/aseforsites
overwrite: false
sourceWebAppId: /subscriptions/34adfa4f-cedf-4dc0-ba29-b6d1a69ab345/resourceGroups/testrg456/providers/Microsoft.Web/sites/srcsiteg478
sourceWebAppLocation: West Europe
kind: app
location: East US
name: sitef6141
resourceGroupName: testrg123
The cloningInfo block copies an app from sourceWebAppId to a new location. The appSettingsOverrides property selectively replaces settings in the cloned app without modifying the source. Setting cloneCustomHostNames and cloneSourceControl to true copies custom domains and Git configuration. The overwrite property controls whether to replace an existing app at the destination.
Beyond these examples
These snippets focus on specific web app features: App Service plan association and Flex Consumption configuration, function runtime, scaling, and deployment storage, and app cloning with configuration overrides. They’re intentionally minimal rather than full application deployments.
The examples reference pre-existing infrastructure such as App Service plans or Flex Consumption hosting, storage accounts for function deployment and state, Application Insights for monitoring, and source web apps for cloning scenarios. They focus on configuring the web app resource rather than provisioning the surrounding infrastructure.
To keep things focused, common web app patterns are omitted, including:
- Site configuration (siteConfig block with connection strings, handlers, runtime versions)
- Managed identity and Key Vault integration
- Virtual network integration (virtualNetworkSubnetId)
- Custom domains and SSL certificates (hostNameSslStates)
- HTTPS enforcement and client certificate authentication
- Deployment slots and swap operations
These omissions are intentional: the goal is to illustrate how each web app feature is wired, not provide drop-in application modules. See the WebApp resource reference for all available configuration options.
Let's deploy Azure App Service Web Apps
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Resource Configuration & Immutability
location, name, kind, cloningInfo, hostingEnvironmentProfile, hyperV, isXenon, and reserved.siteConfig property may contain sensitive information and isn’t returned in normal create and read responses. You’ll need to query it explicitly if needed.hyperV. The isXenon property is obsolete and maintained only for backward compatibility.kind property determines the app type (web app, function app, mobile backend, or API app). It’s immutable after creation. For app resources, refer to Azure documentation for supported values and format requirements.cloningInfo with sourceWebAppId and sourceWebAppLocation. You can optionally override app settings, clone custom hostnames, and clone source control using appSettingsOverrides, cloneCustomHostNames, and cloneSourceControl.Security & Networking
clientCertEnabled to true to enable TLS mutual authentication. Then configure clientCertMode as Required (certificate mandatory) or Optional (certificate accepted but not required). When clientCertEnabled is false, clientCertMode is ignored.httpsOnly to true. This configures the app to accept only HTTPS requests and issues redirects for HTTP requests.virtualNetworkSubnetId with the Azure Resource Manager ID in the format /subscriptions/{subscriptionName}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworks/{vnetName}/subnets/{subnetName} for Regional VNET Integration.Function Apps & Flex Consumption
kind to functionapp,linux and configure functionAppConfig with three main sections: deployment.storage (authentication and blob container URL), runtime (name like python and version like 3.11), and scaleAndConcurrency (instanceMemoryMB and maximumInstanceCount). Include AzureWebJobsStorage and APPLICATIONINSIGHTS_CONNECTION_STRING in siteConfig.appSettings.functionAppConfig.scaleAndConcurrency.alwaysReady to specify pre-warmed instances with instanceCount and trigger name. For HTTP triggers, set triggers.http.perInstanceConcurrency to control concurrent requests per instance.