|
| 1 | +--- |
| 2 | +title: Connect Azure Functions to Azure Storage using command line tools |
| 3 | +description: Learn how to connect Azure Functions to an Azure Storage queue by adding an output binding to your command line project. |
| 4 | +ms.date: 02/07/2020 |
| 5 | +ms.topic: quickstart |
| 6 | +zone_pivot_groups: programming-languages-set-functions |
| 7 | +--- |
| 8 | + |
| 9 | +# Connect Azure Functions to Azure Storage using command line tools |
| 10 | + |
| 11 | +In this article, you integrate an Azure Storage queue with the function and storage account you created in [the previous quickstart](functions-create-first-azure-function-azure-cli.md). You achieve this integration by using an *output binding* that writes data from an HTTP request to a message in the queue. Completing this article incurs no additional costs beyond the few USD cents of the previous quickstart. To learn more about bindings, see [Azure Functions triggers and bindings concepts](functions-triggers-bindings.md). |
| 12 | + |
| 13 | +## Configure your local environment |
| 14 | + |
| 15 | +Before you begin, you must complete the article, [Quickstart: Create an Azure Functions project from the command line](functions-create-first-azure-function-azure-cli.md). If you already cleaned up resources at the end of that article, go through the steps again to recreate the function app and related resources in Azure. |
| 16 | + |
| 17 | +## Retrieve the Azure Storage connection string |
| 18 | + |
| 19 | +When you created a function app in Azure in the previous quickstart, you also created a Storage account. The connection string for this account is stored securely in app settings in Azure. 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. |
| 20 | + |
| 21 | +1. From the root of the project, run the following command, replacing `<APP_NAME>` with the name of your function app from the previous quickstart. This command will overwrite any existing values in the file. |
| 22 | + |
| 23 | + ``` |
| 24 | + func azure functionapp fetch-app-settings <APP_NAME> |
| 25 | + ``` |
| 26 | + |
| 27 | +1. Open *local.settings.json* and locate the value named `AzureWebJobsStorage`, which is the Storage account connection string. You use the name `AzureWebJobsStorage` and the connection string in other sections of this article. |
| 28 | +
|
| 29 | +> [!IMPORTANT] |
| 30 | +> Because *local.settings.json* contains secrets downloaded from Azure, always exclude this file from source control. The *.gitignore* file created with a local functions project excludes the file by default. |
| 31 | +
|
| 32 | +[!INCLUDE [functions-register-storage-binding-extension-csharp](../../includes/functions-register-storage-binding-extension-csharp.md)] |
| 33 | +
|
| 34 | +## Add an output binding definition to the function |
| 35 | +
|
| 36 | +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. |
| 37 | +
|
| 38 | +::: zone pivot="programming-language-python,programming-language-javascript,programming-language-powershell,programming-language-typescript" |
| 39 | +You declare these bindings in the *function.json* file in your function folder. From the previous quickstart, your *function.json* file in the *HttpExample* folder contains two bindings in the `bindings` collection: |
| 40 | +::: zone-end |
| 41 | +
|
| 42 | +::: zone pivot="programming-language-javascript,programming-language-typescript" |
| 43 | +:::code language="json" source="~/functions-quickstart-templates/Functions.Templates/Templates/HttpTrigger-JavaScript/function.json" range="2-18"::: |
| 44 | +::: zone-end |
| 45 | +
|
| 46 | +::: zone pivot="programming-language-python" |
| 47 | +:::code language="json" source="~/functions-quickstart-templates/Functions.Templates/Templates/HttpTrigger-Python/function.json" range="2-18"::: |
| 48 | +::: zone-end |
| 49 | +
|
| 50 | +::: zone pivot="programming-language-powershell" |
| 51 | +:::code language="json" source="~/functions-quickstart-templates/Functions.Templates/Templates/HttpTrigger-PowerShell/function.json" range="2-18"::: |
| 52 | +::: zone-end |
| 53 | +
|
| 54 | +::: zone pivot="programming-language-python,programming-language-javascript, programming-language-powershell, programming-language-typescript" |
| 55 | +Each binding has at least a type, a direction, and a name. In the example above, the first binding is of type `httpTrigger` with the direction `in`. For the `in` direction, `name` specifies the name of an input parameter that's sent to the function when invoked by the trigger. |
| 56 | +::: zone-end |
| 57 | +
|
| 58 | +::: zone pivot="programming-language-javascript,programming-language-typescript" |
| 59 | +The second binding in the collection is named `res`. This `http` binding is an output binding (`out`) that is used to write the HTTP response. |
| 60 | +
|
| 61 | +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: |
| 62 | +
|
| 63 | +:::code language="json" source="~/functions-docs-javascript/functions-add-output-binding-storage-queue-cli/HttpExample/function.json" range="3-26"::: |
| 64 | +::: zone-end |
| 65 | +
|
| 66 | +::: zone pivot="programming-language-python" |
| 67 | +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. |
| 68 | +
|
| 69 | +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: |
| 70 | +
|
| 71 | +:::code language="json" source="~/functions-docs-python/functions-add-output-binding-storage-queue-cli/HttpExample/function.json" range="3-26"::: |
| 72 | +::: zone-end |
| 73 | +
|
| 74 | +::: zone pivot="programming-language-powershell" |
| 75 | +The second binding in the collection is named `res`. This `http` binding is an output binding (`out`) that is used to write the HTTP response. |
| 76 | +
|
| 77 | +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: |
| 78 | +
|
| 79 | +:::code language="json" source="~/functions-docs-powershell/functions-add-output-binding-storage-queue-cli/HttpExample/function.json" range="3-26"::: |
| 80 | +::: zone-end |
| 81 | +
|
| 82 | +::: zone pivot="programming-language-python,programming-language-javascript,programming-language-powershell,programming-language-typescript" |
| 83 | +In this case, `msg` is given to the function as an output argument. 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`. |
| 84 | +::: zone-end |
| 85 | +
|
| 86 | +::: zone pivot="programming-language-csharp" |
| 87 | +[!INCLUDE [functions-add-storage-binding-csharp-library](../../includes/functions-add-storage-binding-csharp-library.md)] |
| 88 | +::: zone-end |
| 89 | +
|
| 90 | +For more information on the details of bindings, see [Azure Functions triggers and bindings concepts](functions-triggers-bindings.md) and [queue output configuration](functions-bindings-storage-queue-output.md#configuration). |
| 91 | +
|
| 92 | +## Add code to use the output binding |
| 93 | +
|
| 94 | +With the queue binding specified in *function.json*, you can now update your function to receive the `msg` output parameter and write messages to the queue. |
| 95 | +
|
| 96 | +::: zone pivot="programming-language-python" |
| 97 | +[!INCLUDE [functions-add-output-binding-python](../../includes/functions-add-output-binding-python.md)] |
| 98 | +::: zone-end |
| 99 | +
|
| 100 | +::: zone pivot="programming-language-javascript" |
| 101 | +[!INCLUDE [functions-add-output-binding-js](../../includes/functions-add-output-binding-js.md)] |
| 102 | +::: zone-end |
| 103 | +
|
| 104 | +::: zone pivot="programming-language-typescript" |
| 105 | +[!INCLUDE [functions-add-output-binding-ts](../../includes/functions-add-output-binding-ts.md)] |
| 106 | +::: zone-end |
| 107 | +
|
| 108 | +::: zone pivot="programming-language-powershell" |
| 109 | +[!INCLUDE [functions-add-output-binding-powershell](../../includes/functions-add-output-binding-powershell.md)] |
| 110 | +::: zone-end |
| 111 | +
|
| 112 | +::: zone pivot="programming-language-csharp" |
| 113 | +[!INCLUDE [functions-add-storage-binding-csharp-library-code](../../includes/functions-add-storage-binding-csharp-library-code.md)] |
| 114 | +::: zone-end |
| 115 | +
|
| 116 | +Observe that you *don't* need to write any code for authentication, getting a queue reference, or writing data. All these integration tasks are conveniently handled in the Azure Functions runtime and queue output binding. |
| 117 | +
|
| 118 | +[!INCLUDE [functions-run-function-test-local-cli](../../includes/functions-run-function-test-local-cli.md)] |
| 119 | +
|
| 120 | +[!INCLUDE [functions-extension-bundles-info](../../includes/functions-extension-bundles-info.md)] |
| 121 | +
|
| 122 | +## View the message in the Azure Storage queue |
| 123 | +
|
| 124 | +You can view the queue in the [Azure portal](../storage/queues/storage-quickstart-queues-portal.md) or in the [Microsoft Azure Storage Explorer](https://storageexplorer.com/). You can also view the queue in the Azure CLI, as described in the following steps: |
| 125 | +
|
| 126 | +1. Open the function project's *local.setting.json* file and copy the connection string value. 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>`. (This environment variable means you don't need to supply the connection string to each subsequent command using the `--connection-string` argument.) |
| 127 | +
|
| 128 | + # [bash](#tab/bash) |
| 129 | + |
| 130 | + ```bash |
| 131 | + AZURE_STORAGE_CONNECTION_STRING="<MY_CONNECTION_STRING>" |
| 132 | + ``` |
| 133 | + |
| 134 | + # [PowerShell](#tab/powershell) |
| 135 | + |
| 136 | + ```powershell |
| 137 | + $env:AZURE_STORAGE_CONNECTION_STRING = "<MY_CONNECTION_STRING>" |
| 138 | + ``` |
| 139 | + |
| 140 | + # [Cmd](#tab/cmd) |
| 141 | + |
| 142 | + ```cmd |
| 143 | + set AZURE_STORAGE_CONNECTION_STRING="<MY_CONNECTION_STRING>" |
| 144 | + ``` |
| 145 | + |
| 146 | + --- |
| 147 | + |
| 148 | +1. (Optional) Use the [`az storage queue list`](/cli/azure/storage/queue#az-storage-queue-list) command to view the Storage queues in your account. The output from this command should include a queue named `outqueue`, which was created when the function wrote its first message to that queue. |
| 149 | + |
| 150 | + ```azure-cli |
| 151 | + az storage queue list --output tsv |
| 152 | + ``` |
| 153 | +
|
| 154 | +1. Use the [`az storage message get`](/cli/azure/storage/message#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. The command reads and removes the first message from the queue. |
| 155 | +
|
| 156 | + # [bash](#tab/bash) |
| 157 | + |
| 158 | + ```bash |
| 159 | + echo `echo $(az storage message get --queue-name outqueue -o tsv --query '[].{Message:content}') | base64 --decode` |
| 160 | + ``` |
| 161 | + |
| 162 | + # [PowerShell](#tab/powershell) |
| 163 | + |
| 164 | + ```powershell |
| 165 | + [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($(az storage message get --queue-name outqueue -o tsv --query '[].{Message:content}'))) |
| 166 | + ``` |
| 167 | + |
| 168 | + # [Cmd](#tab/cmd) |
| 169 | + |
| 170 | + ```cmd |
| 171 | + az storage message get --queue-name outqueue -o tsv --query [].{Message:content} > %TEMP%out.b64 && certutil -decode -f %TEMP%out.b64 %TEMP%out.txt > NUL && type %TEMP%out.txt && del %TEMP%out.b64 %TEMP%out.txt /q |
| 172 | + ``` |
| 173 | +
|
| 174 | + This script uses certutil to decode the base64-encoded message collection from a local temp file. If there's no output, try removing `> NUL` from the script to stop suppressing certutil output, in case there's an error. |
| 175 | + |
| 176 | + --- |
| 177 | + |
| 178 | + Because the message body is stored [base64 encoded](functions-bindings-storage-queue-trigger.md#encoding), the message must be decoded before it's displayed. After you execute `az storage message get`, the message is removed from the queue. 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. |
| 179 | +
|
| 180 | +## Redeploy the project to Azure |
| 181 | +
|
| 182 | +Now that you've verified locally that the function wrote a message to the Azure Storage queue, you can redeploy your project to update the endpoint running on Azure. |
| 183 | +
|
| 184 | +1. In the *LocalFunctionsProj* folder, use the [`func azure functionapp publish`](functions-run-local.md#project-file-deployment) command to redeploy the project, replacing`<APP_NAME>` with the name of your app. |
| 185 | +
|
| 186 | + ``` |
| 187 | + func azure functionapp publish <APP_NAME> |
| 188 | + ``` |
| 189 | + |
| 190 | +1. As in the previous quickstart, use a browser or CURL to test the redeployed function. |
| 191 | +
|
| 192 | + # [Browser](#tab/browser) |
| 193 | + |
| 194 | + Copy the complete **Invoke URL** shown in the output of the publish command into a browser address bar, appending the query parameter `&name=Functions`. The browser should display similar output as when you ran the function locally. |
| 195 | +
|
| 196 | +  |
| 197 | +
|
| 198 | + # [curl](#tab/curl) |
| 199 | + |
| 200 | + Run [`curl`](https://curl.haxx.se/) with the **Invoke URL**, appending the parameter `&name=Functions`. The output of the command should be the text, "Hello Functions." |
| 201 | + |
| 202 | +  |
| 203 | +
|
| 204 | + --- |
| 205 | +
|
| 206 | +1. Examine the Storage queue again, as described in the previous section, to verify that it contains the new message written to the queue. |
| 207 | +
|
| 208 | +## Clean up resources |
| 209 | +
|
| 210 | +After you've finished, use the following command to delete the resource group and all its contained resources to avoid incurring further costs. |
| 211 | +
|
| 212 | +```azurecli |
| 213 | +az group delete --name AzureFunctionsQuickstart-rg |
| 214 | +``` |
| 215 | + |
| 216 | +## Next steps |
| 217 | + |
| 218 | +You've updated your HTTP triggered function to write data to a Storage queue. Now you can learn more about developing Functions from the command line using Core Tools and Azure CLI: |
| 219 | + |
| 220 | ++ [Work with Azure Functions Core Tools](functions-run-local.md) |
| 221 | + |
| 222 | +::: zone pivot="programming-language-csharp" |
| 223 | ++ [Examples of complete Function projects in C#](/samples/browse/?products=azure-functions&languages=csharp). |
| 224 | + |
| 225 | ++ [Azure Functions C# developer reference](functions-dotnet-class-library.md) |
| 226 | +::: zone-end |
| 227 | +::: zone pivot="programming-language-javascript" |
| 228 | ++ [Examples of complete Function projects in JavaScript](/samples/browse/?products=azure-functions&languages=javascript). |
| 229 | + |
| 230 | ++ [Azure Functions JavaScript developer guide](functions-reference-node.md) |
| 231 | +::: zone-end |
| 232 | +::: zone pivot="programming-language-typescript" |
| 233 | ++ [Examples of complete Function projects in TypeScript](/samples/browse/?products=azure-functions&languages=typescript). |
| 234 | + |
| 235 | ++ [Azure Functions TypeScript developer guide](functions-reference-node.md#typescript) |
| 236 | +::: zone-end |
| 237 | +::: zone pivot="programming-language-python" |
| 238 | ++ [Examples of complete Function projects in Python](/samples/browse/?products=azure-functions&languages=python). |
| 239 | + |
| 240 | ++ [Azure Functions Python developer guide](functions-reference-python.md) |
| 241 | +::: zone-end |
| 242 | +::: zone pivot="programming-language-powershell" |
| 243 | ++ [Examples of complete Function projects in PowerShell](/samples/browse/?products=azure-functions&languages=azurepowershell). |
| 244 | + |
| 245 | ++ [Azure Functions PowerShell developer guide](functions-reference-powershell.md) |
| 246 | +::: zone-end |
| 247 | ++ [Azure Functions triggers and bindings](functions-triggers-bindings.md) |
| 248 | + |
| 249 | ++ [Functions pricing page](https://azure.microsoft.com/pricing/details/functions/) |
| 250 | + |
| 251 | ++ [Estimating Consumption plan costs](functions-consumption-costs.md) |
0 commit comments