azure-functions

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Azure Functions

Azure Functions

Build and deploy serverless applications with Azure Functions. Covers function app creation, trigger and binding configuration, deployment strategies, real code examples in Python and Node.js, and production best practices.
使用Azure Functions构建并部署无服务器应用程序。内容涵盖函数应用创建、触发器与绑定配置、部署策略、Python和Node.js的真实代码示例,以及生产环境最佳实践。

When to Use

适用场景

  • You need event-driven compute that scales automatically to zero.
  • You are building APIs, webhooks, or background processing pipelines.
  • You want per-execution billing without managing servers.
  • You need to respond to Azure service events (Blob Storage, Service Bus, Cosmos DB changes).
  • You are implementing lightweight microservices or scheduled tasks.
  • 需要可自动缩容至零的事件驱动型计算能力。
  • 正在构建API、Webhook或后台处理流水线。
  • 希望按执行次数计费,无需管理服务器。
  • 需要响应Azure服务事件(Blob存储、服务总线、Cosmos DB变更)。
  • 正在实现轻量级微服务或定时任务。

Prerequisites

前置条件

bash
undefined
bash
undefined

Install Azure CLI

Install Azure CLI

Install Azure Functions Core Tools v4

Install Azure Functions Core Tools v4

npm install -g azure-functions-core-tools@4
npm install -g azure-functions-core-tools@4

Verify installation

Verify installation

func --version
func --version

Login

Login

az login az account set --subscription "my-subscription-id"
az login az account set --subscription "my-subscription-id"

Create supporting resources

Create supporting resources

az group create --name functions-rg --location eastus
az storage account create
--name myfuncstorageacct
--resource-group functions-rg
--location eastus
--sku Standard_LRS
undefined
az group create --name functions-rg --location eastus
az storage account create
--name myfuncstorageacct
--resource-group functions-rg
--location eastus
--sku Standard_LRS
undefined

Function App Creation

函数应用创建

Consumption Plan (Pay-per-execution)

消耗计划(按执行付费)

bash
undefined
bash
undefined

Python function app on Consumption plan

Python function app on Consumption plan

az functionapp create
--resource-group functions-rg
--consumption-plan-location eastus
--runtime python
--runtime-version 3.11
--functions-version 4
--name myapp-func
--storage-account myfuncstorageacct
--os-type Linux
az functionapp create
--resource-group functions-rg
--consumption-plan-location eastus
--runtime python
--runtime-version 3.11
--functions-version 4
--name myapp-func
--storage-account myfuncstorageacct
--os-type Linux

Node.js function app

Node.js function app

az functionapp create
--resource-group functions-rg
--consumption-plan-location eastus
--runtime node
--runtime-version 20
--functions-version 4
--name myapp-node-func
--storage-account myfuncstorageacct
--os-type Linux
undefined
az functionapp create
--resource-group functions-rg
--consumption-plan-location eastus
--runtime node
--runtime-version 20
--functions-version 4
--name myapp-node-func
--storage-account myfuncstorageacct
--os-type Linux
undefined

Premium Plan (VNet integration, no cold start)

高级计划(支持VNet集成,无冷启动)

bash
undefined
bash
undefined

Create Premium plan

Create Premium plan

az functionapp plan create
--resource-group functions-rg
--name myapp-premium-plan
--location eastus
--sku EP1
--is-linux true
az functionapp plan create
--resource-group functions-rg
--name myapp-premium-plan
--location eastus
--sku EP1
--is-linux true

Create function app on Premium plan

Create function app on Premium plan

az functionapp create
--resource-group functions-rg
--plan myapp-premium-plan
--runtime python
--runtime-version 3.11
--functions-version 4
--name myapp-premium-func
--storage-account myfuncstorageacct
undefined
az functionapp create
--resource-group functions-rg
--plan myapp-premium-plan
--runtime python
--runtime-version 3.11
--functions-version 4
--name myapp-premium-func
--storage-account myfuncstorageacct
undefined

Trigger and Binding Examples

触发器与绑定示例

HTTP Trigger -- Python

HTTP Trigger -- Python

python
undefined
python
undefined

function_app.py (v2 programming model)

function_app.py (v2 programming model)

