Criar uma função no Linux usando um contêiner personalizadoCreate a function on Linux using a custom container

Neste tutorial, você cria e implanta seu código no Azure Functions como um contêiner do Docker personalizado usando uma imagem base do Linux.In this tutorial, you create and deploy your code to Azure Functions as a custom Docker container using a Linux base image. Normalmente, você usa uma imagem personalizada quando suas funções exigem uma versão de linguagem específica ou têm uma configuração ou dependência específica que não é fornecida pela imagem interna.You typically use a custom image when your functions require a specific language version or have a specific dependency or configuration that isn't provided by the built-in image.

O Azure Functions dá suporte a qualquer linguagem ou runtime usando manipuladores personalizados.Azure Functions supports any language or runtime using custom handlers. Para algumas linguagens, como a linguagem de programação R usada neste tutorial, você precisará instalar o runtime ou bibliotecas adicionais como dependências que exigem o uso de um contêiner personalizado.For some languages, such as the R programming language used in this tutorial, you need to install the runtime or additional libraries as dependencies that require the use of a custom container.

Para implantar seu código de função em um contêiner Linux personalizado, você precisa ter a hospedagem em um Plano Premium ou em um Plano dedicado (Serviço de Aplicativo).Deploying your function code in a custom Linux container requires Premium plan or a Dedicated (App Service) plan hosting. A conclusão deste tutorial gera custos de alguns dólares dos EUA em sua conta do Azure, que você pode minimizar limpando os recursos quando terminar.Completing this tutorial incurs costs of a few US dollars in your Azure account, which you can minimize by cleaning-up resources when you're done.

Você também pode usar um contêiner padrão do Serviço de Aplicativo do Azure, conforme descrito em Criar sua primeira função hospedada em Linux.You can also use a default Azure App Service container as described on Create your first function hosted on Linux. Imagens base com suporte para Azure Functions encontram-se no repositório de imagens de base do Azure Functions.Supported base images for Azure Functions are found in the Azure Functions base images repo.

Neste tutorial, você aprenderá como:In this tutorial, you learn how to:

  • Criar um aplicativo de funções e um Dockerfile usando o Azure Functions Core Tools.Create a function app and Dockerfile using the Azure Functions Core Tools.
  • Compile uma imagem personalizada usando o Docker.Build a custom image using Docker.
  • Publique uma imagem personalizada em um registro de contêiner.Publish a custom image to a container registry.
  • Criar recursos de suporte no Azure para o aplicativo de funçõesCreate supporting resources in Azure for the function app
  • Implante um aplicativo de funções do Hub do Docker.Deploy a function app from Docker Hub.
  • Adicione configurações de aplicativo ao aplicativo de funções.Add application settings to the function app.
  • Habilitar a implantação contínua.Enable continuous deployment.
  • Habilitar conexões SSH para o contêiner.Enable SSH connections to the container.
  • Adicionar uma associação de saída de armazenamento de filas.Add a Queue storage output binding.
  • Criar um aplicativo de funções e um Dockerfile usando o Azure Functions Core Tools.Create a function app and Dockerfile using the Azure Functions Core Tools.
  • Compile uma imagem personalizada usando o Docker.Build a custom image using Docker.
  • Publique uma imagem personalizada em um registro de contêiner.Publish a custom image to a container registry.
  • Criar recursos de suporte no Azure para o aplicativo de funçõesCreate supporting resources in Azure for the function app
  • Implante um aplicativo de funções do Hub do Docker.Deploy a function app from Docker Hub.
  • Adicione configurações de aplicativo ao aplicativo de funções.Add application settings to the function app.
  • Habilitar a implantação contínua.Enable continuous deployment.
  • Habilitar conexões SSH para o contêiner.Enable SSH connections to the container.

Você pode seguir este tutorial em qualquer computador que execute o Windows, o macOS ou o Linux.You can follow this tutorial on any computer running Windows, macOS, or Linux.

Configurar o ambiente localConfigure your local environment

Antes de começar, você deverá ter o seguinte:Before you begin, you must have the following:

  • Node.js, versões Active LTS e Maintenance LTS (8.11.1 e 10.14.1 recomendadas).Node.js, Active LTS and Maintenance LTS versions (8.11.1 and 10.14.1 recommended).

Verificação de pré-requisitosPrerequisite check

  • Em um terminal ou uma janela Comando, execute func --version para verificar se a versão do Azure Functions Core Tools é 2.7.1846 ou posterior.In a terminal or command window, run func --version to check that the Azure Functions Core Tools are version 2.7.1846 or later.

  • Execute az --version para verificar se a versão da CLI do Azure é a 2.0.76 ou posterior.Run az --version to check that the Azure CLI version is 2.0.76 or later.

  • Execute az login para entrar no Azure e verifique se a assinatura está ativa.Run az login to sign in to Azure and verify an active subscription.

  • Execute python --version (Linux/MacOS) ou py --version (Windows) para verificar se a versão do Python é 3.8.x, 3.7.x ou 3.6.x.Run python --version (Linux/MacOS) or py --version (Windows) to check your Python version reports 3.8.x, 3.7.x or 3.6.x.
  • Execute docker login para entrar no Docker.Run docker login to sign in to Docker. Esse comando falhará se o Docker não estiver em execução; nesse caso, inicie o Docker e tente o comando novamente.This command fails if Docker isn't running, in which case start docker and retry the command.

Criar e ativar um ambiente virtualCreate and activate a virtual environment

Em uma pasta adequada, execute os comandos a seguir para criar e ativar um ambiente virtual chamado .venv.In a suitable folder, run the following commands to create and activate a virtual environment named .venv. Lembre-se de usar as versões 3.8, 3.7 ou 3.6 do Python, que são compatíveis com o Azure Functions.Be sure to use Python 3.8, 3.7 or 3.6, which are supported by Azure Functions.

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

Se o Python não instalou o pacote venv na distribuição do Linux, execute o seguinte comando:If Python didn't install the venv package on your Linux distribution, run the following command:

sudo apt-get install python3-venv

Você executará todos os comandos posteriores neste ambiente virtual ativado.You run all subsequent commands in this activated virtual environment.

Criar e testar o projeto de funções localCreate and test the local functions project

Em um terminal ou prompt de comando, execute o comando a seguir referente à linguagem escolhida para criar um projeto de aplicativo de funções em uma pasta chamada LocalFunctionsProject.In a terminal or command prompt, run the following command for your chosen language to create a function app project in a folder named LocalFunctionsProject.

func init LocalFunctionsProject --worker-runtime dotnet --docker
func init LocalFunctionsProject --worker-runtime node --language javascript --docker
func init LocalFunctionsProject --worker-runtime powershell --docker
func init LocalFunctionsProject --worker-runtime python --docker
func init LocalFunctionsProject --worker-runtime node --language typescript --docker

Em uma pasta vazia, execute o seguinte comando para gerar o projeto do Functions a partir de um arquétipo Maven.In an empty folder, run the following command to generate the Functions project from a Maven archetype.

mvn archetype:generate -DarchetypeGroupId=com.microsoft.azure -DarchetypeArtifactId=azure-functions-archetype -DjavaVersion=8 -Ddocker

O parâmetro -DjavaVersion informa ao runtime do Functions a versão do Java a ser usada.The -DjavaVersion parameter tells the Functions runtime which version of Java to use. Use -DjavaVersion=11 se desejar que as funções sejam executadas no Java 11.Use -DjavaVersion=11 if you want your functions to run on Java 11. Quando você não especifica -DjavaVersion, o Maven assume o Java 8 como padrão.When you don't specify -DjavaVersion, Maven defaults to Java 8. Para obter mais informações, confira Versões do Java.For more information, see Java versions.

Importante

