Połączenie usługi Azure Functions do usługi Azure Storage przy użyciu narzędzi wiersza polecenia

W tym artykule zintegrowano kolejkę usługi Azure Storage z funkcją i kontem magazynu utworzonym w poprzednim artykule Szybki start. Ta integracja jest osiągana przy użyciu powiązania wyjściowego, które zapisuje dane z żądania HTTP do komunikatu w kolejce. Ukończenie tego artykułu nie wiąże się z dodatkowymi kosztami przekraczającymi kilka centów USD z poprzedniego przewodnika Szybki start. Aby dowiedzieć się więcej na temat powiązań, zobacz Pojęcia dotyczące wyzwalaczy i powiązań usługi Azure Functions.

Konfigurowanie środowiska lokalnego

Przed rozpoczęciem należy ukończyć artykuł Szybki start: tworzenie projektu usługi Azure Functions z poziomu wiersza polecenia. Jeśli zasoby zostały już wyczyszczone na końcu tego artykułu, wykonaj kroki ponownie, aby ponownie utworzyć aplikację funkcji i powiązane zasoby na platformie Azure.

Przed rozpoczęciem należy ukończyć artykuł Szybki start: tworzenie projektu usługi Azure Functions z poziomu wiersza polecenia. Jeśli zasoby zostały już wyczyszczone na końcu tego artykułu, wykonaj kroki ponownie, aby ponownie utworzyć aplikację funkcji i powiązane zasoby na platformie Azure.

Przed rozpoczęciem należy ukończyć artykuł Szybki start: tworzenie projektu usługi Azure Functions z poziomu wiersza polecenia. Jeśli zasoby zostały już wyczyszczone na końcu tego artykułu, wykonaj kroki ponownie, aby ponownie utworzyć aplikację funkcji i powiązane zasoby na platformie Azure.

Przed rozpoczęciem należy ukończyć artykuł Szybki start: tworzenie projektu usługi Azure Functions z poziomu wiersza polecenia. Jeśli zasoby zostały już wyczyszczone na końcu tego artykułu, wykonaj kroki ponownie, aby ponownie utworzyć aplikację funkcji i powiązane zasoby na platformie Azure.

Przed rozpoczęciem należy ukończyć artykuł Szybki start: tworzenie projektu usługi Azure Functions z poziomu wiersza polecenia. Jeśli zasoby zostały już wyczyszczone na końcu tego artykułu, wykonaj kroki ponownie, aby ponownie utworzyć aplikację funkcji i powiązane zasoby na platformie Azure.

Przed rozpoczęciem należy ukończyć artykuł Szybki start: tworzenie projektu usługi Azure Functions z poziomu wiersza polecenia. Jeśli zasoby zostały już wyczyszczone na końcu tego artykułu, wykonaj kroki ponownie, aby ponownie utworzyć aplikację funkcji i powiązane zasoby na platformie Azure.

Pobieranie parametry połączenia usługi Azure Storage

Wcześniej utworzono konto usługi Azure Storage na potrzeby użycia aplikacji funkcji. Parametry połączenia dla tego konta jest bezpiecznie przechowywana w ustawieniach aplikacji na platformie Azure. Pobierając ustawienie do pliku local.settings.json , możesz użyć połączenia do zapisu w kolejce usługi Storage na tym samym koncie podczas uruchamiania funkcji lokalnie.

  1. W katalogu głównym projektu uruchom następujące polecenie, zastąp <APP_NAME> ciąg nazwą aplikacji funkcji z poprzedniego kroku. To polecenie zastępuje wszystkie istniejące wartości w pliku.

    func azure functionapp fetch-app-settings <APP_NAME>
    
  2. Otwórz plik local.settings.json i znajdź wartość o nazwie AzureWebJobsStorage, która jest kontem magazynu parametry połączenia. Nazwa i parametry połączenia są używane AzureWebJobsStorage w innych sekcjach tego artykułu.

Ważne