import azure.functions as func import json import logging
app = func.FunctionApp(http_auth_level=func.AuthLevel.FUNCTION)
@app.route(route="users/{userId}", methods=["GET"]) def get_user(req: func.HttpRequest) -> func.HttpResponse: user_id = req.route_params.get("userId") logging.info(f"Fetching user: {user_id}")
if not user_id:
    return func.HttpResponse(
        json.dumps({"error": "userId is required"}),
        status_code=400,
        mimetype="application/json"
    )

user = {"id": user_id, "name": "Jane Doe", "email": "jane@example.com"}
return func.HttpResponse(
    json.dumps(user),
    status_code=200,
    mimetype="application/json"
)
@app.route(route="users", methods=["POST"]) def create_user(req: func.HttpRequest) -> func.HttpResponse: try: body = req.get_json() except ValueError: return func.HttpResponse( json.dumps({"error": "Invalid JSON"}), status_code=400, mimetype="application/json" )
logging.info(f"Creating user: {body.get('name')}")
return func.HttpResponse(
    json.dumps({"id": "new-id", **body}),
    status_code=201,
    mimetype="application/json"
)
undefined
import azure.functions as func import json import logging
app = func.FunctionApp(http_auth_level=func.AuthLevel.FUNCTION)
@app.route(route="users/{userId}", methods=["GET"]) def get_user(req: func.HttpRequest) -> func.HttpResponse: user_id = req.route_params.get("userId") logging.info(f"Fetching user: {user_id}")
if not user_id:
    return func.HttpResponse(
        json.dumps({"error": "userId is required"}),
        status_code=400,
        mimetype="application/json"
    )

user = {"id": user_id, "name": "Jane Doe", "email": "jane@example.com"}
return func.HttpResponse(
    json.dumps(user),
    status_code=200,
    mimetype="application/json"
)
@app.route(route="users", methods=["POST"]) def create_user(req: func.HttpRequest) -> func.HttpResponse: try: body = req.get_json() except ValueError: return func.HttpResponse( json.dumps({"error": "Invalid JSON"}), status_code=400, mimetype="application/json" )
logging.info(f"Creating user: {body.get('name')}")
return func.HttpResponse(
    json.dumps({"id": "new-id", **body}),
    status_code=201,
    mimetype="application/json"
)
undefined

HTTP Trigger -- Node.js

HTTP Trigger -- Node.js

javascript
// src/functions/httpTrigger.js (v4 programming model)
const { app } = require("@azure/functions");

app.http("getUser", {
  methods: ["GET"],
  authLevel: "function",
  route: "users/{userId}",
  handler: async (request, context) => {
    const userId = request.params.userId;
    context.log(`Fetching user: ${userId}`);

    if (!userId) {
      return { status: 400, jsonBody: { error: "userId is required" } };
    }

    const user = { id: userId, name: "Jane Doe", email: "jane@example.com" };
    return { status: 200, jsonBody: user };
  },
});

app.http("createUser", {
  methods: ["POST"],
  authLevel: "function",
  route: "users",
  handler: async (request, context) => {
    const body = await request.json();
    context.log(`Creating user: ${body.name}`);

    return { status: 201, jsonBody: { id: "new-id", ...body } };
  },
});
javascript
// src/functions/httpTrigger.js (v4 programming model)
const { app } = require("@azure/functions");

app.http("getUser", {
  methods: ["GET"],
  authLevel: "function",
  route: "users/{userId}",
  handler: async (request, context) => {
    const userId = request.params.userId;
    context.log(`Fetching user: ${userId}`);

    if (!userId) {
      return { status: 400, jsonBody: { error: "userId is required" } };
    }

    const user = { id: userId, name: "Jane Doe", email: "jane@example.com" };
    return { status: 200, jsonBody: user };
  },
});

app.http("createUser", {
  methods: ["POST"],
  authLevel: "function",
  route: "users",
  handler: async (request, context) => {
    const body = await request.json();
    context.log(`Creating user: ${body.name}`);

    return { status: 201, jsonBody: { id: "new-id", ...body } };
  },
});

Blob Trigger -- Python

Blob Trigger -- Python

python
@app.blob_trigger(arg_name="blob", path="uploads/{name}",
                   connection="AzureWebJobsStorage")
def process_upload(blob: func.InputStream):
    logging.info(f"Processing blob: {blob.name}, Size: {blob.length} bytes")
    content = blob.read()
    # Process file content here