A variável de ambiente JAVA_HOME precisa ser definida como a localização de instalação da versão correta do JDK para concluir este artigo.The JAVA_HOME environment variable must be set to the install location of the correct version of the JDK to complete this article.

O Maven solicita os valores necessários para concluir a geração do projeto na implantação.Maven asks you for values needed to finish generating the project on deployment.
Forneça os seguintes valores quando solicitado:Provide the following values when prompted:

PromptPrompt ValorValue DescriçãoDescription
groupIdgroupId com.fabrikam Um valor que identifica exclusivamente o projeto em todos os projetos, seguindo as regras de nomenclatura do pacote para Java.A value that uniquely identifies your project across all projects, following the package naming rules for Java.
artifactIdartifactId fabrikam-functions Um valor que é o nome do jar, sem um número de versão.A value that is the name of the jar, without a version number.
versionversion 1.0-SNAPSHOT Escolha o valor padrão.Choose the default value.
packagepackage com.fabrikam.functions Um valor que é o pacote Java para o código de função gerado.A value that is the Java package for the generated function code. Use o padrão.Use the default.

Digite Y ou pressione Enter para confirmar.Type Y or press Enter to confirm.

O Maven cria os arquivos de projeto em uma nova pasta com o nome artifactId, que, neste exemplo, é fabrikam-functions.Maven creates the project files in a new folder with a name of artifactId, which in this example is fabrikam-functions.

func init LocalFunctionsProject --worker-runtime custom --docker

A opção --docker gera um Dockerfile para o projeto, que define um contêiner personalizado adequado para uso com o Azure Functions e com o runtime selecionado.The --docker option generates a Dockerfile for the project, which defines a suitable custom container for use with Azure Functions and the selected runtime.

Navegue até a pasta do projeto:Navigate into the project folder:

cd LocalFunctionsProject
cd fabrikam-functions

Adicione uma função ao projeto usando o comando a seguir, em que o argumento --name é o nome exclusivo da função e o argumento --template especifica o gatilho da função.Add a function to your project by using the following command, where the --name argument is the unique name of your function and the --template argument specifies the function's trigger. func new cria uma subpasta correspondente ao nome da função que contém um arquivo de código apropriado para a linguagem escolhida do projeto, bem como um arquivo de configuração chamado function.json.func new creates a subfolder matching the function name that contains a code file appropriate to the project's chosen language and a configuration file named function.json.

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

Adicione uma função ao projeto usando o comando a seguir, em que o argumento --name é o nome exclusivo da função e o argumento --template especifica o gatilho da função.Add a function to your project by using the following command, where the --name argument is the unique name of your function and the --template argument specifies the function's trigger. func new cria uma subpasta correspondente ao nome da função que contém um arquivo de configuração chamado function.json.func new creates a subfolder matching the function name that contains a configuration file named function.json.

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

Em um editor de texto, crie um arquivo na pasta do projeto chamado handler.R.In a text editor, create a file in the project folder named handler.R. Adicione o trecho mostrado a seguir como o conteúdo.Add the following as its content.

library(httpuv)

PORTEnv <- Sys.getenv("FUNCTIONS_CUSTOMHANDLER_PORT")
PORT <- strtoi(PORTEnv , base = 0L)

http_not_found <- list(
  status=404,
  body='404 Not Found'
)

http_method_not_allowed <- list(
  status=405,
  body='405 Method Not Allowed'
)

hello_handler <- list(
  GET = function (request) {
    list(body=paste(
      "Hello,",
      if(substr(request$QUERY_STRING,1,6)=="?name=") 
        substr(request$QUERY_STRING,7,40) else "World",
      sep=" "))
  }
)

routes <- list(
  '/api/HttpExample' = hello_handler
)

router <- function (routes, request) {
  if (!request$PATH_INFO %in% names(routes)) {
    return(http_not_found)
  }
  path_handler <- routes[[request$PATH_INFO]]

  if (!request$REQUEST_METHOD %in% names(path_handler)) {
    return(http_method_not_allowed)
  }
  method_handler <- path_handler[[request$REQUEST_METHOD]]

  return(method_handler(request))
}

app <- list(
  call = function (request) {
    response <- router(routes, request)
    if (!'status' %in% names(response)) {
      response$status <- 200
    }
    if (!'headers' %in% names(response)) {
      response$headers <- list()
    }
    if (!'Content-Type' %in% names(response$headers)) {
      response$headers[['Content-Type']] <- 'text/plain'
    }

    return(response)
  }
)

cat(paste0("Server listening on :", PORT, "...\n"))
runServer("0.0.0.0", PORT, app)

Em host.json, modifique a seção customHandler para configurar o comando de inicialização do manipulador personalizado.In host.json, modify the customHandler section to configure the custom handler's startup command.

"customHandler": {
  "description": {
      "defaultExecutablePath": "Rscript",
      "arguments": [
      "handler.R"
    ]
  },
  "enableForwardingHttpRequest": true
}

Para testar a função localmente, inicie o host de runtime local do Azure Functions na raiz da pasta do projeto:To test the function locally, start the local Azure Functions runtime host in the root of the project folder:

func start --build  
func start  
npm install
npm start
mvn clean package  
mvn azure-functions:run
R -e "install.packages('httpuv', repos='http://cran.rstudio.com/')"
func start

Quando vir o ponto de extremidade HttpExample na saída, navegue até http://localhost:7071/api/HttpExample?name=Functions.Once you see the HttpExample endpoint appear in the output, navigate to http://localhost:7071/api/HttpExample?name=Functions. O navegador deve exibir uma mensagem "olá" que ecoa de volta Functions, o valor fornecido para o parâmetro de consulta name.The browser should display a "hello" message that echoes back Functions, the value supplied to the name query parameter.

Use CTRL-C para interromper o host.Use Ctrl-C to stop the host.

Compilar a imagem de contêiner e testá-la localmenteBuild the container image and test locally

(Opcional) Examine o Dockerfile na raiz da pasta do projeto.(Optional) Examine the Dockerfile in the root of the project folder. O Dockerfile descreve o ambiente necessário para executar o aplicativo de funções no Linux.The Dockerfile describes the required environment to run the function app on Linux. A lista completa de imagens base com suporte para Azure Functions encontram-se na página de imagens de base do Azure Functions.The complete list of supported base images for Azure Functions can be found in the Azure Functions base image page.

Examine o Dockerfile na raiz da pasta do projeto.Examine the Dockerfile in the root of the project folder. O Dockerfile descreve o ambiente necessário para executar o aplicativo de funções no Linux.The Dockerfile describes the required environment to run the function app on Linux. Os aplicativos do manipulador personalizado usam a imagem mcr.microsoft.com/azure-functions/dotnet:3.0-appservice como base.Custom handler applications use the mcr.microsoft.com/azure-functions/dotnet:3.0-appservice image as its base.

Modifique o Dockerfile para instalar o R. Substitua o conteúdo do Dockerfile pelo mostrado a seguir.Modify the Dockerfile to install R. Replace the contents of Dockerfile with the following.

FROM mcr.microsoft.com/azure-functions/dotnet:3.0-appservice 
ENV AzureWebJobsScriptRoot=/home/site/wwwroot \
    AzureFunctionsJobHost__Logging__Console__IsEnabled=true

RUN apt update && \
    apt install -y r-base && \
    R -e "install.packages('httpuv', repos='http://cran.rstudio.com/')"

COPY . /home/site/wwwroot

Na pasta do projeto raiz, execute o comando docker build e forneça um nome, azurefunctionsimage, e uma tag, v1.0.0.In the root project folder, run the docker build command, and provide a name, azurefunctionsimage, and tag, v1.0.0. Substitua <DOCKER_ID> pela ID da conta do Hub do Docker.Replace <DOCKER_ID> with your Docker Hub account ID. Esse comando compila a imagem do Docker para o contêiner.This command builds the Docker image for the container.

