Azure Resource Managment using Azure Functions with Powershell

  • This is a short discussion on how you can manage Azure resources using Azure Functions with Powershell
  • You might use this approach to enable automated resource control in your Azure Subscription e.g. Turn off a service everyday at 00:00 and turn it back on at 08:00 Am the next morning

NB: Your Azure Function App needs to have the approapriate permissions to read or configure resources using Powershell. Follow this guide to learn more about managed identity for Azure functions.



Getting started

Step 1 - Create a function App

# Creates a function app that uses the Consumption plan instead of a dedicated app plan
yourResourceGroup=blog-rm-pwsh-rg
azureRegion=westeurope   # You may change this if you wish!
yourFunctionAppName=myblogrm-pwsh-$RANDOM
yourStorageAccount=mystorageaccount$RANDOM

# Create a resource group to manage all app resources collectively
az group create -n $yourResourceGroup -l $azureRegion

# Create a storage account used to store function log files, configuration etc.
az storage account create -n $yourStorageAccount -g $yourResourceGroup -l $azureRegion --sku Standard_LRS


# Finally create a powershell function app with a consumption plan
az functionapp create -g $yourResourceGroup --consumption-plan-location $azureRegion -n $yourFunctionAppName -s $yourStorageAccount --runtime powershell --functions-version 3


Step 2 - Role Assignment

  • Go to the identity section on the functionapp blade to enable managed identity
  • Click on role assignement and assign the required roles for the resources you want to manage
# E.g. Assign a managed identity to the app created in Step 1 and,
# Assign a contributor role to the managed identity within the entire resource group you want to manage
myOtherResourceGroup="/subscriptions/<your-subscription-id>/some-other-rg"  # Replace with your own values

az functionapp identity assign -g $yourResourceGroup -n $yourFunctionAppName \
    --scope $myOtherResourceGroup \
    --role Contributor \
    --verbose


Step 3 - Create HTTP triggered Azure Function

We will make use of the built-in editor in Azure Portal to enable quick test runs of our powershell functions.

  • You are now ready to create a function within your function app. For this example, create a new function with an HTTP trigger
  • Edit, requirements.psd1 file in your app files so that it looks something like this
# This file enables modules to be automatically managed by the Functions service.
# See https://aka.ms/functionsmanageddependency for additional information.
#
@{ 
    'Az.Accounts'  = '2.*'
    'Az.Functions' = '2.*'
    'Az.Resources' = '5.*'
}
  • Make sure that this snippet is present in your profile.ps1 file
if ($env:MSI_SECRET) {
    Disable-AzContextAutosave -Scope Process | Out-Null
    Connect-AzAccount -Identity
}
  • When using the Consumption function App Plan, It is not recommended to install the entire Az module, as it might cause timeout issues!
  • Checkout the list of powershell modules your function app might need to use here.

Step 4 - Test

  • Navigate to the internal function code editor in Azure portal
  • Replace the contents of run.ps1 with the following code
using namespace System.Net
param($Request, $TriggerMetadata)


# Use Az module commands to manage your resources here
# Make sure you have assigned the required roles on the managed identity!!!
# For example: Read the metadata of a resource group within your subscription
$rg = (Get-AzResourceGroup -Name "your-own-rg").ResourceGroupName


$body = "Hello, $rg. This HTTP triggered function executed successfully."
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
    StatusCode = [HttpStatusCode]::OK
    Body = $body
})
  • Use the Test/Run button within the Azure Portal editor to test your function
  • You should see a response similar to this:
Hello, photo-text-rg. This HTTP triggered function executed successfully.


Remember to delete the resource you are not using to avoid unexpected charges!

# Remove all resource under the resource group we just created
az group delete -n $yourResourceGroup -y



Troubleshooting

  • “..SubscriptionId cannot be null”

    • Make your Azure Function App has the required roles to acces sthe resource you are trying to manage!
  • “..Az module installation failed”

    • If possible, avoid installing the entire Az module in your function App
    • Only use the submodules that your functions needs, e.g. ‘Az.Resources’ = ‘5.*’
  • “Unresolved Az cmd-let…”

    • Check that the managedDependency property is set in host.json
    //........
    
      "managedDependency": {
        "Enabled": true
    }
    
    //......
  • “Function timeout…”

    • If you are on the consumption plan, the app may need to re-download the dependenancies
    • In some cases, this may cause the function to run over the minimum timeout setting
    • You can change this deafult setting in host.json file
    // ....
     "functionTimeout": "00:10:00"  // Maximum  value on the consumption plan is 10 minutes
    // ...
    • Learn more about this setting, check out the docs

Written by@NdamuleloNemakh
Welcome to my coding diary, I hope you find it useful!

GitHubTwitter