python
@app.blob_trigger(arg_name="blob", path="uploads/{name}",
                   connection="AzureWebJobsStorage")
def process_upload(blob: func.InputStream):
    logging.info(f"Processing blob: {blob.name}, Size: {blob.length} bytes")
    content = blob.read()
    # Process file content here

Timer Trigger -- Python

Timer Trigger -- Python

python
@app.timer_trigger(schedule="0 */5 * * * *", arg_name="timer",
                    run_on_startup=False)
def cleanup_job(timer: func.TimerRequest):
    if timer.past_due:
        logging.warning("Timer is past due")
    logging.info("Running scheduled cleanup")
    # Cleanup logic here
python
@app.timer_trigger(schedule="0 */5 * * * *", arg_name="timer",
                    run_on_startup=False)
def cleanup_job(timer: func.TimerRequest):
    if timer.past_due:
        logging.warning("Timer is past due")
    logging.info("Running scheduled cleanup")
    # Cleanup logic here

Service Bus Trigger -- Python

Service Bus Trigger -- Python

python
@app.service_bus_queue_trigger(arg_name="msg", queue_name="orders",
                                connection="ServiceBusConnection")
@app.cosmos_db_output(arg_name="doc", database_name="mydb",
                       container_name="processed-orders",
                       connection="CosmosDBConnection")
def process_order(msg: func.ServiceBusMessage, doc: func.Out[func.Document]):
    order = json.loads(msg.get_body().decode("utf-8"))
    logging.info(f"Processing order: {order['id']}")

    processed = {
        "id": order["id"],
        "status": "processed",
        "items": order["items"],
        "total": sum(item["price"] for item in order["items"])
    }
    doc.set(func.Document.from_dict(processed))
python
@app.service_bus_queue_trigger(arg_name="msg", queue_name="orders",
                                connection="ServiceBusConnection")
@app.cosmos_db_output(arg_name="doc", database_name="mydb",
                       container_name="processed-orders",
                       connection="CosmosDBConnection")
def process_order(msg: func.ServiceBusMessage, doc: func.Out[func.Document]):
    order = json.loads(msg.get_body().decode("utf-8"))
    logging.info(f"Processing order: {order['id']}")

    processed = {
        "id": order["id"],
        "status": "processed",
        "items": order["items"],
        "total": sum(item["price"] for item in order["items"])
    }
    doc.set(func.Document.from_dict(processed))

Cosmos DB Change Feed Trigger -- Python

Cosmos DB Change Feed Trigger -- Python

python
@app.cosmos_db_trigger_v3(arg_name="documents", database_name="mydb",
                           container_name="orders",
                           connection="CosmosDBConnection",
                           lease_container_name="leases",
                           create_lease_container_if_not_exists=True)
def on_order_change(documents: func.DocumentList):
    for doc in documents:
        logging.info(f"Document changed: {doc['id']}")
python
@app.cosmos_db_trigger_v3(arg_name="documents", database_name="mydb",
                           container_name="orders",
                           connection="CosmosDBConnection",
                           lease_container_name="leases",
                           create_lease_container_if_not_exists=True)
def on_order_change(documents: func.DocumentList):
    for doc in documents:
        logging.info(f"Document changed: {doc['id']}")

Local Development

本地开发

bash
undefined
bash
undefined

Initialize a new Python function project

Initialize a new Python function project

func init MyFunctionProject --python cd MyFunctionProject
func init MyFunctionProject --python cd MyFunctionProject

Create a new function from template

Create a new function from template

func new --name HttpExample --template "HTTP trigger" --authlevel function
func new --name HttpExample --template "HTTP trigger" --authlevel function

Run locally

Run locally

func start
func start

Run locally with specific port

Run locally with specific port

func start --port 7072
func start --port 7072

Test locally

Test locally

Deployment

部署

bash
undefined
bash
undefined

Deploy using Core Tools

Deploy using Core Tools

func azure functionapp publish myapp-func
func azure functionapp publish myapp-func

Deploy with build step for Python

Deploy with build step for Python

func azure functionapp publish myapp-func --build remote
func azure functionapp publish myapp-func --build remote

Deploy using ZIP package

Deploy using ZIP package

zip -r function.zip . -x ".git/" ".venv/" "pycache/*" az functionapp deployment source config-zip
--resource-group functions-rg
--name myapp-func
--src function.zip
zip -r function.zip . -x ".git/" ".venv/" "pycache/*" az functionapp deployment source config-zip
--resource-group functions-rg
--name myapp-func
--src function.zip