docker build --tag <DOCKER_ID>/azurefunctionsimage:v1.0.0 .

Quando o comando for concluído, você poderá executar o novo contêiner localmente.When the command completes, you can run the new container locally.

Para testar o build, execute a imagem em um contêiner local usando o comando docker run, substituindo novamente <DOCKER_ID pela ID do Docker e adicionando o argumento de portas, -p 8080:80:To test the build, run the image in a local container using the docker run command, replacing again <DOCKER_ID with your Docker ID and adding the ports argument, -p 8080:80:

docker run -p 8080:80 -it <docker_id>/azurefunctionsimage:v1.0.0

Quando a imagem estiver em execução em um contêiner local, abra um navegador para http://localhost:8080, o que deve exibir a imagem de espaço reservado mostrada abaixo.Once the image is running in a local container, open a browser to http://localhost:8080, which should display the placeholder image shown below. A imagem aparece neste ponto porque a função está sendo executada no contêiner local, como aconteceria no Azure, o que significa que ela está protegida por uma chave de acesso, conforme definido em function.json com a propriedade "authLevel": "function".The image appears at this point because your function is running in the local container, as it would in Azure, which means that it's protected by an access key as defined in function.json with the "authLevel": "function" property. No entanto, o contêiner ainda não foi publicado em um aplicativo de funções no Azure, de modo que a chave ainda não está disponível.The container hasn't yet been published to a function app in Azure, however, so the key isn't yet available. Se desejar testar no contêiner local, pare o Docker, altere a propriedade de autorização para "authLevel": "anonymous", recompile a imagem e reinicie o Docker.If you want to test against the local container, stop docker, change the authorization property to "authLevel": "anonymous", rebuild the image, and restart docker. Em seguida, redefina "authLevel": "function" em function.json.Then reset "authLevel": "function" in function.json. Para obter mais informações, confira chaves de autorização.For more information, see authorization keys.

Imagem de espaço reservado indicando que o contêiner está sendo executado localmente

Quando a imagem estiver em execução em um contêiner local, navegue até http://localhost:8080/api/HttpExample?name=Functions, que deverá exibir a mesma mensagem "olá" que anteriormente.Once the image is running in a local container, browse to http://localhost:8080/api/HttpExample?name=Functions, which should display the same "hello" message as before. Como o arquétipo Maven gera uma função disparada por HTTP que usa autorização anônima, você ainda poderá chamar a função mesmo se ela estiver em execução no contêiner.Because the Maven archetype generates an HTTP triggered function that uses anonymous authorization, you can still call the function even though it's running in the container.

Depois de verificar o aplicativo de funções no contêiner, pare o Docker pressionando Ctrl+C.After you've verified the function app in the container, stop docker with Ctrl+C.

Enviar a imagem por push para o Docker HubPush the image to Docker Hub

Um Docker Hub é um Registro de Contêiner que hospeda imagens e fornece serviços de contêiner e imagem.Docker Hub is a container registry that hosts images and provides image and container services. Para compartilhar a imagem, que inclui sua implantação no Azure, você precisa enviá-la por push para um Registro.To share your image, which includes deploying to Azure, you must push it to a registry.

  1. Se ainda não tiver entrado no Docker, faça isso usando o comando docker login, substituindo <docker_id> pela ID do Docker.If you haven't already signed in to Docker, do so with the docker login command, replacing <docker_id> with your Docker ID. Esse comando solicita seu nome de usuário e sua senha.This command prompts you for your username and password. A mensagem “Logon com Êxito” confirma que você está conectado.A "Login Succeeded" message confirms that you're signed in.

    docker login
    
  2. Depois de conectado, envie a imagem por push para o Docker Hub usando o comando docker push, mais uma vez substituindo <docker_id> pela ID do Docker.After you've signed in, push the image to Docker Hub by using the docker push command, again replacing <docker_id> with your Docker ID.

    docker push <docker_id>/azurefunctionsimage:v1.0.0
    
  3. Dependendo da velocidade da rede, o primeiro envio da imagem por push pode levar alguns minutos (o envio de alterações posteriores é muito mais rápido).Depending on your network speed, pushing the image the first time might take a few minutes (pushing subsequent changes is much faster). Enquanto estiver aguardando, você pode prosseguir para a próxima seção e criar recursos do Azure em outro terminal.While you're waiting, you can proceed to the next section and create Azure resources in another terminal.

Criar recursos de suporte do Azure para a funçãoCreate supporting Azure resources for your function

Para implantar o código da função no Azure, você precisa criar três recursos:To deploy your function code to Azure, you need to create three resources:

  • Um grupo de recursos, que é um contêiner lógico para recursos relacionados.A resource group, which is a logical container for related resources.
  • Uma conta de Armazenamento do Azure, que mantém o estado e outras informações sobre seus projetos.An Azure Storage account, which maintains state and other information about your projects.
  • Um aplicativo de funções, que fornece o ambiente para a execução do código de função.A function app, which provides the environment for executing your function code. Um aplicativo de funções é mapeado para seu projeto de função local e permite agrupar funções como uma unidade lógica para facilitar o gerenciamento, a implantação e o compartilhamento de recursos.A function app maps to your local function project and lets you group functions as a logical unit for easier management, deployment, and sharing of resources.

Use comandos da CLI do Azure para criar esses itens.You use Azure CLI commands to create these items. Cada comando fornece uma saída em JSON após a conclusão.Each command provides JSON output upon completion.

  1. Entre no Azure usando o comando az login:Sign in to Azure with the az login command:

    az login
    
  2. Crie um grupo de recursos com o comando az group create.Create a resource group with the az group create command. O exemplo a seguir cria um grupo de recursos chamado AzureFunctionsContainers-rg na região westeurope.The following example creates a resource group named AzureFunctionsContainers-rg in the westeurope region. (De modo geral, você cria o grupo de recursos e os recursos em uma região próxima a você usando uma região disponível com o comando az account list-locations.)(You generally create your resource group and resources in a region near you, using an available region from the az account list-locations command.)

    az group create --name AzureFunctionsContainers-rg --location westeurope
    

    Observação

    Você não pode hospedar aplicativos Windows e Linux no mesmo grupo de recursos.You can't host Linux and Windows apps in the same resource group. Se você tiver um grupo de recursos chamado AzureFunctionsContainers-rg com um aplicativo de funções ou um aplicativo Web do Windows, você precisará usar um grupo de recursos diferente.If you have an existing resource group named AzureFunctionsContainers-rg with a Windows function app or web app, you must use a different resource group.

  3. Crie uma conta de armazenamento para uso geral em seu grupo de recursos e região usando o comando az storage account create.Create a general-purpose storage account in your resource group and region by using the az storage account create command. No exemplo a seguir, substitua <storage_name> por um nome exclusivo globalmente que for adequado para você.In the following example, replace <storage_name> with a globally unique name appropriate to you. Os nomes devem conter de 3 a 24 caracteres e podem conter somente números e letras minúsculas.Names must contain three to 24 characters numbers and lowercase letters only. Standard_LRS especifica uma conta para uso geral típica.Standard_LRS specifies a typical general-purpose account.

    az storage account create --name <storage_name> --location westeurope --resource-group AzureFunctionsContainers-rg --sku Standard_LRS
    

    Para este tutorial, a conta de armazenamento gera um custo de apenas alguns centavos de dólar.The storage account incurs only a few USD cents for this tutorial.

  4. Use o comando para criar um plano Premium do Azure Functions chamado myPremiumPlan, com o tipo de preço Elástico Premium 1 (--sku EP1), na região Europa Ocidental (-location westeurope, ou use uma região adequada próxima a você) e em um contêiner Linux (--is-linux).Use the command to create a Premium plan for Azure Functions named myPremiumPlan in the Elastic Premium 1 pricing tier (--sku EP1), in the West Europe region (-location westeurope, or use a suitable region near you), and in a Linux container (--is-linux).

    az functionapp plan create --resource-group AzureFunctionsContainers-rg --name myPremiumPlan --location westeurope --number-of-workers 1 --sku EP1 --is-linux
    

    Aqui, usamos o plano Premium, que pode ser dimensionado conforme necessário.We use the Premium plan here, which can scale as needed. Para saber mais sobre hospedagem, confira Comparação de planos de hospedagem do Azure Functions.To learn more about hosting, see Azure Functions hosting plans comparison. Para calcular os custos, confira a Página de preços do Functions.To calculate costs, see the Functions pricing page.

    O comando também provisiona uma instância associada do Azure Application Insights no mesmo grupo de recursos, com a qual você pode monitorar seu aplicativo de funções e exibir logs.The command also provisions an associated Azure Application Insights instance in the same resource group, with which you can monitor your function app and view logs. Para saber mais, consulte Monitorar Azure Functions.For more information, see Monitor Azure Functions. A instância não gera nenhum custo até você ativá-la.The instance incurs no costs until you activate it.

