Search code examples
terraformazure-functionsazure-powershellterraform-provider-azure

Terraform script to disable multiple functions in Azure Function app


I would like to know how to disable functions in Azure Function app using terraform script.

I have list of function code in a directory and I would like to call those functions from that directory and disable the functions in Azure Function app. Also I need to disable few functions in one environment and keep it enabled remaining functions. How to achieve this?

I have gone through multiple ways but not sure how to implement. I went through terraform documentation, also PowerShell script but not sure how to implement this using terraform as I never found using terraform. Also I am expecting few functions should be disabled in one environment and remaining few should be enabled as it is earlier. Also all functions should be disabled in other environment. I am looking for terraform script to achieve this.

Appreciate if someone could help with the script. Also, I am new to Azure Functions.


Solution

  • I have finally wrote the script by myself in Powershell and Bash script to enable/disable functions from the Azure functionapp and azure function app slots. Below are the two versions. Now, the below script I am executing through terraform null resoruce. The script will meet the below scenarios. So it will not directly possible via terraform instead we need to execute bash/powershell script to enable/disable azure functions and call this script via terraform null resource.

    1. Enable/disable functions from functionapp main slot and funcion app preprod/any slot.
    2. If any function you provide in the Disable_function list then those functions only will be disabled and remaining all other functions which are in the functionapp will be enabled.
    3. If no functions are provided in the disable_function list then it will not perform any action/ it will maintain the same old state in the function app for the functions.
    4. If any typo or misspelled function names listed in the Disabled_function list then it will throw error saying that function does not exist.

    Bash Script:

    #!/bin/bash
    
    # Access environment variables passed from Terraform
    subscription_id="$subscription_id"
    resourceGroupName="$resourceGroupname"
    functionAppName="$functionappname"
    deployment_slot="$deployment_slot"
    
    # Function to check if a function is disabled
    isDisabled() {
      local functionName="$1"
      for disabledFunction in "${disable_functions_array[@]}"; do
        if [ "$disabledFunction" == "$functionName" ]; then
          echo "true"
          return
        fi
      done
      echo "false"
    }
    
    # Define function_list variable based on deployment_slot
    if [ "$deployment_slot" = "production" ]; then
      # Get the list of function names for the main slot (production)
      function_list=$(az rest --method get --uri "https://management.azure.com/subscriptions/${subscription_id}/resourceGroups/${resourceGroupName}/providers/Microsoft.Web/sites/${functionAppName}/functions?api-version=2018-11-01" | jq -r '.value[].name' | cut -d '/' -f2)
    else
      # Get the list of function names for the specified deployment slot
      function_list=$(az rest --method get --uri "https://management.azure.com/subscriptions/${subscription_id}/resourceGroups/${resourceGroupName}/providers/Microsoft.Web/sites/${functionAppName}/slots/${deployment_slot}/functions?api-version=2018-11-01" | jq -r '.value[].name' | cut -d '/' -f2)
    fi
    
    # Transform disable_functions into an array
    IFS=',' read -ra disable_functions_array <<< "$disable_functions"
    
    # Loop through function names and disable/enable functions
    for function in $function_list; do 
      isDisabledFlag=$(isDisabled "$function")
      if [ "$deployment_slot" = "production" ]; then
        az functionapp config appsettings set --name "$functionAppName" --resource-group "$resourceGroupName" --settings "AzureWebJobs.$function.Disabled=$isDisabledFlag"
      else
        az functionapp config appsettings set --name "$functionAppName" --resource-group "$resourceGroupName" --slot "$deployment_slot" --settings "AzureWebJobs.$function.Disabled=$isDisabledFlag"
      fi
    done
    
    
    # Check for non-existent functions in the disable_functions array compared to function_list
    nonExistentFunctions=()
    for disabledFunction in "${disable_functions_array[@]}"; do
     found=false
     for function_name in $function_list; do
     if [ "$disabledFunction" = "$function_name" ]; then
      found=true
      break
     fi
     done
     if [ "$found" = false ]; then
     nonExistentFunctions+=("$disabledFunction")
     fi
    done
    
    # Output non-existent functions and exit if any are found
    if [ ${#nonExistentFunctions[@]} -gt 0 ]; then
     printf -v joined '%s, ' "${nonExistentFunctions[@]}"
     echo "Error: The following functions do not exist: ${joined%, }" >&2
     exit 1
    fi
    

    Powershell Script:

    # Retrieve a list of functions from an Azure Function App in a specific deployment slot
          $functions = func azure functionapp list-functions ${data.azurerm_linux_function_app.temp_function.name} --slot ${var.deployment_slot}
         
         # Extract the names of the functions from the list
          $functionNames = $functions | Select-String -Pattern '^\s+([^\s]+)\s+-' | ForEach-Object { $_.Matches[0].Groups[1].Value }
         
         # Get the list of functions to be disabled from an environment variable and store it in an $disable_functions
          $disable_functions = $env:TF_VAR_disable_functions -split "," | Where-Object { $_ -ne "" }
    
         # Compare the list of functions with disable function list, if matched, functions are disabled else functions are enabled
           foreach ($function in $functionNames) {
           $isDisabled = $disable_functions -contains $function
           az functionapp config appsettings set --name ${data.azurerm_linux_function_app.temp_function.name} --resource-group ${data.azurerm_resource_group.temp_rg.name} --slot ${var.deployment_slot} --settings "AzureWebJobs.$function.Disabled=$isDisabled"
          }
    
         # Throw an error if any non-existent functions were specified in the $disable_functions list
          $nonExistentFunctions = $disable_functions | Where-Object { $functionNames -notcontains $_ }
            if ($nonExistentFunctions.Count -gt 0) {
            throw "The following functions do not exist: $($nonExistentFunctions -join ', ')"
            }