Deploy via CI/CD with GitHub Actions

Deploy via CI/CD with GitHub Actions

az functionapp deployment github-actions add
--resource-group functions-rg
--name myapp-func
--repo "myorg/myrepo"
--branch main
--runtime python
--login-with-github
undefined
az functionapp deployment github-actions add
--resource-group functions-rg
--name myapp-func
--repo "myorg/myrepo"
--branch main
--runtime python
--login-with-github
undefined

Deployment Slots

部署槽

bash
undefined
bash
undefined

Create a staging slot

Create a staging slot

az functionapp deployment slot create
--resource-group functions-rg
--name myapp-func
--slot staging
az functionapp deployment slot create
--resource-group functions-rg
--name myapp-func
--slot staging

Deploy to staging slot

Deploy to staging slot

func azure functionapp publish myapp-func --slot staging
func azure functionapp publish myapp-func --slot staging

Test staging slot

Test staging slot

Swap staging to production

Swap staging to production

az functionapp deployment slot swap
--resource-group functions-rg
--name myapp-func
--slot staging
--target-slot production
az functionapp deployment slot swap
--resource-group functions-rg
--name myapp-func
--slot staging
--target-slot production

Roll back by swapping again

Roll back by swapping again

az functionapp deployment slot swap
--resource-group functions-rg
--name myapp-func
--slot staging
--target-slot production
undefined
az functionapp deployment slot swap
--resource-group functions-rg
--name myapp-func
--slot staging
--target-slot production
undefined

Application Settings and Security

应用设置与安全

bash
undefined
bash
undefined

Set application settings

Set application settings

az functionapp config appsettings set
--resource-group functions-rg
--name myapp-func
--settings
ServiceBusConnection="Endpoint=sb://..."
CosmosDBConnection="AccountEndpoint=https://..."
CUSTOM_SETTING="my-value"
az functionapp config appsettings set
--resource-group functions-rg
--name myapp-func
--settings
ServiceBusConnection="Endpoint=sb://..."
CosmosDBConnection="AccountEndpoint=https://..."
CUSTOM_SETTING="my-value"

Set settings as slot-specific

Set settings as slot-specific

az functionapp config appsettings set
--resource-group functions-rg
--name myapp-func
--slot-settings
ENVIRONMENT="staging"
az functionapp config appsettings set
--resource-group functions-rg
--name myapp-func
--slot-settings
ENVIRONMENT="staging"

Enable managed identity

Enable managed identity

az functionapp identity assign
--resource-group functions-rg
--name myapp-func
az functionapp identity assign
--resource-group functions-rg
--name myapp-func

Configure CORS

Configure CORS

az functionapp cors add
--resource-group functions-rg
--name myapp-func
--allowed-origins "https://myapp.example.com"
az functionapp cors add
--resource-group functions-rg
--name myapp-func
--allowed-origins "https://myapp.example.com"

Set minimum TLS version

Set minimum TLS version

az functionapp config set
--resource-group functions-rg
--name myapp-func
--min-tls-version 1.2
az functionapp config set
--resource-group functions-rg
--name myapp-func
--min-tls-version 1.2

Enable Application Insights

Enable Application Insights

az functionapp config appsettings set
--resource-group functions-rg
--name myapp-func
--settings APPINSIGHTS_INSTRUMENTATIONKEY="your-key"
undefined
az functionapp config appsettings set
--resource-group functions-rg
--name myapp-func
--settings APPINSIGHTS_INSTRUMENTATIONKEY="your-key"
undefined

Terraform Configuration

Terraform配置

hcl
resource "azurerm_service_plan" "functions" {
  name                = "myapp-func-plan"
  location            = azurerm_resource_group.main.location
  resource_group_name = azurerm_resource_group.main.name
  os_type             = "Linux"
  sku_name            = "Y1"  # Consumption plan
}