Criar e configurar um aplicativo de funções no Azure usando a imagemCreate and configure a function app on Azure with the image

Um aplicativo de funções no Azure gerencia a execução das funções em seu plano de hospedagem.A function app on Azure manages the execution of your functions in your hosting plan. Nesta seção, você usa os recursos do Azure da seção anterior para criar um aplicativo de funções baseado em uma imagem no Docker Hub e configurá-lo com uma cadeia de conexão para o Armazenamento do Azure.In this section, you use the Azure resources from the previous section to create a function app from an image on Docker Hub and configure it with a connection string to Azure Storage.

  1. Crie o aplicativo do Functions usando o comando az functionapp create.Create the Functions app using the az functionapp create command. No exemplo a seguir, substitua <storage_name> pelo nome usado na seção anterior para a conta de armazenamento.In the following example, replace <storage_name> with the name you used in the previous section for the storage account. Além disso, substitua <app_name> por um nome exclusivo globalmente que for adequado para você e <docker_id> pela ID do Docker.Also replace <app_name> with a globally unique name appropriate to you, and <docker_id> with your Docker ID.

    az functionapp create --name <app_name> --storage-account <storage_name> --resource-group AzureFunctionsContainers-rg --plan myPremiumPlan --runtime <functions runtime stack> --deployment-container-image-name <docker_id>/azurefunctionsimage:v1.0.0
    
    az functionapp create --name <app_name> --storage-account <storage_name> --resource-group AzureFunctionsContainers-rg --plan myPremiumPlan --runtime custom --deployment-container-image-name <docker_id>/azurefunctionsimage:v1.0.0
    

    O parâmetro deployment-container-image-name especifica a imagem a ser usada para o aplicativo de funções.The deployment-container-image-name parameter specifies the image to use for the function app. Você pode usar o comando az functionapp config container show para exibir informações sobre a imagem usada para a implantação.You can use the az functionapp config container show command to view information about the image used for deployment. Use também o comando az functionapp config container set para implantação com base em outra imagem.You can also use the az functionapp config container set command to deploy from a different image.

  2. Exiba a cadeia de conexão da conta de armazenamento que você criou usando o comando az storage account show-connection-string.Display the connection string for the storage account you created by using the az storage account show-connection-string command. Substitua <storage-name> pelo nome da conta de armazenamento criada acima:Replace <storage-name> with the name of the storage account you created above:

    az storage account show-connection-string --resource-group AzureFunctionsContainers-rg --name <storage_name> --query connectionString --output tsv
    
  3. Adicione essa configuração ao aplicativo de funções usando o comando az functionapp config appsettings set.Add this setting to the function app by using the az functionapp config appsettings set command. No seguinte comando, substitua <app_name> pelo nome do aplicativo de funções e substitua <connection_string> pela cadeia de conexão da etapa anterior (uma cadeia de caracteres longa codificada que começa com "DefaultEndpointProtocol="):In the following command, replace <app_name> with the name of your function app, and replace <connection_string> with the connection string from the previous step (a long encoded string that begins with "DefaultEndpointProtocol="):

    az functionapp config appsettings set --name <app_name> --resource-group AzureFunctionsContainers-rg --settings AzureWebJobsStorage=<connection_string>
    

    Dica

    No Bash, você pode usar uma variável de shell para capturar a cadeia de conexão em vez de usar a área de transferência.In Bash, you can use a shell variable to capture the connection string instead of using the clipboard. Primeiro, use o seguinte comando para criar uma variável com a cadeia de conexão:First, use the following command to create a variable with the connection string:

    storageConnectionString=$(az storage account show-connection-string --resource-group AzureFunctionsContainers-rg --name <storage_name> --query connectionString --output tsv)
    

    Em seguida, faça referência à variável no segundo comando:Then refer to the variable in the second command:

    az functionapp config appsettings set --name <app_name> --resource-group AzureFunctionsContainers-rg --settings AzureWebJobsStorage=$storageConnectionString
    
  4. Agora, a função pode usar essa cadeia de conexão para acessar a conta de armazenamento.The function can now use this connection string to access the storage account.

Observação

Se publicar a imagem personalizada em uma conta de contêiner particular, você deverá usar as variáveis de ambiente no Dockerfile para a cadeia de conexão.If you publish your custom image to a private container account, you should use environment variables in the Dockerfile for the connection string instead. Para obter mais informações, confira a Instrução ENV.For more information, see the ENV instruction. Você também precisa definir as variáveis DOCKER_REGISTRY_SERVER_USERNAME e DOCKER_REGISTRY_SERVER_PASSWORD.You should also set the variables DOCKER_REGISTRY_SERVER_USERNAME and DOCKER_REGISTRY_SERVER_PASSWORD. Em seguida, para usar os valores, você deve recompilar a imagem, enviá-la por push para o Registro e, então, reiniciar o aplicativo de funções no Azure.To use the values, then, you must rebuild the image, push the image to the registry, and then restart the function app on Azure.

Verificar as funções no AzureVerify your functions on Azure

Com a imagem implantada no aplicativo de funções no Azure, você pode invocar a função usando solicitações HTTP.With the image deployed to the function app on Azure, you can now invoke the function through HTTP requests. Como a definição de function.json inclui a propriedade "authLevel": "function", primeiro você precisa obter a chave de acesso (também chamada de "chave de função") e incluí-la como um parâmetro de URL em qualquer solicitação para o ponto de extremidade.Because the function.json definition includes the property "authLevel": "function", you must first obtain the access key (also called the "function key") and include it as a URL parameter in any requests to the endpoint.

  1. Recupere a URL da função com a chave de acesso (função) usando o portal do Azure ou a CLI do Azure, com o comando az rest.)Retrieve the function URL with the access (function) key by using the Azure portal, or by using the Azure CLI with the az rest command.)

    1. Entre no portal do Azure, em seguida, procure e selecione Aplicativo de Funções.Sign in to the Azure portal, then search for and select Function App.

    2. Selecione a função que você deseja verificar.Select the function you want to verify.

    3. No painel de navegação esquerdo, selecione Funções e, em seguida, selecione a função que você deseja verificar.In the left navigation panel, select Functions, and then select the function you want to verify.

      Escolher a sua função no portal do Azure

    4. Selecione Obter a URL da função.Select Get Function Url.

      Obter a URL da função no portal do Azure

    5. Na janela pop-up, selecione padrão (chave de função) e, em seguida, copie a URL para a área de transferência.In the pop-up window, select default (function key) and then copy the URL to the clipboard. A chave é a cadeia de caracteres que segue ?code=.The key is the string of characters following ?code=.

      Escolha a chave de acesso da função padrão

    Observação

    Já que seu aplicativo de funções é implantado como um contêiner, você não pode fazer alterações no seu código de função no portal.Because your function app is deployed as a container, you can't make changes to your function code in the portal. Em vez disso, você precisa atualizar o projeto na imagem local, enviar a imagem por push para o Registro novamente e reimplantar no Azure.You must instead update the project in the local image, push the image to the registry again, and then redeploy to Azure. Você pode configurar a implantação contínua em uma seção posterior.You can set up continuous deployment in a later section.

  2. Cole a URL da função na barra de endereços do navegador, adicionando o parâmetro &name=Azure ao final da URL.Paste the function URL into your browser's address bar, adding the parameter &name=Azure to the end of this URL. Um texto semelhante a"Olá, Azure" deve aparecer no navegador.Text like "Hello, Azure" should appear in the browser.

    Resposta da função no navegador.

  3. Para testar a autorização, remova o parâmetro code= da URL e verifique se você não recebe nenhuma resposta da função.To test authorization, remove the code= parameter from the URL and verify that you get no response from the function.

