快速入门:使用 Azure Developer CLI 创建函数并将其部署到 Azure Functions

在本快速入门中,你将使用 Azure 开发人员命令行工具创建响应 HTTP 请求的函数。 在本地测试代码后,将其部署到你创建的在 Azure Functions 的 Flex 消耗计划中运行的新无服务器函数应用中。

项目源使用 Azure Developer CLI (azd) 来简化将代码部署到 Azure 的过程。 此部署遵循安全且可缩放的 Azure Functions 部署的当前最佳做法。

重要

弹性消耗计划目前为预览版。

默认情况下,Flex 消耗计划采用按使用量付费的计费模式,这意味着完成此快速入门只需在你的 Azure 帐户中支付几美分或更少费用。

先决条件

初始化项目

可以使用 azd init 命令从模板创建本地 Azure Functions 代码项目。

  1. 在本地终端或命令提示符下,在空文件夹中运行此 azd init 命令:

    azd init --template functions-quickstart-dotnet-azd -e flexquickstart-dotnet
    

    此命令从模板存储库中拉取项目文件,并在当前文件夹中初始化项目。 -e 标志设置当前环境的名称。 在 azd 中,环境用于维护应用的唯一部署上下文,你可以定义多个环境。 它也在 Azure 中你创建的资源组名称中使用。

  2. 运行此命令以导航到 http 应用文件夹:

    cd http
    
  3. 在包含此 JSON 数据的 http 文件夹中创建名为 local.settings.json 的文件:

    {
        "IsEncrypted": false,
        "Values": {
            "AzureWebJobsStorage": "UseDevelopmentStorage=true",
            "FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated"
        }
    }
    

    在本地运行时,需要此文件。

  1. 在本地终端或命令提示符下,在空文件夹中运行此 azd init 命令:

    azd init --template azure-functions-java-flex-consumption-azd -e flexquickstart-java 
    

    此命令从模板存储库中拉取项目文件,并在当前文件夹中初始化项目。 -e 标志设置当前环境的名称。 在 azd 中,环境用于维护应用的唯一部署上下文,你可以定义多个环境。 它也在 Azure 中你创建的资源组名称中使用。

  2. 运行此命令以导航到 http 应用文件夹:

    cd http
    
  3. 在包含此 JSON 数据的 http 文件夹中创建名为 local.settings.json 的文件:

    {
        "IsEncrypted": false,
        "Values": {
            "AzureWebJobsStorage": "UseDevelopmentStorage=true",
            "FUNCTIONS_WORKER_RUNTIME": "java"
        }
    }
    

    在本地运行时,需要此文件。

  1. 在本地终端或命令提示符下,在空文件夹中运行此 azd init 命令:

    azd init --template functions-quickstart-javascript-azd -e flexquickstart-js
    

    此命令从模板存储库中拉取项目文件,并在根文件夹中初始化项目。 -e 标志设置当前环境的名称。 在 azd 中,环境用于维护应用的唯一部署上下文,你可以定义多个环境。 它也在 Azure 中你创建的资源组名称中使用。

  2. 在包含此 JSON 数据的根文件夹中创建名为 local.settings.json 的文件

    {
        "IsEncrypted": false,
        "Values": {
            "AzureWebJobsStorage": "UseDevelopmentStorage=true",
            "FUNCTIONS_WORKER_RUNTIME": "node"
        }
    }
    

    在本地运行时,需要此文件。

  1. 在本地终端或命令提示符下,在空文件夹中运行此 azd init 命令:

    azd init --template functions-quickstart-powershell-azd -e flexquickstart-ps
    

    此命令从模板存储库中拉取项目文件,并在根文件夹中初始化项目。 -e 标志设置当前环境的名称。 在 azd 中,环境用于维护应用的唯一部署上下文,你可以定义多个环境。 它也在 Azure 中你创建的资源组名称中使用。

  2. 运行此命令以导航到 src 应用文件夹:

    cd src
    
  3. 在包含此 JSON 数据的 src 文件夹中创建名为 local.settings.json 的文件:

    {
        "IsEncrypted": false,
        "Values": {
            "AzureWebJobsStorage": "UseDevelopmentStorage=true",
            "FUNCTIONS_WORKER_RUNTIME": "powershell",
            "FUNCTIONS_WORKER_RUNTIME_VERSION": "7.2"
        }
    }
    

    在本地运行时,需要此文件。

  1. 在本地终端或命令提示符下,在空文件夹中运行此 azd init 命令:

    azd init --template functions-quickstart-typescript-azd -e flexquickstart-ts
    

    此命令从模板存储库中拉取项目文件,并在根文件夹中初始化项目。 -e 标志设置当前环境的名称。 在 azd 中,环境用于维护应用的唯一部署上下文,你可以定义多个环境。 它也在 Azure 中你创建的资源组名称中使用。

  2. 在包含此 JSON 数据的根文件夹中创建名为 local.settings.json 的文件

    {
        "IsEncrypted": false,
        "Values": {
            "AzureWebJobsStorage": "UseDevelopmentStorage=true",
            "FUNCTIONS_WORKER_RUNTIME": "node"
        }
    }
    

    在本地运行时,需要此文件。

  1. 在本地终端或命令提示符下,在空文件夹中运行此 azd init 命令:

    azd init --template functions-quickstart-python-http-azd -e flexquickstart-py
    

    此命令从模板存储库中拉取项目文件,并在根文件夹中初始化项目。 -e 标志设置当前环境的名称。 在 azd 中,环境用于维护应用的唯一部署上下文,你可以定义多个环境。 它也在 Azure 中你创建的资源组名称中使用。

  2. 在包含此 JSON 数据的根文件夹中创建名为 local.settings.json 的文件

    {
        "IsEncrypted": false,
        "Values": {
            "AzureWebJobsStorage": "UseDevelopmentStorage=true",
            "FUNCTIONS_WORKER_RUNTIME": "python"
        }
    }
    

    在本地运行时,需要此文件。