Ponieważ plik local.settings.json zawiera wpisy tajne pobrane z platformy Azure, zawsze wykluczaj ten plik z kontroli źródła. Plik .gitignore utworzony za pomocą projektu funkcji lokalnych wyklucza plik domyślnie.

Rejestrowanie rozszerzeń do wiązania

Z wyjątkiem wyzwalaczy HTTP i czasomierza powiązania są implementowane jako pakiety rozszerzeń. Uruchom następujące polecenie dotnet add package w oknie terminalu, aby dodać pakiet rozszerzenia magazynu do projektu.

dotnet add package Microsoft.Azure.Functions.Worker.Extensions.Storage.Queues --prerelease

Teraz możesz dodać powiązanie danych wyjściowych magazynu do projektu.

Dodawanie definicji powiązania wyjściowego do funkcji

Mimo że funkcja może mieć tylko jeden wyzwalacz, może mieć wiele powiązań wejściowych i wyjściowych, co umożliwia łączenie się z innymi usługami i zasobami platformy Azure bez konieczności pisania niestandardowego kodu integracji.

Te powiązania są deklarowane w pliku function.json w folderze funkcji. W poprzednim przewodniku Szybki start plik function.json w folderze HttpExample zawiera dwa powiązania w bindings kolekcji:

W przypadku korzystania z modelu programowania języka Python w wersji 2 atrybuty powiązania są definiowane bezpośrednio w pliku function_app.py jako dekoratory. W poprzednim przewodniku Szybki start plik function_app.py zawiera już jedno powiązanie oparte na dekoratorze:

import azure.functions as func
import logging

app = func.FunctionApp()

@app.function_name(name="HttpTrigger1")
@app.route(route="hello", auth_level=func.AuthLevel.ANONYMOUS)

Dekorator route dodaje powiązanie HttpTrigger i HttpOutput do funkcji, co umożliwia wyzwalanie funkcji po osiągnięciu określonej trasy przez żądania HTTP.

Aby zapisać w kolejce usługi Azure Storage z tej funkcji, dodaj queue_output dekorator do kodu funkcji:

@app.queue_output(arg_name="msg", queue_name="outqueue", connection="AzureWebJobsStorage")

W dekoratorze arg_name identyfikuje parametr powiązania, do którego odwołuje się kod, queue_name jest nazwą kolejki, do którą zapisuje powiązanie, i connection jest nazwą ustawienia aplikacji zawierającego parametry połączenia dla konta magazynu. W przewodnikach Szybki start użyjesz tego samego konta magazynu co aplikacja funkcji, która znajduje się w ustawieniu AzureWebJobsStorage (z pliku local.settings.json ). queue_name Gdy element nie istnieje, powiązanie tworzy je przy pierwszym użyciu.

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

Drugie powiązanie w kolekcji nosi nazwę res. To http powiązanie jest powiązaniem wyjściowym (out), które jest używane do zapisywania odpowiedzi HTTP.

Aby zapisać w kolejce usługi Azure Storage z tej funkcji, dodaj out powiązanie typu queue o nazwie msg, jak pokazano w poniższym kodzie:

    {
      "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"
    }
  ]
}

Drugie powiązanie w kolekcji nosi nazwę res. To http powiązanie jest powiązaniem wyjściowym (out), które jest używane do zapisywania odpowiedzi HTTP.

Aby zapisać w kolejce usługi Azure Storage z tej funkcji, dodaj out powiązanie typu queue o nazwie msg, jak pokazano w poniższym kodzie:

    {
      "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"
    }
  ]
}

W tym przypadku msg funkcja jest podawana jako argument wyjściowy. queue W przypadku typu należy również określić nazwę kolejki w queueName pliku i podać nazwę połączenia usługi Azure Storage (z pliku local.settings.json) w pliku connection.

W projekcie języka C# powiązania są definiowane jako atrybuty powiązania w metodzie funkcji. Określone definicje zależą od tego, czy aplikacja działa w procesie (biblioteka klas języka C#), czy w izolowanym procesie roboczym.