Habilitar a implantação contínua no AzureEnable continuous deployment to Azure

Você pode habilitar o Azure Functions para atualizar automaticamente sua implantação de uma imagem sempre que você atualizar a imagem no Registro.You can enable Azure Functions to automatically update your deployment of an image whenever you update the image in the registry.

  1. Habilite a implantação contínua usando o comando az functionapp deployment container config, substituindo <app_name> pelo nome do aplicativo de funções:Enable continuous deployment by using az functionapp deployment container config command, replacing <app_name> with the name of your function app:

    az functionapp deployment container config --enable-cd --query CI_CD_URL --output tsv --name <app_name> --resource-group AzureFunctionsContainers-rg
    

    Esse comando habilita a implantação contínua e retorna a URL do webhook de implantação.This command enables continuous deployment and returns the deployment webhook URL. (Você pode recuperar essa URL a qualquer momento usando o comando az functionapp deployment container show-cd-url.)(You can retrieve this URL at any later time by using the az functionapp deployment container show-cd-url command.)

  2. Copie a URL do webhook de implantação para a área de transferência.Copy the deployment webhook URL to the clipboard.

  3. Abra o Docker Hub, entre e selecione Repositórios na barra de navegação.Open Docker Hub, sign in, and select Repositories on the nav bar. Localize e selecione a imagem, selecione a guia Webhooks, especifique um Nome do webhook, cole a URL em URL do Webhook e, em seguida, selecione Criar:Locate and select image, select the Webhooks tab, specify a Webhook name, paste your URL in Webhook URL, and then select Create:

    Adicione o webhook em seu repositório DockerHub

  4. Com o webhook definido, o Azure Functions reimplanta sua imagem sempre que você a atualiza no Docker Hub.With the webhook set, Azure Functions redeploys your image whenever you update it in Docker Hub.

Habilitar conexões SSHEnable SSH connections

O SSH permite a comunicação segura entre um contêiner e um cliente.SSH enables secure communication between a container and a client. Com o SSH habilitado, você pode se conectar ao contêiner usando as Ferramentas Avançadas do Serviço de Aplicativo (Kudu).With SSH enabled, you can connect to your container using App Service Advanced Tools (Kudu). Para facilitar a conexão com o contêiner usando SSH, o Azure Functions fornece uma imagem base que já tem o SSH habilitado.To make it easy to connect to your container using SSH, Azure Functions provides a base image that has SSH already enabled. Você só precisa editar o Dockerfile e, em seguida, recompilar e reimplantar a imagem.You need only edit your Dockerfile, then rebuild and redeploy the image. Em seguida, você pode se conectar ao contêiner usando as Ferramentas Avançadas (Kudu)You can then connect to the container through the Advanced Tools (Kudu)

  1. No Dockerfile, acrescente a cadeia de caracteres -appservice à imagem base na instrução FROM:In your Dockerfile, append the string -appservice to the base image in your FROM instruction:

    FROM mcr.microsoft.com/azure-functions/dotnet:3.0-appservice
    
    FROM mcr.microsoft.com/azure-functions/node:2.0-appservice
    
    FROM mcr.microsoft.com/azure-functions/powershell:2.0-appservice
    
    FROM mcr.microsoft.com/azure-functions/python:2.0-python3.7-appservice
    
    FROM mcr.microsoft.com/azure-functions/node:2.0-appservice
    
  2. Recompile a imagem usando o comando docker build novamente, substituindo <docker_id> pela ID do Docker:Rebuild the image by using the docker build command again, replacing <docker_id> with your Docker ID:

    docker build --tag <docker_id>/azurefunctionsimage:v1.0.0 .
    
  3. Envie por push a imagem atualizada para o Docker Hub, o que deve levar bem menos tempo do que o primeiro push, pois somente os segmentos atualizados da imagem precisam ser carregados.Push the updated image to Docker Hub, which should take considerably less time than the first push only the updated segments of the image need to be uploaded.

    docker push <docker_id>/azurefunctionsimage:v1.0.0
    
  4. O Azure Functions reimplanta automaticamente a imagem em seu aplicativo de funções. O processo leva menos de um minuto.Azure Functions automatically redeploys the image to your functions app; the process takes place in less than a minute.

  5. Em um navegador, abra https://<app_name>.scm.azurewebsites.net/, substituindo <app_name> por seu nome exclusivo.In a browser, open https://<app_name>.scm.azurewebsites.net/, replacing <app_name> with your unique name. Essa URL é o ponto de extremidade das Ferramentas Avançadas (Kudu) para seu contêiner do aplicativo de funções.This URL is the Advanced Tools (Kudu) endpoint for your function app container.

  6. Entre em sua conta do Azure e selecione SSH para estabelecer uma conexão com o contêiner.Sign in to your Azure account, and then select the SSH to establish a connection with the container. A conexão poderá levar algum tempo se o Azure ainda estiver atualizando a imagem de contêiner.Connecting may take a few moments if Azure is still updating the container image.

  7. Depois que a conexão com o contêiner for estabelecida, execute o comando top para exibir os processos em execução.After a connection is established with your container, run the top command to view the currently running processes.

    Comando top do Linux em execução em uma sessão de SSH

Gravar em uma fila do Armazenamento do AzureWrite to an Azure Storage queue

O Azure Functions permite conectar suas funções a outros serviços e recursos do Azure sem precisar escrever um código de integração próprio.Azure Functions lets you connect your functions to other Azure services and resources without having to write your own integration code. Essas associações, que representam a entrada e a saída, são declaradas na definição de função.These bindings, which represent both input and output, are declared within the function definition. Dados de associações são fornecidos à função como parâmetros.Data from bindings is provided to the function as parameters. Um gatilho é um tipo especial de associação de entrada.A trigger is a special type of input binding. Embora uma função tenha apenas um gatilho, ela pode ter várias associações de entrada e de saída.Although a function has only one trigger, it can have multiple input and output bindings. Para saber mais, confira Conceitos de gatilhos e de associações do Azure Functions.To learn more, see Azure Functions triggers and bindings concepts.

Esta seção mostra como integrar sua função a uma fila do Armazenamento do Azure.This section shows you how to integrate your function with an Azure Storage queue. A associação de saída que você adiciona a essa função escreve dados de uma solicitação HTTP em uma mensagem na fila.The output binding that you add to this function writes data from an HTTP request to a message in the queue.

Recuperar a cadeia de conexão do Armazenamento do AzureRetrieve the Azure Storage connection string