resource "azurerm_linux_function_app" "main" {
  name                       = "myapp-func"
  location                   = azurerm_resource_group.main.location
  resource_group_name        = azurerm_resource_group.main.name
  service_plan_id            = azurerm_service_plan.functions.id
  storage_account_name       = azurerm_storage_account.func.name
  storage_account_access_key = azurerm_storage_account.func.primary_access_key

  identity {
    type = "SystemAssigned"
  }

  site_config {
    application_stack {
      python_version = "3.11"
    }
    cors {
      allowed_origins = ["https://myapp.example.com"]
    }
  }

  app_settings = {
    FUNCTIONS_WORKER_RUNTIME       = "python"
    WEBSITE_RUN_FROM_PACKAGE       = "1"
    APPINSIGHTS_INSTRUMENTATIONKEY = azurerm_application_insights.main.instrumentation_key
  }

  tags = var.tags
}
hcl
resource "azurerm_service_plan" "functions" {
  name                = "myapp-func-plan"
  location            = azurerm_resource_group.main.location
  resource_group_name = azurerm_resource_group.main.name
  os_type             = "Linux"
  sku_name            = "Y1"  # Consumption plan
}

resource "azurerm_linux_function_app" "main" {
  name                       = "myapp-func"
  location                   = azurerm_resource_group.main.location
  resource_group_name        = azurerm_resource_group.main.name
  service_plan_id            = azurerm_service_plan.functions.id
  storage_account_name       = azurerm_storage_account.func.name
  storage_account_access_key = azurerm_storage_account.func.primary_access_key

  identity {
    type = "SystemAssigned"
  }

  site_config {
    application_stack {
      python_version = "3.11"
    }
    cors {
      allowed_origins = ["https://myapp.example.com"]
    }
  }

  app_settings = {
    FUNCTIONS_WORKER_RUNTIME       = "python"
    WEBSITE_RUN_FROM_PACKAGE       = "1"
    APPINSIGHTS_INSTRUMENTATIONKEY = azurerm_application_insights.main.instrumentation_key
  }

  tags = var.tags
}

Troubleshooting

故障排查

SymptomCauseFix
Cold start latency > 10sConsumption plan cold startUse Premium plan (EP1+) or enable
WEBSITE_RUN_FROM_PACKAGE=1
Function not triggeringConnection string misconfiguredCheck
az functionapp config appsettings list
for correct binding values
ModuleNotFoundError
in Python
Dependencies not installed during deployUse
--build remote
flag or include
requirements.txt
in package
HTTP 401 UnauthorizedAuth level mismatch or missing function keyVerify auth level in code matches expectations; pass
x-functions-key
header
Blob trigger not firingStorage account connection wrongVerify
AzureWebJobsStorage
points to the correct account
Timer trigger runs twiceMultiple instances on Premium planSet
WEBSITE_MAX_DYNAMIC_APPLICATION_SCALE_OUT=1
or use singleton lock
Deployment slot swap failsSlot settings not configuredEnsure slot-specific settings are marked with
--slot-settings
Out of memory errorsLarge payloads or memory leaksStream data instead of loading entirely; increase plan tier
症状原因解决方法
冷启动延迟>10秒消耗计划冷启动使用高级计划(EP1+)或启用
WEBSITE_RUN_FROM_PACKAGE=1
函数未触发连接字符串配置错误检查
az functionapp config appsettings list
中的绑定值是否正确
Python中出现
ModuleNotFoundError
部署时未安装依赖使用
--build remote
参数,或在包中包含
requirements.txt
HTTP 401未授权认证级别不匹配或缺少函数密钥验证代码中的认证级别是否符合预期;传递
x-functions-key
请求头
Blob触发器未触发存储账户连接错误验证
AzureWebJobsStorage
指向正确的账户
定时器触发器执行两次高级计划上存在多个实例设置
WEBSITE_MAX_DYNAMIC_APPLICATION_SCALE_OUT=1
或使用单例锁
部署槽交换失败槽设置未配置确保槽特定设置已通过
--slot-settings
标记
内存不足错误大负载或内存泄漏流式处理数据而非全部加载;提升计划层级

Related Skills

相关技能

  • azure-networking
    -- VNet integration for Premium plan functions accessing private resources.
  • azure-sql
    -- Database connections from function bindings.
  • terraform-azure
    -- Infrastructure as Code for function app provisioning.
  • arm-templates
    -- Bicep-based function app deployment.
  • azure-networking
    -- 高级计划函数访问私有资源的VNet集成。
  • azure-sql
    -- 函数绑定的数据库连接。
  • terraform-azure
    -- 函数应用配置的基础设施即代码。
  • arm-templates
    -- 基于Bicep的函数应用部署。