Otwórz plik projektu HttpExample.cs i dodaj następującą MultiResponse klasę:

public class MultiResponse
{
    [QueueOutput("outqueue",Connection = "AzureWebJobsStorage")]
    public string[] Messages { get; set; }
    public HttpResponseData HttpResponse { get; set; }
}

Klasa MultiResponse umożliwia zapisywanie w kolejce magazynu o nazwie outqueue i komunikat o powodzeniu HTTP. Do kolejki można wysłać wiele komunikatów, ponieważ QueueOutput atrybut jest stosowany do tablicy ciągów.

Właściwość Connection ustawia parametry połączenia dla konta magazynu. W takim przypadku można pominąć Connection , ponieważ używasz już domyślnego konta magazynu.

W projekcie Języka Java powiązania są definiowane jako adnotacje powiązań w metodzie funkcji. Plik function.json jest następnie automatycznie generowany na podstawie tych adnotacji.

Przejdź do lokalizacji kodu funkcji w obszarze src/main/java, otwórz plik projektu Function.java i dodaj następujący parametr do run definicji metody:

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

Parametr msg jest typem OutputBinding<T> , który reprezentuje kolekcję ciągów. Te ciągi są zapisywane jako komunikaty do powiązania wyjściowego po zakończeniu działania funkcji. W tym przypadku dane wyjściowe są kolejką magazynu o nazwie outqueue. Parametry połączenia dla konta magazynu jest ustawiana przez metodę connection . Przekazujesz ustawienie aplikacji, które zawiera parametry połączenia konta magazynu, zamiast przekazywać sam parametry połączenia.

Definicja run metody musi teraz wyglądać podobnie do poniższego przykładu:

@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) {
    ...
}

Aby uzyskać więcej informacji na temat szczegółów powiązań, zobacz Pojęcia dotyczące wyzwalaczy i powiązań usługi Azure Functions oraz konfiguracja danych wyjściowych kolejki.

Dodawanie kodu w celu użycia powiązania wyjściowego

Po zdefiniowaniu powiązania kolejki można teraz zaktualizować funkcję w celu odbierania parametru wyjściowego msg i zapisywania komunikatów w kolejce.

Zaktualizuj httpExample\function_app.py , aby był zgodny z następującym kodem, dodaj msg parametr do definicji funkcji i msg.set(name) w instrukcji if name: :

import azure.functions as func
import logging

app = func.FunctionApp(http_auth_level=func.AuthLevel.ANONYMOUS)

@app.route(route="HttpExample")
@app.queue_output(arg_name="msg", queue_name="outqueue", connection="AzureWebJobsStorage")
def HttpExample(req: func.HttpRequest, msg: func.Out [func.QueueMessage]) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')

    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}. This HTTP triggered function executed successfully.")
    else:
        return func.HttpResponse(
             "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response.",
             status_code=200
        )

Parametr msg jest wystąpieniem klasy azure.functions.Out class. Metoda set zapisuje komunikat ciągu w kolejce. W takim przypadku jest to przekazana name do funkcji w ciągu zapytania adresu URL.

Dodaj kod, który używa obiektu powiązania wyjściowego msg do context.bindings utworzenia komunikatu kolejki. Dodaj ten kod przed instrukcją context.res .

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

W tym momencie funkcja może wyglądać następująco:

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"
        };
    }
};

Dodaj kod, który używa obiektu powiązania wyjściowego msg do context.bindings utworzenia komunikatu kolejki. Dodaj ten kod przed instrukcją context.res .

context.bindings.msg = name;

W tym momencie funkcja musi wyglądać następująco:

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;

Dodaj kod, który używa Push-OutputBinding polecenia cmdlet do pisania tekstu w kolejce przy użyciu powiązania wyjściowego msg . Dodaj ten kod przed ustawieniem stanu OK w instrukcji if .

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

W tym momencie funkcja musi wyglądać następująco:

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
})

