Partekatu honen bidez:


Inicio rápido: Creación de una aplicación de Durable Functions que usa el proveedor de almacenamiento MSSQL

Use Durable Functions, una característica de Azure Functions, para escribir funciones con estado en un entorno sin servidor. Durable Functions administra el estado, los puntos de control y los reinicios en la aplicación.

Durable Functions es compatible con varios proveedores de almacenamiento, también denominados back-ends, para almacenar el estado en tiempo de ejecución de la orquestación y la entidad. En esta guía rápida, creas una aplicación de Durable Functions para usar el proveedor de almacenamiento de Microsoft SQL Server (MSSQL) mediante Visual Studio Code.

En este inicio rápido se crea una aplicación de .NET (modelo aislado) con fines de demostración. El contenido proporcionado en este artículo se aplica a otros idiomas de maneras similares.

Nota:

  • El back-end de MSSQL se diseñó para maximizar la portabilidad y el control de las aplicaciones sobre los datos. Usa Microsoft SQL Server para conservar todos los datos del centro de tareas para que los usuarios obtengan las ventajas de una infraestructura moderna de sistema de administración de bases de datos de nivel empresarial (DBMS). Para obtener más información sobre cuándo usar el proveedor de almacenamiento MSSQL, vea la introducción a los proveedores de almacenamiento.

  • Actualmente no se admite la migración de datos del centro de tareas entre proveedores de almacenamiento. Las aplicaciones de funciones que tienen datos en tiempo de ejecución existentes comienzan con un centro de tareas nuevo y vacío después de cambiar al back-end de MSSQL. Del mismo modo, el contenido del centro de tareas que se crea mediante MSSQL no se puede conservar si cambia a otro proveedor de almacenamiento.

Requisitos previos

Para completar este inicio rápido necesita instalar:

Creación de un proyecto de Azure Functions

En Visual Studio Code, cree un proyecto local de Azure Functions.

  1. En el menú Ver, seleccione Paleta de comandos (o seleccione Ctrl+Mayús+P).

  2. En la solicitud (>), escriba y seleccione Azure Functions: Crear nuevo proyecto.

    Recorte de pantalla que muestra el comando para crear un proyecto de Functions.

  3. Selecciona Examinar. En el cuadro de diálogo Seleccionar carpeta, vaya a una carpeta que se vaya a usar para el proyecto y, a continuación, elija Seleccionar.

  4. En las indicaciones, seleccione o escriba los siguientes valores:

    Pronto Acción Descripción
    Selección de un lenguaje para el proyecto de la aplicación de funciones Selección de .NET Crea un proyecto de Funciones de C# local
    Seleccione un entorno de ejecución .NET. Seleccione .NET 8.0. aislado. Crea un proyecto de Functions que admite .NET 8 que se ejecuta en un proceso de trabajo aislado y Azure Functions Runtime 4.0.
    Seleccionar una plantilla para la primera función de su proyecto Seleccione Orquestación de Durable Functions. Crea una orquestación de Durable Functions.
    Elección de un tipo de almacenamiento duradero Seleccione MSSQL. Selecciona el proveedor de almacenamiento de MSSQL.
    Proporcionar un nombre de función Escriba HelloOrchestration. Un nombre de la función de orquestación.
    Proporcionar un espacio de nombres Escriba Company.Function. Un espacio de nombres para la clase generada.
    Seleccionar cómo desea que se abra el proyecto Seleccione Abrir en la ventana actual. Abre Visual Studio Code en la carpeta seleccionada.

Visual Studio Code instala Azure Functions Core Tools si es necesario crear el proyecto. También crea el proyecto de una aplicación de funciones en una carpeta. Este proyecto contiene los archivos de configuración host.json y local.settings.json.

Otro archivo, HelloOrchestration.cs, contiene los bloques de creación básicos de una aplicación de Durable Functions:

Método Descripción
HelloOrchestration Define la orquestación de aplicaciones de Durable Functions. En este caso, la orquestación se inicia, crea una lista y, a continuación, le agrega el resultado de tres llamadas a funciones. Una vez finalizadas las tres llamadas a funciones, devuelve la lista.
SayHello Una aplicación de funciones sencilla que devuelve hola. Esta función contiene la lógica de negocios que está orquestada.
HelloOrchestration_HttpStart Una función desencadenada por HTTP que inicia una instancia de la orquestación y devuelve una respuesta de comprobación de estado.