创建并激活虚拟环境

在根文件夹中,运行以下命令以创建并激活一个名为 .venv 的虚拟环境:

python3 -m venv .venv
source .venv/bin/activate

如果 Python 未在 Linux 分发版中安装 venv 包,请运行以下命令:

sudo apt-get install python3-venv

在本地环境中运行

  1. 在终端或命令提示符下从应用文件夹运行以下命令:

    func start
    
    mvn clean package
    mvn azure-functions:run
    
    npm install
    func start  
    
    npm install
    npm start  
    

    当 Functions 主机在本地项目文件夹中启动时,它会将 HTTP 触发函数的 URL 终结点写入终端输出。

  2. 在浏览器中,导航到 httpget 终结点,该终结点应类似于以下 URL:

    http://localhost:7071/api/httpget

  3. 在新终端或命令提示符窗口中运行此 curl 命令,向 httppost 终结点发送带有 JSON 有效负载的 POST 请求:

    curl -i http://localhost:7071/api/httppost -H "Content-Type: text/json" -d @testdata.json
    
    curl -i http://localhost:7071/api/httppost -H "Content-Type: text/json" -d "@src/functions/testdata.json"
    

    此命令从 testdata.json 项目文件读取 JSON 有效负载数据。 可以在 test.http 项目文件中找到这两个 HTTP 请求的示例。

  4. 完成后,在终端窗口中按 Ctrl+C 停止 func.exe 主机进程。

  1. 运行 deactivate 以关闭虚拟环境。

查看代码(可选)

可以查看定义两个 HTTP 触发器函数终结点的代码:

        [Function("httpget")]
        public IActionResult Run([HttpTrigger(AuthorizationLevel.Function, "get")]
          HttpRequest req,
          string name)
        {
            var returnValue = string.IsNullOrEmpty(name)
                ? "Hello, World."
                : $"Hello, {name}.";

            _logger.LogInformation($"C# HTTP trigger function processed a request for {returnValue}.");

            return new OkObjectResult(returnValue);
        }
    @FunctionName("httpget")
    public HttpResponseMessage run(
            @HttpTrigger(
                name = "req",
                methods = {HttpMethod.GET},
                authLevel = AuthorizationLevel.FUNCTION)
                HttpRequestMessage<Optional<String>> request,
            final ExecutionContext context) {
        context.getLogger().info("Java HTTP trigger processed a request.");

        // Parse query parameter
        String name = Optional.ofNullable(request.getQueryParameters().get("name")).orElse("World");

        return request.createResponseBuilder(HttpStatus.OK).body("Hello, " + name).build();
    }