Anteriormente, você criou uma conta de Armazenamento do Azure para uso pelo aplicativo de funções.Earlier, you created an Azure Storage account for use by the function app. A cadeia de conexão dessa conta é armazenada com segurança nas configurações do aplicativo no Azure.The connection string for this account is stored securely in app settings in Azure. Ao baixar a configuração para o arquivo local.settings.json, use essa conexão para gravar em uma fila do Armazenamento na mesma conta ao executar a função localmente.By downloading the setting into the local.settings.json file, you can use that connection write to a Storage queue in the same account when running the function locally.

  1. Na raiz do projeto, execute o comando a seguir, substituindo <app_name> pelo nome do aplicativo de funções do início rápido anterior.From the root of the project, run the following command, replacing <app_name> with the name of your function app from the previous quickstart. Esse comando substituirá todos os valores existentes no arquivo.This command will overwrite any existing values in the file.

    func azure functionapp fetch-app-settings <app_name>
    
  2. Abra local.settings.json e localize o valor chamado AzureWebJobsStorage, que é a cadeia de conexão da conta de armazenamento.Open local.settings.json and locate the value named AzureWebJobsStorage, which is the Storage account connection string. Você usará o nome AzureWebJobsStorage e a cadeia de conexão em outras seções deste artigo.You use the name AzureWebJobsStorage and the connection string in other sections of this article.

Importante

Como local.settings.json contém segredos baixados do Azure, sempre exclua esse arquivo do controle do código-fonte.Because local.settings.json contains secrets downloaded from Azure, always exclude this file from source control. O arquivo .gitignore criado com um projeto de funções locais exclui o arquivo por padrão.The .gitignore file created with a local functions project excludes the file by default.

Registrar as extensões de associaçãoRegister binding extensions

Com exceção dos gatilhos de timer e HTTP, as associações são implementadas como pacotes de extensão.With the exception of HTTP and timer triggers, bindings are implemented as extension packages. Execute o comando dotnet add package a seguir na janela Terminal para adicionar o pacote de extensão Armazenamento ao seu projeto.Run the following dotnet add package command in the Terminal window to add the Storage extension package to your project.

dotnet add package Microsoft.Azure.WebJobs.Extensions.Storage --version 3.0.4

Agora, você pode adicionar a associação de saída do armazenamento ao seu projeto.Now, you can add the storage output binding to your project.

Adicionar uma definição de associação de saída à funçãoAdd an output binding definition to the function

Embora uma função possa ter apenas um gatilho, ela pode ter várias associações de entrada e saída, o que permite que você se conecte a outros serviços e recursos do Azure sem escrever um código de integração personalizado.Although a function can have only one trigger, it can have multiple input and output bindings, which let you connect to other Azure services and resources without writing custom integration code.

Você declara essas associações no arquivo function.json em sua pasta de funções.You declare these bindings in the function.json file in your function folder. No início rápido anterior, o arquivo function.json na pasta HttpExample contém duas associações na coleção bindings:From the previous quickstart, your function.json file in the HttpExample folder contains two bindings in the bindings collection:

"bindings": [
    {
        "authLevel": "function",
        "type": "httpTrigger",
        "direction": "in",
        "name": "req",
        "methods": [
            "get",
            "post"
        ]
    },
    {
        "type": "http",
        "direction": "out",
        "name": "res"
    }
]
"scriptFile": "__init__.py",
"bindings": [
    {
        "authLevel": "function",
        "type": "httpTrigger",
        "direction": "in",
        "name": "req",
        "methods": [
            "get",
            "post"
        ]
    },
    {
        "type": "http",
        "direction": "out",
        "name": "$return"
    }
"bindings": [
  {
    "authLevel": "function",
    "type": "httpTrigger",
    "direction": "in",
    "name": "Request",
    "methods": [
      "get",
      "post"
    ]
  },
  {
    "type": "http",
    "direction": "out",
    "name": "Response"
  }
]

Cada associação tem, pelo menos, um tipo, uma direção e um nome.Each binding has at least a type, a direction, and a name. No exemplo acima, a primeira associação é do tipo httpTrigger com a direção in.In the example above, the first binding is of type httpTrigger with the direction in. Para a direção de in, name especifica o nome de um parâmetro de entrada que é enviado para a função quando invocado pelo gatilho.For the in direction, name specifies the name of an input parameter that's sent to the function when invoked by the trigger.

A segunda associação na coleção é denominada res.The second binding in the collection is named res. Essa associação http é uma associação de saída (out) usada para gravar a resposta HTTP.This http binding is an output binding (out) that is used to write the HTTP response.

Para fazer uma gravação em uma fila do Armazenamento do Azure por meio dessa função, adicione uma associação out do tipo queue com o nome msg, conforme mostrado no código abaixo:To write to an Azure Storage queue from this function, add an out binding of type queue with the name msg, as shown in the code below:

    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "res"
    },
    {
      "type": "queue",
      "direction": "out",
      "name": "msg",
      "queueName": "outqueue",
      "connection": "AzureWebJobsStorage"
    }
  ]
}

A segunda associação na coleção é do tipo http com a direção out; nesse caso, o name especial de $return indica que essa associação usa o valor retornado da função em vez de fornecer um parâmetro de entrada.The second binding in the collection is of type http with the direction out, in which case the special name of $return indicates that this binding uses the function's return value rather than providing an input parameter.

Para fazer uma gravação em uma fila do Armazenamento do Azure por meio dessa função, adicione uma associação out do tipo queue com o nome msg, conforme mostrado no código abaixo:To write to an Azure Storage queue from this function, add an out binding of type queue with the name msg, as shown in the code below:

"bindings": [
  {
    "authLevel": "anonymous",
    "type": "httpTrigger",
    "direction": "in",
    "name": "req",
    "methods": [
      "get",
      "post"
    ]
  },
  {
    "type": "http",
    "direction": "out",
    "name": "$return"
  },
  {
    "type": "queue",
    "direction": "out",
    "name": "msg",
    "queueName": "outqueue",
    "connection": "AzureWebJobsStorage"
  }
]

A segunda associação na coleção é denominada res.The second binding in the collection is named res. Essa associação http é uma associação de saída (out) usada para gravar a resposta HTTP.This http binding is an output binding (out) that is used to write the HTTP response.

Para fazer uma gravação em uma fila do Armazenamento do Azure por meio dessa função, adicione uma associação out do tipo queue com o nome msg, conforme mostrado no código abaixo:To write to an Azure Storage queue from this function, add an out binding of type queue with the name msg, as shown in the code below:

    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "Request",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "Response"
    },
    {
      "type": "queue",
      "direction": "out",
      "name": "msg",
      "queueName": "outqueue",
      "connection": "AzureWebJobsStorage"
    }
  ]
}

Nesse caso, msg é fornecido à função como um argumento de saída.In this case, msg is given to the function as an output argument. Para um tipo queue, também é necessário especificar o nome da fila em queueName e fornecer o nome da conexão do Armazenamento do Azure (por meio de local.settings.json) em connection.For a queue type, you must also specify the name of the queue in queueName and provide the name of the Azure Storage connection (from local.settings.json) in connection.

Em um projeto de biblioteca de classes C#, as associações são definidas como atributos de associação no método de função.In a C# class library project, the bindings are defined as binding attributes on the function method. O arquivo function.json exigido por Functions é gerado automaticamente com base nesses atributos.The function.json file required by Functions is then auto-generated based on these attributes.

Abra o arquivo de projeto HttpExample.cs e adicione o seguinte parâmetro à definição do método Run:Open the HttpExample.cs project file and add the following parameter to the Run method definition:

[Queue("outqueue"),StorageAccount("AzureWebJobsStorage")] ICollector<string> msg,