Para obtener más información sobre estas funciones, consulte Características y tipos de Durable Functions.

Configuración de la base de datos

Nota:

Si ya tiene una base de datos compatible con MSSQL, puede omitir esta sección y omitir la sección siguiente sobre cómo configurar una base de datos local basada en Docker.

Dado que el back-end de MSSQL está diseñado para la portabilidad, tiene varias opciones para configurar la base de datos de copia de seguridad. Por ejemplo, puede configurar una instancia de SQL Server local, usar una instancia totalmente administrada de Azure SQL Database, o usar cualquier otra opción de hospedaje compatible con SQL Server.

También puede realizar el desarrollo local y sin conexión mediante SQL Server Express en el equipo Windows local o usar una imagen de Docker de SQL Server que se ejecuta en un contenedor de Docker.

Este inicio rápido se centra en el uso de una imagen de Docker de SQL Server.

Configuración de la instancia local de SQL Server basada en Docker

Use los siguientes comandos de PowerShell para configurar una base de datos local de SQL Server en Docker. Puede instalar PowerShell en Windows, macOS o Linux.

# primary parameters
$pw        = "yourStrong(!)Password"
$edition   = "Developer"
$port      = 1433
$tag       = "2019-latest"
$dbname    = "DurableDB"
$collation = "Latin1_General_100_BIN2_UTF8"

# pull the image from the Microsoft container registry
docker pull mcr.microsoft.com/mssql/server:$tag

# run the image and provide some basic setup parameters
docker run --name mssql-server -e 'ACCEPT_EULA=Y' -e "MSSQL_SA_PASSWORD=$pw" -e "MSSQL_PID=$edition" -p ${port}:1433 -d mcr.microsoft.com/mssql/server:$tag

# wait a few seconds for the container to start...

# create the database with strict binary collation
docker exec -it mssql-server /opt/mssql-tools/bin/sqlcmd -S . -U sa -P "$pw" -Q "CREATE DATABASE [$dbname] COLLATE $collation"

# if sqlcmd is in the mssql-tools18 folder
# docker exec -it mssql-server /opt/mssql-tools18/bin/sqlcmd -C -S . -U sa -P "$pw" -Q "CREATE DATABASE [$dbname] COLLATE $collation"

Ahora debería tener una instancia local de SQL Server que se ejecuta en Docker y está escuchando en el puerto 1443. Si el puerto 1443 entra en conflicto con otro servicio, vuelva a ejecutar estos comandos después de cambiar la variable $port a un valor diferente.

Para validar la instalación de la base de datos, consulte la nueva base de datos SQL:

docker exec -it mssql-server /opt/mssql-tools/bin/sqlcmd -S . -U sa -P "$pw" -Q "SELECT name FROM sys.databases"

Si la configuración de la base de datos se completó correctamente, el nombre de la base de datos (por ejemplo, DurableDB) aparece en la salida de la línea de comandos:

name

--------------------------------------------------------------
master

tempdb

model

msdb

DurableDB

Nota:

Para detener y eliminar un contenedor en ejecución, puede usar docker stop <containerName> y docker rm <containerName> respectivamente. Puede usar estos comandos para volver a crear el contenedor y detenerlo cuando termine este inicio rápido. Para obtener más ayuda, ejecute docker --help.

Solución de problemas

Si se encuentra con "Error de respuesta del demonio: error del exec en tiempo de ejecución de OCI" al ejecutar docker exec para crear la base de datos, es probable que la carpeta /opt/mssql-tools/bin/sqlcmd no exista. Abra Docker Desktop, seleccione el contenedor de Docker de SQL Server, seleccione Archivos y busque la carpeta mssql-tools. Compruebe si esta carpeta tiene un nombre diferente, como /opt/mssql-tools18/bin/sqlcmd. Actualice el comando en consecuencia.

En ODBC Driver 18 para SQL Server, la opción Cifrar conexión se establece en true de forma predeterminada. Si se encuentra con "error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed:self signed certificate" al ejecutar docker exec para realizar operaciones de base de datos, anexe -C, que es equivalente a la opción de ADO.net TRUSTSERVERCERTIFICATE = true.

