2. Create local Azure Function app in Visual Studio Code

In this article of the series, you create an Azure Function app in Visual Studio Code to manage Azure resource groups.

Create function app

Use Visual Studio Code to create a local Function app.

  1. In a bash terminal, create and change into a new directory:

    mkdir typescript-function-resource-group-api && cd typescript-function-resource-group-api
    
  2. In a bash terminal, open Visual Studio Code:

    code .
    
  3. Open the Visual Studio Code command palette: Ctrl + Shift + p.

  4. Enter Azure Functions: create new project. Use the following table to finish the prompts:

    Prompt Value
    Create new project Accept the default name, typescript-function-resource-group-api.
    Select a language Select TypeScript.
    Select a template for your project's first function Select HTTP trigger.
    Create new HTTP trigger Enter the API name of resource-groups.
    Authorization level Select anonymous. If you continue with this project after this article series, change the authorization level to the function. Learn more about Function-level authorization.

    The project boilerplate is created.

  5. In a Visual Studio Code integrated bash terminal, opened with Ctrl + Shift + `, install the project dependencies:

    npm install
    

Add service principal settings to local.settings.json file

  1. Open the local.settings.json file in the project root directory and edit your VALUES section with the four following environment variables.

    {
      "IsEncrypted": false,
      "Values": {
        "AzureWebJobsStorage": "",
        "FUNCTIONS_WORKER_RUNTIME": "node",
        "AZURE_CLIENT_ID": "REPLACE-WITH-SERVICE-PRINCIPAL-APPID",
        "AZURE_CLIENT_SECRET": "REPLACE-WITH-SERVICE-PRINCIPAL-PASSWORD",
        "AZURE_SUBSCRIPTION_ID":"REPLACE-WITH-SUBSCRIPTION-ID",
        "AZURE_TENANT_ID":"REPLACE-WITH-SERVICE-PRINCIPAL-TENANT"
      }
    }
    
  2. Refer to your temporary copy of settings from the previous article to edit the required environment variables. These environment variables are REQUIRED for the context to use DefaultAzureCredential.

    • AZURE_TENANT_ID: tenant from the service principal output above.
    • AZURE_CLIENT_ID: appId from the service principal output above.
    • AZURE_CLIENT_SECRET: password from the service principal output above.
  3. You also need to set the subscription ID. It is required to use the Azure SDK for resource management.

    • AZURE_SUBSCRIPTION: Your default subscription containing your resource groups.

This local.settings.json file is ignored by your local git on purpose so you don't accidentally commit it to your source code.

Install npm dependencies for Azure Identity and Resource management

In a Visual Studio Code integrated bash terminal, install the Azure SDK dependencies for Azure Identity and Resource management.

npm install @azure/identity @azure/arm-resources

List all resource groups in subscription with JavaScript

  1. Open the ./resource-groups/index.ts file and replace the contents with the following:

    import { AzureFunction, Context, HttpRequest } from "@azure/functions"
    import { listResourceGroups } from "../lib/azure-resource-groups";
    
    /*
    
    Get Resource Groups:
    
    curl http://localhost:7071/api/resource-groups
    
    */
    const httpTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise<void> {
    
        try{
            const list = await listResourceGroups();
    
            context.log(`${(list && list.length) ? list.length : 0} resource groups found`);
    
            context.res = {
                body: {
                    status: 200,
                    list: list
                }
            };
        } catch (err) {
    
            context.log(`No resource groups found: ${JSON.stringify(err)}`);
    
            context.res = {
                status: 500,
                body: err
            };
        }
    
    
    };
    
    export default httpTrigger;
    

    This file responds to API requests.

  2. Create a root-level directory named lib and create a new file in that directory named azure-resource-groups.ts.

  3. Copy the following code into the azure-resource-groups.ts file:

    // Include npm dependencies
    import { DefaultAzureCredential } from "@azure/identity";
    import { ResourceManagementClient } from "@azure/arm-resources";
    import { getSubscriptionId } from "./environment-vars";
    
    const subscriptionId  = getSubscriptionId();
    
    // Create Azure authentication credentials
    const credentials = new DefaultAzureCredential();
    
    // Create Azure SDK client for Resource Management such as resource groups
    const resourceManagement = new ResourceManagementClient(credentials, subscriptionId);
    
    // all resources groups in subscription
    export const listResourceGroups = async () =>{
        return await resourceManagement.resourceGroups.list();
    }
    

    This file completes the following:

    • Gets the subscription ID
    • Creates the DefaultAzureCredential context
    • Creates the ResourceManagementClient required to use the Resource management SDK.
    • Gets all the resource groups in the subscription.
  4. Create a new file in that directory named environment-vars.ts and copy the following code into that file.

    export const checkAzureAuth = () => {
      // The following code is only used to check you have environment
      // variables configured. The DefaultAzureCredential reads your
      // environment - it doesn't read these variables.
      const tenantId = process.env["AZURE_TENANT_ID"];
      if (!tenantId)
        throw Error("AZURE_TENANT_ID is missing from environment variables.");
      const clientId = process.env["AZURE_CLIENT_ID"];
      if (!clientId)
        throw Error("AZURE_CLIENT_ID is missing from environment variables.");
      const secret = process.env["AZURE_CLIENT_SECRET"];
      if (!secret)
        throw Error("AZURE_CLIENT_SECRET is missing from environment variables.");
    };
    
    export const getSubscriptionId = () => {
    
        checkAzureAuth();
    
      // Get subscription from environment variables
      const subscriptionId = process.env["AZURE_SUBSCRIPTION_ID"];
      if (!subscriptionId)
        throw Error("Azure Subscription is missing from environment variables.");
      return subscriptionId;
    };
    

    This file checks the environment variables before returning the subscription ID.

Test local functions

  1. In the Visual Studio Code integrated terminal, run the local project:

    npm start
    
  2. Wait until the integrated bash terminal displays the running function's URL.

    Partial screenshot of Visual Studio Code's integrated bash terminal when the Azure Function is running locally and displaying the local URL for the APIs in the Function app.

  3. Open a second integrated bash terminal in Visual Studio Code, Ctrl + Shift + 5, and use the following cURL command to use the API:

    curl http://localhost:7071/api/resource-groups
    

    If you have many resource groups in your subscription, you may want to pipe the output to a file for easier review.

    curl http://localhost:7071/api/resource-groups > resource-groups.json
    

    The response includes status and a list of all resource groups in your subscription.

Troubleshooting

If you couldn't complete this article, check the following table for issues. If your issue isn't listed in the table, open an issue on this documentation page.

Issue Fix
The app didn't start. Review the errors. Make sure you installed the required dependencies.
The app started but you can't get a 200 response. Make sure your curl command is requesting from the correct local route.
The API returned a 200 response but returned no results. Use the Visual Studio Code extension for Azure Resources to verify that your subscription has any resource groups. If you don't see any resource groups, don't worry. This article series adds an API to create and delete resource groups in your subscription. This API is added after the first deployment of the source code to Azure, so that you learn how to redeploy your code.

Next steps