O parâmetro msg é um tipo ICollector<T>, que representa uma coleção de mensagens que são gravadas em uma associação de saída quando a função é concluída.The msg parameter is an ICollector<T> type, which represents a collection of messages that are written to an output binding when the function completes. Nesse caso, a saída é uma fila de armazenamento denominada outqueue.In this case, the output is a storage queue named outqueue. A cadeia de conexão para a Conta de armazenamento é definida pelo StorageAccountAttribute.The connection string for the Storage account is set by the StorageAccountAttribute. Esse atributo indica a configuração que contém a cadeia de conexão da Conta de armazenamento e pode ser aplicada no nível de classe, método ou parâmetro.This attribute indicates the setting that contains the Storage account connection string and can be applied at the class, method, or parameter level. Nesse caso, você poderia omitir StorageAccountAttribute porque já está usando a conta de armazenamento padrão.In this case, you could omit StorageAccountAttribute because you are already using the default storage account.

A definição do método Executar deve agora se parecer com o seguinte:The Run method definition should now look like the following:

[FunctionName("HttpExample")]
public static async Task<IActionResult> Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req, 
    [Queue("outqueue"),StorageAccount("AzureWebJobsStorage")] ICollector<string> msg, 
    ILogger log)

Em um projeto Java, as associações são definidas como anotações de associação no método de função.In a Java project, the bindings are defined as binding annotations on the function method. O arquivo function.json é então gerado automaticamente com base nessas anotações.The function.json file is then autogenerated based on these annotations.

Procure a localização do código de função em src/main/java, abra o arquivo de projeto Function.java e adicione o seguinte parâmetro à definição do método run:Browse to the location of your function code under src/main/java, open the Function.java project file, and add the following parameter to the run method definition:

@QueueOutput(name = "msg", queueName = "outqueue", connection = "AzureWebJobsStorage") OutputBinding<String> msg

O parâmetro msg é um tipo OutputBinding<T>, que representa uma coleção de cadeias de caracteres que são gravadas como mensagens em uma associação de saída quando a função é concluída.The msg parameter is an OutputBinding<T> type, which represents a collection of strings that are written as messages to an output binding when the function completes. Nesse caso, a saída é uma fila de armazenamento denominada outqueue.In this case, the output is a storage queue named outqueue. A cadeia de conexão para a conta de armazenamento é definida pelo método connection.The connection string for the Storage account is set by the connection method. Em vez da própria cadeia de conexão, passe a configuração de aplicativo que contém a cadeia de conexão da conta de armazenamento.Rather than the connection string itself, you pass the application setting that contains the Storage account connection string.

A definição do método run agora deverá ser semelhante ao seguinte exemplo:The run method definition should now look like the following example:

@FunctionName("HttpTrigger-Java")
public HttpResponseMessage run(
        @HttpTrigger(name = "req", methods = {HttpMethod.GET, HttpMethod.POST}, authLevel = AuthorizationLevel.FUNCTION)  
        HttpRequestMessage<Optional<String>> request, 
        @QueueOutput(name = "msg", queueName = "outqueue", connection = "AzureWebJobsStorage") 
        OutputBinding<String> msg, final ExecutionContext context) {
    ...
}

Adicionar código para usar a associação de saídaAdd code to use the output binding

Com a associação de fila definida, agora você pode atualizar sua função para receber o parâmetro de saída msg e gravar mensagens na fila.With the queue binding defined, you can now update your function to receive the msg output parameter and write messages to the queue.

Atualize HttpExample\__init__.py para que ele corresponda ao código a seguir, adicionando o parâmetro msg à definição da função e a msg.set(name) na instrução if name:.Update HttpExample\__init__.py to match the following code, adding the msg parameter to the function definition and msg.set(name) under the if name: statement.

import logging

import azure.functions as func


def main(req: func.HttpRequest, msg: func.Out[func.QueueMessage]) -> str:

    name = req.params.get('name')
    if not name:
        try:
            req_body = req.get_json()
        except ValueError:
            pass
        else:
            name = req_body.get('name')

    if name:
        msg.set(name)
        return func.HttpResponse(f"Hello {name}!")
    else:
        return func.HttpResponse(
            "Please pass a name on the query string or in the request body",
            status_code=400
        )

O parâmetro msg é uma instância do azure.functions.InputStream class.The msg parameter is an instance of the azure.functions.InputStream class. O método set grava uma mensagem de cadeia de caracteres na fila, nesse caso, o nome transmitido para a função na cadeia de consulta de URL.Its set method writes a string message to the queue, in this case the name passed to the function in the URL query string.

Adicione um código que usa o objeto de associação de saída msg em context.bindings para criar uma mensagem da fila.Add code that uses the msg output binding object on context.bindings to create a queue message. Adicione esse código antes da instrução context.res.Add this code before the context.res statement.

// Add a message to the Storage queue,
// which is the name passed to the function.
context.bindings.msg = (req.query.name || req.body.name);

Neste ponto, sua função deve ser a seguinte:At this point, your function should look as follows:

module.exports = async function (context, req) {
    context.log('JavaScript HTTP trigger function processed a request.');

    if (req.query.name || (req.body && req.body.name)) {
        // Add a message to the Storage queue,
        // which is the name passed to the function.
        context.bindings.msg = (req.query.name || req.body.name);
        context.res = {
            // status: 200, /* Defaults to 200 */
            body: "Hello " + (req.query.name || req.body.name)
        };
    }
    else {
        context.res = {
            status: 400,
            body: "Please pass a name on the query string or in the request body"
        };
    }
};

Adicione um código que usa o objeto de associação de saída msg em context.bindings para criar uma mensagem da fila.Add code that uses the msg output binding object on context.bindings to create a queue message. Adicione esse código antes da instrução context.res.Add this code before the context.res statement.

context.bindings.msg = name;

Neste ponto, sua função deve ser a seguinte:At this point, your function should look as follows:

import { AzureFunction, Context, HttpRequest } from "@azure/functions"

const httpTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise<void> {
    context.log('HTTP trigger function processed a request.');
    const name = (req.query.name || (req.body && req.body.name));

    if (name) {
        // Add a message to the storage queue, 
        // which is the name passed to the function.
        context.bindings.msg = name; 
        // Send a "hello" response.
        context.res = {
            // status: 200, /* Defaults to 200 */
            body: "Hello " + (req.query.name || req.body.name)
        };
    }
    else {
        context.res = {
            status: 400,
            body: "Please pass a name on the query string or in the request body"
        };
    }
};

export default httpTrigger;

Adicione código que usa o cmdlet Push-OutputBinding para gravar texto na fila usando a associação de saída msg.Add code that uses the Push-OutputBinding cmdlet to write text to the queue using the msg output binding. Adicione esse código antes de definir o status como OK na instrução if.Add this code before you set the OK status in the if statement.

$outputMsg = $name
Push-OutputBinding -name msg -Value $outputMsg

Neste ponto, sua função deve ser a seguinte:At this point, your function should look as follows:

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 or the body of the request.
$name = $Request.Query.Name
if (-not $name) {
    $name = $Request.Body.Name
}

if ($name) {
    # Write the $name value to the queue, 
    # which is the name passed to the function.
    $outputMsg = $name
    Push-OutputBinding -name msg -Value $outputMsg

    $status = [HttpStatusCode]::OK
    $body = "Hello $name"
}
else {
    $status = [HttpStatusCode]::BadRequest
    $body = "Please pass a name on the query string or in the request body."
}

# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
    StatusCode = $status
    Body = $body
})

Adicione um código que usa o objeto de associação de saída de msg para criar uma mensagem da fila.Add code that uses the msg output binding object to create a queue message. Adicione esse código antes do método retornar.Add this code before the method returns.

if (!string.IsNullOrEmpty(name))
{
    // Add a message to the output collection.
    msg.Add(string.Format("Name passed to the function: {0}", name));
}

Neste ponto, sua função deve ser a seguinte:At this point, your function should look as follows:

[FunctionName("HttpExample")]
public static async Task<IActionResult> Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req, 
    [Queue("outqueue"),StorageAccount("AzureWebJobsStorage")] ICollector<string> msg, 
    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;

    if (!string.IsNullOrEmpty(name))
    {
        // Add a message to the output collection.
        msg.Add(string.Format("Name passed to the function: {0}", name));
    }
    return name != null
        ? (ActionResult)new OkObjectResult($"Hello, {name}")
        : new BadRequestObjectResult("Please pass a name on the query string or in the request body");
}

Agora, você pode usar o novo parâmetro msg para fazer a gravação na associação de saída por meio do código de função.Now, you can use the new msg parameter to write to the output binding from your function code. Adicione a linha de código a seguir antes da resposta de êxito para adicionar o valor de name à associação de saída msg.Add the following line of code before the success response to add the value of name to the msg output binding.

msg.setValue(name);

Ao usar uma associação de saída, não é necessário usar o código do SDK do Armazenamento do Azure para se autenticar, para obter uma referência de fila ou para escrever dados.When you use an output binding, you don't have to use the Azure Storage SDK code for authentication, getting a queue reference, or writing data. O runtime do Functions e a associação de saída da fila fazem essas tarefas para você.The Functions runtime and queue output binding do those tasks for you.

O método run agora deverá ser semelhante ao seguinte exemplo:Your run method should now look like the following example:

public HttpResponseMessage run(
        @HttpTrigger(name = "req", methods = {HttpMethod.GET, HttpMethod.POST}, authLevel = AuthorizationLevel.ANONYMOUS) 
        HttpRequestMessage<Optional<String>> request, 
        @QueueOutput(name = "msg", queueName = "outqueue", 
        connection = "AzureWebJobsStorage") OutputBinding<String> msg, 
        final ExecutionContext context) {
    context.getLogger().info("Java HTTP trigger processed a request.");

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

    if (name == null) {
        return request.createResponseBuilder(HttpStatus.BAD_REQUEST)
        .body("Please pass a name on the query string or in the request body").build();
    } else {
        // Write the name to the message queue. 
        msg.setValue(name);

        return request.createResponseBuilder(HttpStatus.OK).body("Hello, " + name).build();
    }
}

Atualizar os testesUpdate the tests

Como o arquétipo também cria um conjunto de testes, você precisa atualizar esses testes para manipular o novo parâmetro msg na assinatura do método run.Because the archetype also creates a set of tests, you need to update these tests to handle the new msg parameter in the run method signature.

Procure a localização do código de teste em src/test/java, abra o arquivo de projeto Function.java e substitua a linha de código em //Invoke pelo código a seguir.Browse to the location of your test code under src/test/java, open the Function.java project file, and replace the line of code under //Invoke with the following code.

@SuppressWarnings("unchecked")
final OutputBinding<String> msg = (OutputBinding<String>)mock(OutputBinding.class);
final HttpResponseMessage ret = new Function().run(req, msg, context);

Atualizar a imagem no RegistroUpdate the image in the registry

  1. Na pasta raiz, execute docker build novamente e, desta vez, atualize a versão na marca para v1.0.1.In the root folder, run docker build again, and this time update the version in the tag to v1.0.1. Assim como antes, substitua <docker_id> pela ID da conta do Docker Hub:As before, replace <docker_id> with your Docker Hub account ID:

    docker build --tag <docker_id>/azurefunctionsimage:v1.0.1 .
    
  2. Envie a imagem atualizada por push de volta para o repositório usando docker push:Push the updated image back to the repository with docker push:

    docker push <docker_id>/azurefunctionsimage:v1.0.1
    
  3. Como você configurou a entrega contínua, atualizar a imagem no Registro novamente atualiza automaticamente seu aplicativo de funções no Azure.Because you configured continuous delivery, updating the image in the registry again automatically updates your function app in Azure.

Exibir a mensagem na fila do Armazenamento do AzureView the message in the Azure Storage queue

Em um navegador, use a mesma URL que antes para invocar a função.In a browser, use the same URL as before to invoke your function. O navegador deve exibir a mesma resposta que antes, porque você não modificou essa parte do código da função.The browser should display the same response as before, because you didn't modify that part of the function code. O código adicionado, no entanto, gravou uma mensagem usando o parâmetro de URL name na fila de armazenamento outqueue.The added code, however, wrote a message using the name URL parameter to the outqueue storage queue.

Veja a fila no portal do Azure ou no Gerenciador de Armazenamento do Microsoft Azure.You can view the queue in the Azure portal or in the Microsoft Azure Storage Explorer. Veja também a fila na CLI do Azure, conforme descrito nas seguintes etapas:You can also view the queue in the Azure CLI, as described in the following steps:

  1. Abra o arquivo local.setting.json do projeto de funções e copie o valor da cadeia de conexão.Open the function project's local.setting.json file and copy the connection string value. Em um terminal ou uma janela Comando, execute o comando a seguir para criar uma variável de ambiente chamada AZURE_STORAGE_CONNECTION_STRING, colando a cadeia de conexão específica no lugar de <MY_CONNECTION_STRING>.In a terminal or command window, run the following command to create an environment variable named AZURE_STORAGE_CONNECTION_STRING, pasting your specific connection string in place of <MY_CONNECTION_STRING>. (Essa variável de ambiente significa que você não precisa fornecer a cadeia de conexão para cada comando posterior usando o argumento --connection-string.)(This environment variable means you don't need to supply the connection string to each subsequent command using the --connection-string argument.)

    export AZURE_STORAGE_CONNECTION_STRING="<MY_CONNECTION_STRING>"
    
  2. (Opcional) Use o comando az storage queue list para ver as filas de armazenamento em sua conta.(Optional) Use the az storage queue list command to view the Storage queues in your account. A saída desse comando deve incluir uma fila chamada outqueue, que foi criada quando a função gravou a primeira mensagem nessa fila.The output from this command should include a queue named outqueue, which was created when the function wrote its first message to that queue.

    az storage queue list --output tsv
    
  3. Use o comando az storage message get para ler as mensagens dessa fila, que deve ser o primeiro nome usado ao testar a função anteriormente.Use the az storage message get command to read the message from this queue, which should be the first name you used when testing the function earlier. O comando lê e remove a primeira mensagem da fila.The command reads and removes the first message from the queue.

    echo `echo $(az storage message get --queue-name outqueue -o tsv --query '[].{Message:content}') | base64 --decode`
    

    Como o corpo da mensagem é armazenado codificado em base64, a mensagem deve ser decodificada antes de ser exibida.Because the message body is stored base64 encoded, the message must be decoded before it's displayed. Depois de executar az storage message get, a mensagem é removida da fila.After you execute az storage message get, the message is removed from the queue. Se houver apenas uma mensagem em outqueue, você não recuperará uma mensagem quando executar esse comando pela segunda vez e receberá um erro.If there was only one message in outqueue, you won't retrieve a message when you run this command a second time and instead get an error.

Limpar os recursosClean up resources

Se quiser continuar trabalhando com o Azure Functions usando os recursos criados neste tutorial, mantenha todos esses recursos.If you want to continue working with Azure Function using the resources you created in this tutorial, you can leave all those resources in place. Como criou um Plano Premium para o Azure Functions, você terá um custo contínuo de USD 1 ou 2 por dia.Because you created a Premium Plan for Azure Functions, you'll incur one or two USD per day in ongoing costs.

Para evitar os custos contínuos, exclua o grupo de recursos AzureFunctionsContainer-rg para limpar todos os recursos que estão nele:To avoid ongoing costs, delete the AzureFunctionsContainer-rg resource group to clean up all the resources in that group:

az group delete --name AzureFunctionsContainer-rg

Próximas etapasNext steps