const { app } = require('@azure/functions');

app.http('httpget', {
    methods: ['GET'],
    authLevel: 'function',
    handler: async (request, context) => {
        context.log(`Http function processed request for url "${request.url}"`);

        const name = request.query.get('name') || await request.text() || 'world';

        return { body: `Hello, ${name}!` };
    }
});
import { app, HttpRequest, HttpResponseInit, InvocationContext } from "@azure/functions";

export async function httpGetFunction(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
    context.log(`Http function processed request for url "${request.url}"`);

    const name = request.query.get('name') || await request.text() || 'world';

    return { body: `Hello, ${name}!` };
};

app.http('httpget', {
    methods: ['GET'],
    authLevel: 'function',
    handler: httpGetFunction
});

function.json 文件定义 httpget 函数:

{
  "bindings": [
    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "Request",
      "methods": [
        "get"
      ],
      "route": "httpget"
    },
    {
      "type": "http",
      "direction": "out",
      "name": "Response"
    }
  ]
}

run.ps1 文件实现函数代码:

using namespace System.Net

# Input bindings are passed in via param block.
param($Request, $TriggerMetadata)

# Write to the Azure Functions log stream.
Write-Host "PowerShell HTTP trigger function processed a request."

# Interact with query parameters
$name = $Request.Query.name

$body = "This HTTP triggered function executed successfully. Pass a name in the query string for a personalized response."

if ($name) {
    $body = "Hello, $name. This HTTP triggered function executed successfully."
}

# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
    StatusCode = [HttpStatusCode]::OK
    Body = $body
})
@app.route(route="httpget", methods=["GET"])
def http_get(req: func.HttpRequest) -> func.HttpResponse:
    name = req.params.get("name", "World")

    logging.info(f"Processing GET request. Name: {name}")

    return func.HttpResponse(f"Hello, {name}!")

可在此处查看完整的模板项目。

可在此处查看完整的模板项目。

可在此处查看完整的模板项目。

可在此处查看完整的模板项目。

可在此处查看完整的模板项目。

可在此处查看完整的模板项目。

在本地验证函数后,可以将其发布到 Azure。

创建 Azure 资源

此项目配置为使用 azd provision 命令在 Flex 消耗计划中创建函数应用,以及其他所需的 Azure 资源。

注意

该项目包括一组 Bicep 文件,azd 使用这些文件可以按照最佳做法为 Flex 消耗计划创建安全部署。

Java 应用目前不支持 azd upazd deploy 命令。

  1. 在项目的根文件夹中,运行以下命令以创建所需的 Azure 资源:

    azd provision
    

    根文件夹包含 azd 所需的 azure.yaml 定义文件。

    如果尚未登录,系统会要求你使用 Azure 帐户进行身份验证。

  2. 出现提示时,请提供以下所需的部署参数:

    参数 描述
    Azure 订阅 要在其中创建资源的订阅。
    Azure 位置 要在其中创建包含新 Azure 资源的资源组的 Azure 区域。 仅显示当前支持 Flex 消耗计划的区域。

    azd provision 命令使用你对这些提示的回复和 Bicep 配置文件来创建和配置这些所需的 Azure 资源:

    • Flex 消耗计划和函数应用
    • Azure 存储(必需)和 Application Insights(推荐)
    • 帐户的访问策略和角色
    • 使用托管标识(而不是存储的连接字符串)的服务到服务连接
    • 安全运行函数应用和其他 Azure 资源的虚拟网络

    命令成功完成后,可以将项目代码部署到 Azure 中的这个新函数应用。

部署到 Azure

可以使用 Core Tools 打包代码,并从 target 输出文件夹将其部署到 Azure。

  1. 导航到 target 输出文件夹中等效的应用文件夹:

    cd http/target/azure-functions/contoso-functions
    

    此文件夹应具有 host.json 文件,该文件指示它是已编译 Java 函数应用的根目录。

  2. 运行以下命令,使用 Core Tools 将已编译的 Java 代码项目部署到 Azure 中的新函数应用资源:

    APP_NAME=$(azd env get-value AZURE_FUNCTION_NAME)
    func azure functionapp publish $APP_NAME
    

    azd env get-value 命令从本地环境中获取函数应用名称,这是使用 func azure functionapp publish进行部署所必需的。 发布成功完成后,可以看到指向 Azure 中的 HTTP 触发器终结点的链接。

部署到 Azure

此项目配置为使用 azd up 命令将此项目部署到 Azure 中 Flex 消耗计划中的新函数应用。

提示

该项目包括一组 Bicep 文件,azd 使用这些文件可以按照最佳做法为 Flex 消耗计划创建安全部署。

  1. 运行以下命令,让 azd 在 Azure 中创建所需的 Azure 资源,并将代码项目部署到新的函数应用:

    azd up
    

    根文件夹包含 azd 所需的 azure.yaml 定义文件。

    如果尚未登录,系统会要求你使用 Azure 帐户进行身份验证。

  2. 出现提示时,请提供以下所需的部署参数:

    参数 描述
    Azure 订阅 要在其中创建资源的订阅。
    Azure 位置 要在其中创建包含新 Azure 资源的资源组的 Azure 区域。 仅显示当前支持 Flex 消耗计划的区域。

    azd up 命令使用你对这些提示的回复和 Bicep 配置文件来完成这些部署任务:

    • 创建和配置这些所需的 Azure 资源(等效于 azd provision):

      • Flex 消耗计划和函数应用
      • Azure 存储(必需)和 Application Insights(推荐)
      • 帐户的访问策略和角色
      • 使用托管标识(而不是存储的连接字符串)的服务到服务连接
      • 安全运行函数应用和其他 Azure 资源的虚拟网络
    • 打包代码并将其部署到部署容器(等效于 azd deploy)。 然后,应用将启动并在已部署的包中运行。

    命令成功完成后,你会看到指向所创建资源的链接。

在 Azure 上调用函数

现在,可以通过使用 HTTP 测试工具或浏览器(对于 GET 请求)向 URL 发出 HTTP 请求来调用 Azure 中的函数终结点。 函数在 Azure 中运行时,系统将强制实施访问密钥授权,你必须向请求提供函数访问密钥。

可以使用 Core Tools 获取 Azure 中运行的函数的 URL 终结点。

  1. 在本地终端或命令提示符下,运行以下命令以获取 URL 终结点值:

    SET APP_NAME=(azd env get-value AZURE_FUNCTION_NAME)
    func azure functionapp list-functions $APP_NAME --show-keys
    
    $APP_NAME = azd env get-value AZURE_FUNCTION_NAME
    func azure functionapp list-functions $APP_NAME --show-keys
    

    azd env get-value 命令从本地环境中获取函数应用名称。 将 --show-keys 选项与 func azure functionapp list-functions 一起使用,意味着每个终结点返回的“Invoke URL:”值都包含一个函数级访问密钥。

  2. 与之前一样,使用 HTTP 测试工具在 Azure 中运行的函数应用中验证这些 URL。

重新部署代码

可以根据需要多次运行 azd up 命令,以预配 Azure 资源并为函数应用部署代码更新。

注意

已部署的代码文件始终被最新的部署包覆盖。

azd 提示的初始响应和 azd 生成的任何环境变量都本地存储在你的命名环境中。 使用 azd env get-values 命令查看创建 Azure 资源时使用的环境中的所有变量。

清理资源

使用完函数应用和相关资源后,可以使用此命令从 Azure 中删除函数应用及其相关资源,并避免产生任何进一步的成本:

azd down --no-prompt

注意

--no-prompt 选项指示 azd 在未经你确认的情况下删除资源组。

此命令不会影响本地代码项目。