Azure App Services and Serverless Computing


Welcome back to our Azure Compute series! After exploring Virtual Machines and Scale Sets, let's dive into Azure's Platform-as-a-Service (PaaS) offerings: Azure App Services and Azure Functions. These services enable you to build and deploy applications without managing the underlying infrastructure.
Azure App Services: Web Apps Made Simple
What is Azure App Service?
Azure App Service is a fully managed platform for building, deploying, and scaling web apps. It supports multiple programming languages and frameworks, allowing developers to focus on writing code rather than managing servers.
Key Features
- Multiple Language Support: ASP.NET, .NET Core, Java, Ruby, Node.js, PHP, Python
- Built-in DevOps: Continuous integration and deployment from GitHub, Azure DevOps, and more
- Auto-scaling: Automatically scale based on demand
- Global Scale: Deploy to multiple regions worldwide
- Security and Compliance: Built-in authentication, SSL certificates, and compliance certifications
Types of App Services
1. Web Apps
Host web applications and REST APIs:
# Create a web app
az webapp create \
--resource-group myResourceGroup \
--plan myAppServicePlan \
--name myUniqueWebApp \
--runtime "DOTNET|8.0"
2. API Apps
Build and host RESTful APIs:
# Deploy API app with continuous deployment
az webapp deployment source config \
--name myApiApp \
--resource-group myResourceGroup \
--repo-url https://github.com/username/api-repo \
--branch main \
--manual-integration
3. Mobile Apps
Backend services for mobile applications:
# Create mobile app backend
az webapp create \
--resource-group myResourceGroup \
--plan myAppServicePlan \
--name myMobileBackend \
--runtime "DOTNETCORE|6.0"
App Service Plans
App Service Plans define the compute resources for your apps:
Tier | Best For | Features |
Free/Shared | Development, testing | Limited resources, no custom domains |
Basic | Small production apps | Custom domains, SSL, manual scale |
Standard | Production workloads | Auto-scale, staging slots, daily backups |
Premium | High-performance apps | Advanced auto-scale, VNet integration |
Isolated | Enterprise apps | Dedicated environment, advanced security |
Deployment Slots
Deployment slots enable zero-downtime deployments:
# Create a staging slot
az webapp deployment slot create \
--name myWebApp \
--resource-group myResourceGroup \
--slot staging
# Deploy to staging
az webapp deployment source config \
--name myWebApp \
--resource-group myResourceGroup \
--slot staging \
--repo-url https://github.com/username/app-repo
# Swap staging to production
az webapp deployment slot swap \
--name myWebApp \
--resource-group myResourceGroup \
--slot staging \
--target-slot production
Azure Functions: Serverless Computing
What are Azure Functions?
Azure Functions is a serverless compute service that lets you run event-driven code without managing infrastructure. You pay only for the time your code runs, making it cost-effective for sporadic workloads.
Key Benefits
- Event-Driven: Triggered by various events (HTTP requests, timers, storage changes)
- Pay-per-Execution: Only pay when your function runs
- Auto-Scaling: Automatically scales from zero to thousands of instances
- Multiple Languages: C#, JavaScript, Python, Java, PowerShell, and more
Function Triggers
HTTP Trigger
[FunctionName("HttpTriggerCSharp")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
string name = req.Query["name"];
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
dynamic data = JsonConvert.DeserializeObject(requestBody);
name = name ?? data?.name;
string responseMessage = string.IsNullOrEmpty(name)
? "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."
: $"Hello, {name}. This HTTP triggered function executed successfully.";
return new OkObjectResult(responseMessage);
}
Timer Trigger
[FunctionName("TimerTriggerCSharp")]
public static void Run([TimerTrigger("0 */5 * * * *")]TimerInfo myTimer, ILogger log)
{
log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");
}
Blob Storage Trigger
[FunctionName("BlobTriggerCSharp")]
public static void Run(
[BlobTrigger("samples-workitems/{name}", Connection = "AzureWebJobsStorage")] Stream myBlob,
string name,
ILogger log)
{
log.LogInformation($"C# Blob trigger function processed blob\n"
$"Name: {name}\n"
$"Blob Size: {myBlob.Length} bytes");
// Process the blob content
// Example: Read blob content
using (var reader = new StreamReader(myBlob))
{
string content = reader.ReadToEnd();
log.LogInformation($"Blob content: {content}");
}
}
Service Bus Queue Trigger
[FunctionName("ServiceBusQueueTrigger")]
public static async Task Run(
[ServiceBusTrigger("myqueue", Connection = "ServiceBusConnection")] string myQueueItem,
ILogger log)
{
log.LogInformation($"C# ServiceBus queue trigger function processed message: {myQueueItem}");
try
{
// Process the queue message
var order = JsonConvert.DeserializeObject<Order>(myQueueItem);
// Business logic here
await ProcessOrderAsync(order);
log.LogInformation($"Successfully processed order {order.Id}");
}
catch (Exception ex)
{
log.LogError(ex, "Error processing queue message");
throw; // Re-throw to handle poison messages
}
}
private static async Task ProcessOrderAsync(Order order)
{
// Implementation here
await Task.CompletedTask;
}
public class Order
{
public string Id { get; set; }
public string CustomerId { get; set; }
public decimal Amount { get; set; }
}
Dependency Injection Example
// Startup.cs
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddHttpClient();
builder.Services.AddScoped<IOrderService, OrderService>();
builder.Services.AddSingleton<IConfiguration>(provider =>
{
var config = new ConfigurationBuilder()
.AddEnvironmentVariables()
.Build();
return config;
});
}
}
// Function with Dependency Injection
public class OrderFunction
{
private readonly IOrderService _orderService;
private readonly ILogger<OrderFunction> _logger;
public OrderFunction(IOrderService orderService, ILogger<OrderFunction> logger)
{
_orderService = orderService;
_logger = logger;
}
[FunctionName("ProcessOrder")]
public async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "post", Route = "orders")] HttpRequest req)
{
try
{
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
var order = JsonConvert.DeserializeObject<Order>(requestBody);
var result = await _orderService.ProcessOrderAsync(order);
return new OkObjectResult(result);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error processing order");
return new BadRequestObjectResult("Failed to process order");
}
}
}
public interface IOrderService
{
Task<string> ProcessOrderAsync(Order order);
}
public class OrderService : IOrderService
{
public async Task<string> ProcessOrderAsync(Order order)
{
// Business logic implementation
await Task.Delay(100); // Simulate processing
return $"Order {order.Id} processed successfully";
}
}
Creating Azure Functions
# Create a function app
az functionapp create \
--resource-group myResourceGroup \
--consumption-plan-location eastus \
--runtime dotnet \
--runtime-version 8 \
--functions-version 4 \
--name myFunctionApp \
--storage-account mystorageaccount
Hosting Plans
1. Consumption Plan
- Pay-per-execution
- Automatic scaling
- 5-minute execution timeout (default)
2. Premium Plan
- Pre-warmed instances
- Unlimited execution duration
- VNet connectivity
3. Dedicated Plan
- Run on App Service Plan
- Predictable pricing
- Full control over scaling
Durable Functions
For complex, stateful functions in serverless environments:
[FunctionName("OrderProcessing")]
public static async Task<string> RunOrchestrator(
[OrchestrationTrigger] IDurableOrchestrationContext context)
{
var orderId = context.GetInput<string>();
// Step 1: Validate order
await context.CallActivityAsync("ValidateOrder", orderId);
// Step 2: Process payment
await context.CallActivityAsync("ProcessPayment", orderId);
// Step 3: Ship order
await context.CallActivityAsync("ShipOrder", orderId);
return "Order processed successfully";
}
Best Practices
App Services
- Use Deployment Slots: Implement blue-green deployments
- Enable Application Insights: Monitor performance and errors
- Configure Auto-Scale: Handle traffic variations automatically
- Secure Your Apps: Use authentication providers and SSL certificates
- Optimize Performance: Use CDN for static content
Azure Functions (.NET Specific)
- Keep Functions Small: Single responsibility principle
- Handle Cold Starts: Use Premium plans for consistent performance
- Use Dependency Injection: Register services in
Startup.cs
for better testability - Implement Proper Error Handling: Use try-catch and structured logging
- Async/Await Best Practices: Use
ConfigureAwait(false)
for better performance - Secure Function Keys: Rotate keys regularly and use Azure Key Vault
- NuGet Package Management: Keep packages updated and minimize dependencies
- Monitor Costs: Watch execution counts and duration
Real-World Architecture Example
E-commerce Platform
Frontend (React) → App Service
↓
API Gateway → Azure Functions
↓
┌─────────────────────────┐
│ • User Authentication │
│ • Order Processing │
│ • Inventory Updates │
│ • Email Notifications │
└─────────────────────────┘
↓
Azure Storage + Cosmos DB
Implementation Steps
- Frontend: Deploy React app to App Service
- API Functions: Create HTTP-triggered functions for each API endpoint
- Background Processing: Use queue-triggered functions for async tasks
- Monitoring: Implement Application Insights across all services
Cost Optimization
App Services
- Right-size your plan: Start small and scale up as needed
- Use shared plans: For development and testing
- Implement auto-shutdown: For non-production environments
Azure Functions
- Optimize execution time: Reduce function duration
- Use appropriate hosting plans: Consumption for sporadic loads
- Implement efficient triggers: Avoid unnecessary executions
Monitoring and Debugging
Application Insights Integration
public static class Function1
{
[FunctionName("Function1")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
// Your function logic here
return new OkObjectResult("Function executed successfully");
}
}
Log Analytics Queries
// Function execution times
requests
| where cloud_RoleName == "myFunctionApp"
| summarize avg(duration), count() by name
| order by avg_duration desc
Common Pitfalls to Avoid
- Over-provisioning App Service Plans: Choose the right tier for your needs
- Ignoring Cold Starts: Consider Premium functions for consistent performance
- Not implementing proper monitoring: Set up alerts and dashboards
- Security oversights: Always use HTTPS and implement authentication
- Lack of error handling: Implement comprehensive error handling and logging
What's Next?
In our next post, we'll explore Container Services in Azure, covering:
- Azure Container Instances (ACI)
- Azure Kubernetes Service (AKS)
- Azure Container Registry
- Container deployment strategies
Conclusion
Azure App Services and Functions provide powerful platforms for building modern, scalable applications. App Services offer a managed environment for web applications, while Functions enable serverless architectures that can significantly reduce costs and complexity.
By combining these services, you can build robust, scalable applications that automatically adapt to demand while minimizing operational overhead.
Key Takeaways:
- App Services provide managed hosting for web applications and APIs
- Azure Functions enable event-driven, serverless computing
- Both services integrate seamlessly with other Azure services
- Choose the right hosting plan based on your performance and cost requirements
- Implement proper monitoring and security from the start
Tags: Azure, App Services, Azure Functions, Serverless, PaaS, Web Applications
Category: Azure Compute Series
Estimated Reading Time: 12 minutes
Subscribe to my newsletter
Read articles from Nilay Barot directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Nilay Barot
Nilay Barot
As an experienced software engineer with a demonstrated history of working in the computer software industry, I'm skilled in Win Forms, WPF, ASP.NET Web forms, C++, C#, JavaScript, React and Go. I'm a software engineering professional with a Bachelor of Engineering - BE focused in Computer Engineering from Mahatma Gandhi Institute of Technology. Throughout my career, I've been passionate about building high-quality software that meets the needs of users, and I'm always striving to learn and grow as a developer. With a keen eye for detail and a commitment to excellence, I'm dedicated to delivering results that exceed expectations. In my free time, I enjoy reading books on technology, playing video games, and exploring new software development trends. Let's connect on LinkedIn and share our experiences as technology enthusiasts.