|
| 1 | +--- |
| 2 | +title: Tutorial - Trigger Azure Container Instances by an Azure function |
| 3 | +description: Create an HTTP-triggered, serverless PowerShell function to automate creation of Azure container instances |
| 4 | +services: container-instances |
| 5 | +author: dlepow |
| 6 | +manager: gwallace |
| 7 | + |
| 8 | +ms.service: container-instances |
| 9 | +ms.topic: tutorial |
| 10 | +ms.date: 09/20/2019 |
| 11 | +ms.author: danlep |
| 12 | +ms.custom: |
| 13 | +--- |
| 14 | + |
| 15 | +# Tutorial: Use an HTTP-triggered Azure function to create a container group |
| 16 | + |
| 17 | +[Azure Functions](../azure-functions/functions-overview.md) is a serverless compute service that can run scripts or code in response to a variety of events, such as an HTTP request, a timer, or a message in an Azure Storage queue. |
| 18 | + |
| 19 | +In this tutorial, you create an Azure function that takes an HTTP request and triggers deployment of a [container group](container-instances-container-groups.md). This example shows the basics of using Azure Functions to automatically create resources in Azure Container Instances. Modify or extend the example for more complex scenarios or other event triggers. |
| 20 | + |
| 21 | +You learn how to: |
| 22 | + |
| 23 | +> [!div class="checklist"] |
| 24 | +> * Use Visual Studio Code with the [Azure Functions extension](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-azurefunctions) to create a basic HTTP-triggered PowerShell function. |
| 25 | +> * Enable an identity in the function app and give it permissions to create Azure resources. |
| 26 | +> * Modify and republish the PowerShell function to automate deployment of a single-container container group. |
| 27 | +> * Verify the HTTP-triggered deployment of the container. |
| 28 | +
|
| 29 | +> [!IMPORTANT] |
| 30 | +> PowerShell for Azure Functions is currently in preview. Previews are made available to you on the condition that you agree to the [supplemental terms of use][terms-of-use]. Some aspects of this feature may change prior to general availability (GA). |
| 31 | +
|
| 32 | +## Prerequisites |
| 33 | + |
| 34 | +See [Create your first PowerShell function in Azure](../azure-functions/functions-create-first-function-powershell.md#prerequisites) for prerequisites to install and use Visual Studio Code with the Azure Functions on your OS. |
| 35 | + |
| 36 | +Some steps in this article use the Azure CLI. You can use the Azure Cloud Shell or a local installation of the Azure CLI to complete these steps. If you need to install or upgrade, see [Install Azure CLI][azure-cli-install]. |
| 37 | + |
| 38 | +## Create a basic PowerShell function |
| 39 | + |
| 40 | +Follow steps in [Create your first PowerShell function in Azure](../azure-functions/functions-create-first-function-powershell.md) to create a PowerShell function using the HTTP Trigger template. Use the default Azure function name **HttpTrigger**. As shown in the quickstart, test the function locally, and publish the project to a function app in Azure. This example is a basic HTTP-triggered function that returns a text string. In later steps in this article, you modify the function to create a container group. |
| 41 | + |
| 42 | +This article assumes you publish the project using the name *myfunctionapp*, in an Azure resource group automatically named according to the function app name (also *myfunctionapp*). Substitute your unique function app name and resource group name in later steps. |
| 43 | + |
| 44 | +## Enable an Azure-managed identity in the function app |
| 45 | + |
| 46 | +Now enable a system-assigned [managed identity](../app-service/overview-managed-identity.md?toc=/azure/azure-functions/toc.json#adding-a-system-assigned-identity) in your function app. The PowerShell host running the app can automatically authenticate using this identity, enabling functions to take actions on Azure services to which the identity has been granted access. In this tutorial, you grant the managed identity permissions to create resources in the function app's resource group. |
| 47 | + |
| 48 | +First use the [az group show][az-group-show] command to get the ID of the function app's resource group and store it in an environment variable. This example assumes you run the command in a Bash shell. |
| 49 | + |
| 50 | +```azurecli |
| 51 | +rgID=$(az group show --name myfunctionapp --query id --output tsv) |
| 52 | +``` |
| 53 | + |
| 54 | +Run [az functionapp identity app assign][az-functionapp-identity-app-assign] to assign a local identity to the function app and assign a contributor role to the resource group. This role allows the identity to create additional resources such as container groups in the resource group. |
| 55 | + |
| 56 | +```azurecli |
| 57 | +az functionapp identity assign \ |
| 58 | + --name myfunctionapp \ |
| 59 | + --resource-group myfunctionapp \ |
| 60 | + --role contributor --scope $rgID |
| 61 | +``` |
| 62 | + |
| 63 | +## Modify HttpTrigger function |
| 64 | + |
| 65 | +Modify the PowerShell code for the **HttpTrigger** function to create a container group. In file `run.ps1` for the function, find the following code block. This code displays a name value, if one is passed as a query string in the function URL: |
| 66 | + |
| 67 | +```powershell |
| 68 | +[...] |
| 69 | +if ($name) { |
| 70 | + $status = [HttpStatusCode]::OK |
| 71 | + $body = "Hello $name" |
| 72 | +} |
| 73 | +[...] |
| 74 | +``` |
| 75 | + |
| 76 | +Replace this code with the following example block. Here, if a name value is passed in the query string, it is used to name and create a container group using the [New-AzContainerGroup][new-azcontainergroup] cmdlet. Make sure to replace the resource group name *myfunctionapp* with the name of the resource group for your function app: |
| 77 | + |
| 78 | +```powershell |
| 79 | +[...] |
| 80 | +if ($name) { |
| 81 | + $status = [HttpStatusCode]::OK |
| 82 | + New-AzContainerGroup -ResourceGroupName myfunctionapp -Name $name ` |
| 83 | + -Image alpine -OsType Linux ` |
| 84 | + -Command "echo 'Hello from an Azure container instance triggered by an Azure function'" ` |
| 85 | + -RestartPolicy Never |
| 86 | + $body = "Started container group $name" |
| 87 | +} |
| 88 | +[...] |
| 89 | +``` |
| 90 | + |
| 91 | +This example creates a container group consisting of a single container instance running the `alpine` image. The container runs a single `echo` command and then terminates. In a real-world example, you might trigger creation of one or more container groups for running a batch job. |
| 92 | + |
| 93 | +## Test function app locally |
| 94 | + |
| 95 | +Ensure that the function runs properly locally before republishing the function app project to Azure. As shown in the [PowerShell quickstart](../azure-functions/functions-create-first-function-powershell.md), insert a local breakpoint in the PowerShell script and a `Wait-Debugger` call above it. For debugging guidance, see [Debug PowerShell Azure Functions locally](../azure-functions/functions-debug-powershell-local.md). |
| 96 | + |
| 97 | + |
| 98 | +## Republish Azure function app |
| 99 | + |
| 100 | +After you've verified that the function runs correctly on your local computer, it's time to republish the project to the existing function app in Azure. |
| 101 | + |
| 102 | +> [!NOTE] |
| 103 | +> Remember to remove any calls to `Wait-Debugger` before you publish your functions to Azure. |
| 104 | +
|
| 105 | +1. In Visual Studio Code, open the Command Palette. Search for and select `Azure Functions: Deploy to function app...`. |
| 106 | +1. Select the current working folder to zip and deploy. |
| 107 | +1. Select the subscription and then the name of the existing function app (*myfunctionapp*). Confirm that you want to overwrite the previous deployment. |
| 108 | + |
| 109 | +A notification is displayed after your function app is created and the deployment package is applied. Select **View Output** in this notification to view the creation and deployment results, including the Azure resources that you updated. |
| 110 | + |
| 111 | +## Run the function in Azure |
| 112 | + |
| 113 | +After the deployment completes successfully, get the function URL. For example, use the **Azure: Functions** area in Visual Studio code to copy the **HttpTrigger** function URL, or get the function URL in the [Azure portal](../azure-functions/functions-create-first-azure-function.md#test-the-function). |
| 114 | + |
| 115 | +The function URL includes a unique code and is of the form: |
| 116 | + |
| 117 | +``` |
| 118 | +https://myfunctionapp.azurewebsites.net/api/HttpTrigger?code=bmF/GljyfFWISqO0GngDPCtCQF4meRcBiHEoaQGeRv/Srx6dRcrk2M== |
| 119 | +``` |
| 120 | + |
| 121 | +### Run function without passing a name |
| 122 | + |
| 123 | +As a first test, run the `curl` command and pass the function URL without appending a `name` query string. Make sure to include your function's unique code. |
| 124 | + |
| 125 | +```bash |
| 126 | +curl --verbose "https://myfunctionapp.azurewebsites.net/api/HttpTrigger?code=bmF/GljyfFWISqO0GngDPCtCQF4meRcBiHEoaQGeRv/Srx6dRcrk2M==" |
| 127 | +``` |
| 128 | + |
| 129 | +The function returns status code 400 and the text `Please pass a name on the query string or in the request body`: |
| 130 | + |
| 131 | +``` |
| 132 | +[...] |
| 133 | +> GET /api/HttpTrigger?code=bmF/GljyfFWISqO0GngDPCtCQF4meRcBiHEoaQGeRv/Srx6dRcrk2M== HTTP/2 |
| 134 | +> Host: myfunctionapp.azurewebsites.net |
| 135 | +> User-Agent: curl/7.54.0 |
| 136 | +> Accept: */* |
| 137 | +> |
| 138 | +* Connection state changed (MAX_CONCURRENT_STREAMS updated)! |
| 139 | +< HTTP/2 400 |
| 140 | +< content-length: 62 |
| 141 | +< content-type: text/plain; charset=utf-8 |
| 142 | +< date: Mon, 05 Aug 2019 22:08:15 GMT |
| 143 | +< |
| 144 | +* Connection #0 to host myfunctionapp.azurewebsites.net left intact |
| 145 | +Please pass a name on the query string or in the request body. |
| 146 | +``` |
| 147 | + |
| 148 | +### Run function and pass the name of a container group |
| 149 | + |
| 150 | +Now run the `curl` command by appending the name of a container group (*mycontainergroup*) as a query string `&name=mycontainergroup`: |
| 151 | + |
| 152 | +```bash |
| 153 | +curl --verbose "https://myfunctionapp.azurewebsites.net/api/HttpTrigger?code=bmF/GljyfFWISqO0GngDPCtCQF4meRcBiHEoaQGeRv/Srx6dRcrk2M==&name=mycontainergroup" |
| 154 | +``` |
| 155 | + |
| 156 | +The function returns status code 200 and triggers the creation of the container group: |
| 157 | + |
| 158 | +``` |
| 159 | +[...] |
| 160 | +> GET /api/HttpTrigger?ode=bmF/GljyfFWISqO0GngDPCtCQF4meRcBiHEoaQGeRv/Srx6dRcrk2M==&name=mycontainergroup HTTP/2 |
| 161 | +> Host: myfunctionapp.azurewebsites.net |
| 162 | +> User-Agent: curl/7.54.0 |
| 163 | +> Accept: */* |
| 164 | +> |
| 165 | +* Connection state changed (MAX_CONCURRENT_STREAMS updated)! |
| 166 | +< HTTP/2 200 |
| 167 | +< content-length: 28 |
| 168 | +< content-type: text/plain; charset=utf-8 |
| 169 | +< date: Mon, 05 Aug 2019 22:15:30 GMT |
| 170 | +< |
| 171 | +* Connection #0 to host myfunctionapp.azurewebsites.net left intact |
| 172 | +Started container group mycontainergroup |
| 173 | +``` |
| 174 | + |
| 175 | +Verify that the container ran with the [az container logs][az-container-logs] command: |
| 176 | + |
| 177 | +```azurecli |
| 178 | +az container logs --resource-group myfunctionapp --name mycontainergroup |
| 179 | +``` |
| 180 | + |
| 181 | +Sample output: |
| 182 | + |
| 183 | +```console |
| 184 | +Hello from an Azure container instance triggered by an Azure function |
| 185 | +``` |
| 186 | + |
| 187 | +## Clean up resources |
| 188 | + |
| 189 | +If you no longer need any of the resources you created in this tutorial, you can execute the [az group delete][az-group-delete] command to remove the resource group and all resources it contains. This command deletes the container registry you created, as well as the running container, and all related resources. |
| 190 | + |
| 191 | +```azurecli-interactive |
| 192 | +az group delete --name myfunctionapp |
| 193 | +``` |
| 194 | + |
| 195 | +## Next steps |
| 196 | + |
| 197 | +In this tutorial, you created an Azure function that takes an HTTP request and triggers deployment of a container group. You learned how to: |
| 198 | + |
| 199 | +> [!div class="checklist"] |
| 200 | +> * Use Visual Studio Code with the Azure Functions extension to create a basic HTTP-triggered PowerShell function. |
| 201 | +> * Enable an identity in the function app and give it permissions to create Azure resources. |
| 202 | +> * Modify the PowerShell function code to automate deployment of a single-container container group. |
| 203 | +> * Verify the HTTP-triggered deployment of the container. |
| 204 | +
|
| 205 | +For a detailed example to launch and monitor a containerized job, see the blog post [Event-Driven Serverless Containers with PowerShell Azure Functions and Azure Container Instances](https://dev.to/azure/event-driven-serverless-containers-with-powershell-azure-functions-and-azure-container-instances-e9b) and accompanying [code sample](https://github.com/anthonychu/functions-powershell-run-aci). |
| 206 | + |
| 207 | +See the [Azure Functions documentation](/azure/azure-functions/) for detailed guidance on creating Azure functions and publishing a functions project. |
| 208 | + |
| 209 | +<!-- IMAGES --> |
| 210 | + |
| 211 | + |
| 212 | +<!-- LINKS - external --> |
| 213 | +[terms-of-use]: https://azure.microsoft.com/support/legal/preview-supplemental-terms/ |
| 214 | + |
| 215 | +<!-- LINKS - internal --> |
| 216 | + |
| 217 | +[azure-cli-install]: /cli/azure/install-azure-cli |
| 218 | +[az-group-show]: /cli/azure/group#az-group-show |
| 219 | +[az-group-delete]: /cli/azure/group#az-group-delete |
| 220 | +[az-functionapp-identity-app-assign]: /cli/azure/functionapp/identity#az-functionapp-identity-assign |
| 221 | +[new-azcontainergroup]: /powershell/module/az.containerinstance/new-azcontainergroup |
| 222 | +[az-container-logs]: /cli/azure/container#az-container-logs |
0 commit comments