Azure Function w/ User Assigned Identity

view gist on github

January 12, 2019
gist

Azure utility functions

What is this?

It’s an ARM template and an Azure Function App (https://github.com/noelbundick/azure-utilities) that I use as a base for doing interesting things in Azure. Ex: Start a VM from a Chrome bookmark, spin up Azure Container Instances as Azure DevOps build agents on-demand, etc. Cleanup resource groups on a timer trigger, etc.

It uses User Assigned Identity so I don’t have to juggle certs or Service Principal credentials

Note: there’s some other “global infra” stuff in this template and I couldn’t be bothered to clean it up. I know this exact template works, so you get bonus content!

Why did you make it?

I’ve long had Functions that use a Service Principal to make Azure calls. I wanted to use User Assigned Identity so that I never have to worry about secrets.

I also wanted to wire up the Microsoft.Azure.Services.AppAuthentication with the fluent Azure SDK

How does it work?

I forked & inlined the AppAuthentication library because it doesn’t support this scenario yet. Keep an eye on these issues:

The ARM template deploys a User Assigned Identity and an Azure Function that has the identity assigned. It also sets the AzureServicesAuthConnectionString to reference the AppId of the created identity.

How do I use it?

Run this:

BASENAME=noel

# Get your user objectId (for KeyVault - unnecessary for this example, but like I said, I didn't clean up the template)
OID=$(az ad user show --upn $(az account show --query 'user.name' -o tsv) --query objectId -o tsv)

# Deploy some stuff! This will create a Function App & User Assigned Identity named "{baseName}-utility"
az group create -n infra -l westus2
az group deployment create -g infra --template-file ./azuredeploy.json --parameters baseName=$BASENAME userObjectId=$OID

# Give your new User Assigned Identity permissions so it can do things in your subscription (turn on VMs, clean up storage blobs, whatever)
IDENTITY_OID=$(az identity show -n "$BASENAME-utility" -g infra --query principalId -o tsv) 
az role assignment create --role Contributor --assignee-object-id $IDENTITY_OID

# Use azure-functions-core-tools to deploy the function into the provisioned app
# You could configure source deployment straight from the repo if you wanted, but I don't have working code for that off the top of my head - so here's something that definitely works
git clone https://github.com/noelbundick/azure-utilities
cd azure-utilities/src/Acanthamoeba.Functions
dotnet publish -c Release
cd bin/Release/netcoreapp2.1/publish
zip -r Acanthamoeba.Functions.zip *
az functionapp deployment source config-zip --src Acanthamoeba.Functions.zip -n "$BASENAME-utility" -g infra

azuredeploy.json