Zastąp istniejącą HttpExample klasę następującym kodem:

    [Function("HttpExample")]
    public static MultiResponse Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req,
        FunctionContext executionContext)
    {
        var logger = executionContext.GetLogger("HttpExample");
        logger.LogInformation("C# HTTP trigger function processed a request.");

        var message = "Welcome to Azure Functions!";

        var response = req.CreateResponse(HttpStatusCode.OK);
        response.Headers.Add("Content-Type", "text/plain; charset=utf-8");
        response.WriteString(message);

        // Return a response to both HTTP trigger and storage output binding.
        return new MultiResponse()
        {
            // Write a single message.
            Messages = new string[] { message },
            HttpResponse = response
        };
    }
}

Teraz możesz użyć nowego msg parametru do zapisania w powiązaniu wyjściowym z kodu funkcji. Dodaj następujący wiersz kodu przed odpowiedzią na powodzenie, aby dodać wartość name do powiązania wyjściowego msg .

msg.setValue(name);

W przypadku korzystania z powiązania wyjściowego nie trzeba używać kodu zestawu SDK usługi Azure Storage do uwierzytelniania, pobierania odwołania do kolejki ani zapisywania danych. Powiązanie danych wyjściowych środowiska uruchomieniowego i kolejki usługi Functions wykonuje te zadania.

Metoda run musi teraz wyglądać podobnie do poniższego przykładu:

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();
    }
}

Aktualizowanie testów

Ponieważ archetyp tworzy również zestaw testów, należy zaktualizować te testy, aby obsłużyć nowy msg parametr w podpisie run metody.

Przejdź do lokalizacji kodu testowego w obszarze src/test/java, otwórz plik projektu Function.java i zastąp wiersz kodu w obszarze //Invoke następującym kodem:

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

Zwróć uwagę, że nie musisz pisać żadnego kodu na potrzeby uwierzytelniania, uzyskiwania odwołania do kolejki ani zapisywania danych. Wszystkie te zadania integracji są wygodnie obsługiwane w środowisku uruchomieniowym usługi Azure Functions i powiązaniu danych wyjściowych kolejki.

Lokalne uruchamianie funkcji

  1. Uruchom funkcję, uruchamiając lokalny host środowiska uruchomieniowego usługi Azure Functions z folderu LocalFunctionProj .

    func start
    

    Na końcu danych wyjściowych muszą pojawić się następujące wiersze:

    Zrzut ekranu przedstawiający dane wyjściowe okna terminalu podczas lokalnego uruchamiania funkcji.

    Uwaga

    Jeśli funkcja HttpExample nie jest wyświetlana jak pokazano powyżej, prawdopodobnie uruchomiono hosta spoza folderu głównego projektu. W takim przypadku użyj klawiszy Ctrl+C, aby zatrzymać hosta, przejść do folderu głównego projektu i ponownie uruchomić poprzednie polecenie.

  2. Skopiuj adres URL funkcji HTTP z tych danych wyjściowych do przeglądarki i dołącz ciąg ?name=<YOUR_NAME>zapytania , tworząc pełny adres URL, taki jak http://localhost:7071/api/HttpExample?name=Functions. W przeglądarce powinien zostać wyświetlony komunikat odpowiedzi, który zwraca wartość ciągu zapytania. Terminal, w którym rozpoczęto projekt, pokazuje również dane wyjściowe dziennika podczas wysyłania żądań.

  3. Po zakończeniu naciśnij klawisze Ctrl + C i wpisz y , aby zatrzymać hosta funkcji.

Napiwek

Podczas uruchamiania host pobiera i instaluje rozszerzenie powiązania magazynu i inne rozszerzenia powiązań firmy Microsoft. Ta instalacja jest wykonywana, ponieważ rozszerzenia powiązań są domyślnie włączone w pliku host.json o następujących właściwościach:

{
    "version": "2.0",
    "extensionBundle": {
        "id": "Microsoft.Azure.Functions.ExtensionBundle",
        "version": "[1.*, 2.0.0)"
    }
}

Jeśli wystąpią jakiekolwiek błędy związane z rozszerzeniami powiązań, sprawdź, czy powyższe właściwości znajdują się w host.json.