Adición de una cadena de conexión SQL a local.settings.json

El back-end de MSSQL necesita una cadena de conexión para acceder a la base de datos. La obtención de una cadena de conexión depende principalmente de su proveedor de servidor MSSQL específico.

Si usa los comandos anteriores de Docker sin cambiar ningún parámetro, la cadena de conexión es:

Server=localhost,1433;Database=DurableDB;User Id=sa;Password=yourStrong(!)Password;

En local.settings.json, asigne la cadena de conexión de la instancia de SQL Server basada en Docker a SQLDB_Connection. Visual Studio Code agregó esta variable al seleccionar MSSQL como backend para la aplicación Durable Functions.

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true", 
    "SQLDB_Connection": "Server=localhost,1433;Database=DurableDB;User Id=sa;Password=yourStrong(!)Password;",
    "FUNCTIONS_WORKER_RUNTIME": "<dependent on your programming language>"
  }
}

Prueba local

Abra una ventana de terminal en la carpeta raíz de la aplicación y ejecute azurite start. Azurite es el emulador de Azure Storage, que es necesario para ejecutar cualquier aplicación de funciones.

Abra otra ventana de terminal en la carpeta raíz de la aplicación e inicie la aplicación de funciones ejecutando func host start.

  1. En la ventana de terminal, copie el punto de conexión URL de la función activada por HTTP.

    Recorte de pantalla de la ventana de salida local de Azure.

  2. Use una herramienta de prueba HTTP para enviar una solicitud HTTP POST al punto de conexión de la dirección URL.

    La respuesta es el resultado inicial de la función HTTP. Le hace saber que la orquestación de Durable Functions se inició correctamente. Todavía no muestra el resultado final de la orquestación. La respuesta incluye algunas direcciones URL útiles.

  3. Copie el valor de la dirección URL de statusQueryGetUri, péguelo en la barra de direcciones del explorador y ejecute la solicitud. Como alternativa, también puede seguir usando la herramienta de prueba HTTP para emitir la solicitud GET.

    La solicitud consultará la instancia de orquestación sobre el estado. Debería ver que la instancia finalizó y que incluye las salidas o los resultados de la aplicación de Durable Functions como en este ejemplo:

    {
        "name":"HelloCities",
        "instanceId":"7f99f9474a6641438e5c7169b7ecb3f2",
        "runtimeStatus":"Completed",
        "input":null,
        "customStatus":null,
        "output":"Hello, Tokyo! Hello, London! Hello, Seattle!",
        "createdTime":"2023-01-31T18:48:49Z",
        "lastUpdatedTime":"2023-01-31T18:48:56Z"
    }
    

Ejecución de la aplicación en Azure

Para ejecutar la aplicación en Azure, debe crear varios recursos. Para una limpieza cómoda más adelante, cree todos los recursos del mismo grupo de recursos.

Crear una base de datos de Azure SQL

Nota:

Si ya tiene una base de datos de Azure SQL u otra instancia de SQL Server accesible públicamente que desea usar, puede ir a la sección siguiente.

No permitir que los servicios y recursos de Azure accedan a esta configuración de servidor [SQL] para escenarios de producción. Las aplicaciones reales deben implementar enfoques más seguros, como restricciones de firewall más fuertes o configuraciones de red virtual.

En Azure Portal, puede crear una base de datos de Azure SQL. Durante la creación:

  • Habilitación de los servicios y recursos de Azure para acceder a este servidor (en Redes)
  • Establezca el valor de Intercalación de base de datos (en Configuración adicional) en Latin1_General_100_BIN2_UTF8.

Creación de una aplicación de Azure Functions y recursos auxiliares

  1. Abra una ventana de terminal e inicie sesión en Azure:

    az login
    
  2. Cree los siguientes recursos en el mismo grupo de recursos y región que la base de datos SQL:

    • Una cuenta de almacenamiento de uso general, que se usa para almacenar datos importantes de la aplicación, como el propio código de la aplicación. Los nombres de cuenta de almacenamiento deben contener solo tres a 24 caracteres y letras minúsculas.
    • Un plan para una aplicación funcional premium
    • Una aplicación de funciones
    # Variables
    location=<REGION>
    resourceGroup=<RESOURCE_GROUP_NAME>
    storage=<STORAGE_NAME>
    planName=<PREMIUM_PLAN_NAME>
    functionApp=<APP_NAME>
    skuStorage="Standard_LRS"
    skuPlan="EP1"
    functionsVersion="4"
    
    # Create an Azure storage account
    echo "Creating $storage"
    az storage account create --name $storage --location "$location" --resource-group $resourceGroup --sku $skuStorage --allow-blob-public-access false
    
    # Create a premium plan
    echo "Creating $premiumPlan"
    az functionapp plan create --name $planName --resource-group $resourceGroup --location "$location" --sku $skuPlan
    
    # Create a function app hosted in the premium plan
    echo "Creating $functionApp"
    az functionapp create --name $functionApp --storage-account $storage --plan $planName --resource-group $resourceGroup --functions-version $functionsVersion
    

Creación de una identidad administrada de Azure

Las identidades administradas hacen que la aplicación sea más segura mediante la eliminación de secretos de la aplicación, como las credenciales de las cadenas de conexión. Puede elegir entre la identidad administrada asignada por el sistema y la asignada por el usuario. En este inicio rápido se muestra cómo configurar la identidad administrada asignada por el usuario, que es la opción recomendada, ya que no está vinculada al ciclo de vida de la aplicación.

Los siguientes comandos crean el recurso de identidad y lo asignan a la aplicación:

# Variables
subscription=<SUBSCRIPTION_ID>
identity=<IDENTITY_NAME>

# Create a managed identity resource
echo "Creating $identity"
az identity create -g $resourceGroup -n $identity --location "$location"

# Construct the identity resource ID 
resourceId="/subscriptions/$subscription/resourceGroups/$resourceGroup/providers/Microsoft.ManagedIdentity/userAssignedIdentities/$identity"

# Assign the identity to the Azure Functions app
echo "Assigning $identity to app"
az functionapp identity assign -g $resourceGroup -n $functionApp --identities "$resourceId"

# Get the identity's ClientId and PrincipalId (also called ObjectId) for a later step. 
clientId=$(az identity show --name $identity --resource-group $resourceGroup --query 'clientId' --output tsv)

principalId=$(az identity show --name $identity --resource-group $resourceGroup --query 'principalId' --output tsv)

Concesión de acceso a Azure Storage y Azure SQL Database

Azure Storage

Asigne el rol de identidad Propietario de datos de Storage Blob para acceder a la cuenta de almacenamiento.

# Set the scope of the access
scope="/subscriptions/$subscription/resourceGroups/$resourceGroup/providers/Microsoft.Storage/storageAccounts/$storage"

# Assign the role
echo "Assign Storage Blob Data Owner role to identity"
az role assignment create --assignee "$clientId" --role "Storage Blob Data Owner" --scope "$scope"

Azure SQL Database

Nota:

No se admite la autenticación en la base de datos de Azure SQL mediante identidad administrada al hospedar una aplicación de Durable Functions en el plan de consumo flexible. Si la aplicación está hospedada en el plan de consumo flexible, vaya a la sección Establecer configuración de la aplicación .

  1. Comience estableciendo la identidad del desarrollador como administrador de la base de datos.

    El usuario asignado es su identidad, así que cambie a su correo electrónico:

    assignee=$(az ad user show --id "someone@example.com" --query "id" --output tsv)
    

    Establezca assignee como administrador de la base de datos de Azure SQL:

    az sql server ad-admin create --resource-group $resourceGroup --server-name <SQL_SERVER_NAME> --display-name ADMIN --object-id "$assignee"
    
  2. Conéctese a la base de datos SQL creada anteriormente mediante herramientas como Azure Data Studio o SQL Management Server Studio. O bien, puede ejecutar el siguiente comando SQLCMD para conectarse:

    sqlcmd -S <SQL_SERVER_NAME>.database.windows.net -d <DATABASE_NAME> -U <someone@example.com> -P "ACCOUNT_PASSWORD" -G -l 30
    

    Conceda a la identidad db_owner acceso mediante la ejecución de la consulta siguiente en la base de datos. El IDENTITY_OBJECT_ID es el PrincipalId del paso de creación de identidades.

    CREATE USER "<IDENTITY_NAME>" FROM EXTERNAL PROVIDER With OBJECT_ID='<IDENTITY_OBJECT_ID>'
    ALTER ROLE db_owner ADD MEMBER "<IDENTITY_NAME>";
    GO
    
  3. Conéctese a la base de datos master y conceda acceso a su identidad dbmanager:

    CREATE USER "<IDENTITY_NAME>" FROM EXTERNAL PROVIDER With OBJECT_ID='<IDENTITY_OBJECT_ID>'
    ALTER ROLE dbmanager ADD MEMBER "<IDENTITY_NAME>";
    GO
    

Establecimiento de la configuración de aplicación necesaria

Debe agregar la siguiente configuración de la aplicación a la aplicación:

  • AzureWebJobsStorage__accountName: nombre de la cuenta de Azure Storage
  • AzureWebJobsStorage__clientId: ClientId de la identidad administrada
  • AzureWebJobsStorage__credential: tipo de credencial, que es managedidentity.
  • SQLDB_Connection: cadena de conexión de base de datos SQL

Si usa la identidad administrada asignada por el usuario para autenticarse en la base de datos SQL, la cadena de conexión debe ser similar a la siguiente:

dbserver=<SQL_SERVER_NAME>
sqlDB=<SQL_DB_NAME>
clientId=<IDENTITY_CLIENT_ID>

sqlconnstr="Server=tcp:$dbserver.database.windows.net,1433;Initial Catalog=$sqlDB;Persist Security Info=False;User ID=$clientId;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Authentication='Active Directory Managed Identity';"

En el caso de las aplicaciones flex Consumption, use una cadena de conexión para autenticarse por ahora. Para encontrarlo, vaya al recurso de SQL Database en Azure Portal, vaya a la pestaña Configuración y haga clic en Cadenas de conexión:

Captura de pantalla que muestra la cadena de conexión de la base de datos.

La cadena de conexión debe tener este formato:

dbserver=<SQL_SERVER_NAME>
sqlDB=<SQL_DB_NAME>
username=<DB_USER_LOGIN>
password=<DB_USER_PASSWORD>

sqlconnstr="Server=tcp:$dbserver.database.windows.net,1433;Initial Catalog=$sqlDB;Persist Security Info=False;User ID=$username;Password=$password;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;"

Ejecute el siguiente comando para establecer la configuración:

az functionapp config appsettings set --name $functionApp --resource-group $resourceGroup --settings AzureWebJobsStorage__accountName="$storage" AzureWebJobsStorage__clientId="$clientId" AzureWebJobsStorage__credential="managedidentity" SQLDB_Connection=$sqlconnstr

Elimine la configuración existente AzureWebJobsStorage :

az functionapp config appsettings delete --name $functionApp --resource-group $resourceGroup --setting-names "AzureWebJobsStorage"

Implementación del proyecto local en Azure y prueba

Por último, en la carpeta del proyecto raíz, implemente la aplicación en Azure mediante la ejecución de:

func azure functionapp publish $functionApp

Una vez finalizada la implementación, ejecute lo siguiente para obtener la dirección URL del desencadenador HTTP:

az functionapp function list --resource-group $resourceGroup --name $functionApp  --query '[].{Function:name, URL:invokeUrlTemplate}' --output json

Pruebe como hizo durante el desarrollo local con una herramienta de prueba HTTP.

También puede validar que el back-end de MSSQL está configurado correctamente consultando la base de datos para los datos del centro de tareas.

Por ejemplo, puede consultar las instancias de orquestación en el panel de información general de la base de datos SQL. Seleccione Editor de consultas, autentíquese y, a continuación, ejecute la consulta siguiente:

SELECT TOP 5 InstanceID, RuntimeStatus, CreatedTime, CompletedTime FROM dt.Instances

Después de ejecutar un orquestador simple, debería ver al menos un resultado, como se muestra en este ejemplo:

Captura de pantalla que muestra los resultados del Editor de consultas de Azure SQL para la consulta SQL.

Pasos siguientes