Wyświetlanie komunikatu w kolejce usługi Azure Storage

Kolejkę można wyświetlić w witrynie Azure Portal lub w Eksplorator usługi Microsoft Azure Storage. Kolejkę można również wyświetlić w interfejsie wiersza polecenia platformy Azure zgodnie z opisem w następujących krokach:

  1. Otwórz plik local.setting.json projektu funkcji i skopiuj wartość parametry połączenia. W terminalu lub oknie polecenia uruchom następujące polecenie, aby utworzyć zmienną środowiskową o nazwie AZURE_STORAGE_CONNECTION_STRINGi wkleić określone parametry połączenia zamiast <MY_CONNECTION_STRING>. (Ta zmienna środowiskowa oznacza, że nie trzeba podawać parametry połączenia do każdego kolejnego polecenia przy użyciu argumentu--connection-string).

    export AZURE_STORAGE_CONNECTION_STRING="<MY_CONNECTION_STRING>"
    
  2. (Opcjonalnie) Użyj polecenia , az storage queue list aby wyświetlić kolejki usługi Storage na koncie. Dane wyjściowe tego polecenia muszą zawierać kolejkę o nazwie outqueue, która została utworzona, gdy funkcja napisała swój pierwszy komunikat do tej kolejki.

    az storage queue list --output tsv
    
  3. az storage message get Użyj polecenia , aby odczytać komunikat z tej kolejki, który powinien być wartością podaną podczas testowania funkcji wcześniej. Polecenie odczytuje i usuwa pierwszy komunikat z kolejki.

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

    Ponieważ treść komunikatu jest przechowywana w formacie base64, przed wyświetleniem komunikatu musi zostać zdekodowany. Po wykonaniu az storage message getpolecenia komunikat zostanie usunięty z kolejki. Jeśli w programie outqueuebył tylko jeden komunikat , nie po raz drugi uruchomisz tego polecenia i zamiast tego wystąpi błąd.

Ponowne wdrażanie projektu na platformie Azure

Po zweryfikowaniu lokalnie, że funkcja napisała komunikat do kolejki usługi Azure Storage, możesz ponownie wdrożyć projekt w celu zaktualizowania punktu końcowego uruchomionego na platformie Azure.

W folderze LocalFunctionsProj użyj func azure functionapp publish polecenia , aby ponownie wdrożyć projekt, zastępując<APP_NAME> ciąg nazwą aplikacji.

func azure functionapp publish <APP_NAME>

W folderze projektu lokalnego użyj następującego polecenia Narzędzia Maven, aby ponownie opublikować projekt:

mvn azure-functions:deploy

Weryfikowanie na platformie Azure

  1. Podobnie jak w poprzednim przewodniku Szybki start, użyj przeglądarki lub narzędzia CURL do przetestowania ponownie wdrożonej funkcji.

    Skopiuj pełny adres URL wywołania widoczny w danych wyjściowych polecenia publikowania na pasku adresu przeglądarki, dołączając parametr &name=Functionszapytania . Przeglądarka powinna wyświetlać te same dane wyjściowe co podczas lokalnego uruchamiania funkcji.

  2. Ponownie sprawdź kolejkę magazynu, zgodnie z opisem w poprzedniej sekcji, aby sprawdzić, czy zawiera on nowy komunikat zapisany w kolejce.

Czyszczenie zasobów

Po zakończeniu użyj następującego polecenia, aby usunąć grupę zasobów i wszystkie zawarte w niej zasoby, aby uniknąć ponoszenia dalszych kosztów.

az group delete --name AzureFunctionsQuickstart-rg

Następne kroki

Zaktualizowano funkcję wyzwalaną przez protokół HTTP, aby zapisywać dane w kolejce usługi Storage. Teraz możesz dowiedzieć się więcej na temat tworzenia funkcji z poziomu wiersza polecenia przy użyciu narzędzi Core Tools i interfejsu wiersza polecenia platformy Azure: