Integrating ACI with other Azure services
Containers Containers Containers
One of the big themes from this year's Build conference was containers. Service Fabric Mesh will make it easier to run containers on Service Fabric. Web Apps for Containers now supports multi-container web apps and Windows containers. Azure Container Registry (ACR) now has the ability to build container images. And Dev Spaces is a really exciting feature making it really easy for a development team to use Azure Kubernetes Service (AKS) to run and debug their containers in the cloud.
Azure Container Instances
One of my favourite new container related services in Azure is Azure Container Instances (ACI). This is essentially serverless containers and is designed to be the quickest and easiest way to get a container up and running in the cloud.
I've already written about some of the things you could do with ACI, such as building and deploying an ASP.NET Core app, running a media processing task, and running multiple ACI containers together in a "container group".
But the real power of ACI comes not from using them on their own, but combining them with other Azure services. So today I want to highlight some services that integrate really well with Azure Container Instances: Azure Functions, Azure Logic Apps, and AKS. For each one I'll point you to a great demo app that shows off the capabilities of using ACI in conjunction with that service.
Managing ACI Containers with Azure Functions
Azure Container Instances are great for batch jobs, or handling bursts of load. As work becomes available, you can rapidly spin up new instances of your ACI container groups to meet demand or work through the backlog, and then delete them once the demand subsides.
But of course you need something to monitor the load and manage the creation and deletion of those container groups, and Azure Functions is a great fit. If you've created a service principal, you can use that to create or delete new ACI container groups with the Azure .NET SDK or REST APIs.
Brian Peek and Dimitris Gkanatsios have created a superb demo scenario that shows how Azure Container Instances can be managed from Azure Functions. In their example, they monitor how many players are connected in an online game, and if there are too many players for one server to handle, they spin up a new server instance with ACI. They also shut them down when they're no longer needed. You can check out the video and code.
Using ACI Containers as activities in a Durable Functions workflow
I'm a huge fan of Durable Functions for building serverless workflows, but sometimes you need to perform an activity that isn't a good fit for a function. Maybe it needs to run for a long time (the consumption plan limits your function duration to 10 minutes), access an Azure File Share (you can't mount Azure File Shares to an app service plan), or use custom software that is difficult to install directly onto an App Service instance.
One current drawback of using an ACI Container Group to implement a step in a Durable Functions workflow is how to determine when it's finished. I'd love to see Event Grid integration so the container group itself publishes an event when it finishes running. But until then, you'd need to either poll it for status, or get it to report back with a webhook when it's done. Fortunately, the Durable Functions features of waiting for external events, and supporting timeouts for long-running tasks make this kind of pattern possible to implement.
I've not yet got a demo of ACI + Durable Functions to share with you yet, but I've built out most of the necessary pieces, so I'll blog again once I've connected them together. Basically I want to take my media processing Durable Functions workflow sample, but use ACI instances to implement the actual FFMPEG transcodes rather than doing them directly in the Function App.
Using ACI containers in Logic Apps workflows
I've got less experience with Azure Logic Apps. They in many ways are a similar to Durable Functions in that they offer a serverless way of running workflows in the cloud. The development experience is using a visual designer, rather than a code based approach. One strength they have is over 100 connectors to other services, meaning that if your workflow is mostly about connecting different services together, it can be quick to get something up and running.
Logic Apps includes an "ACI Connector" which supports creating and deleting container groups, getting the status or logs of a container group, and listing container groups. This means you can quite easily create a workflow that creates a container group and uses a Logic Apps "until" block to watch its status until a certain condition is met, and then delete the group.
For a sample application that shows this off, check out this sentiment analysis demo which shows a Logic App triggered off incoming emails. For each email, it extracts the text and then creates an ACI container group that uses Azure Cognitive Services to perform sentiment analysis on that text. It's a slightly contrived example as Logic Apps could easily have just called Cognitive Services directly, but it shows the principle of how you can use a container inside a Logic Apps workflow. The project contains detailed instructions for how to try this out for yourself.
Using ACI for elastic bursting with Azure Kubernetes Service (AKS)
The final integration possibility is to use ACI to provide additional elastic scale to a Kubernetes cluster. Thanks to the "Virtual Kubelet" ACI Connector project you can make ACI appear as a "virtual" node in a Kubernetes cluster, essentially providing infinite scale. The
az aks install-connector Azure CLI command makes this especially easy to set up if your Kubernetes cluster is an instance of AKS.
This diagram was shown in several presentations at this year's Build conference to show how the virtual Kubelet ACI connector integrates with an AKS cluster:
There's a great demo application that shows the ACI connector in action available here. The scenario is a facial recognition application. By default, the one node AKS cluster only has a single instance of the "image recognizer" container running, resulting in a backlog of tasks building up. But with a single command you can scale up to multiple instances running in ACI, enabling you to rapidly work through the backlog. You can see a video of this demo app in action in this Azure Friday episode with Ria Bhatia
Azure Container Instances really shines when used in conjunction with other Azure services, bringing the benefits of containers, per-second billing, and elastic scale to your existing Functions Apps, Logic Apps and Kubernetes deployments.
Can we use Managed Service Identity (MSI) within aci container , I know it's possible with service fabric mesh.vivek kumar Jain
Good question. I'm not sure, but I don't think MSI is currently available for aci. Would be a useful featureMark Heath
Very interesting! I look foward to your Durable Function+ACI post but that brings me to ask why exactly? Is it to get around the Consumption plan's 5/10 minute constraint?NullReference
I have a specific challenge around a long running job which is updating a potentially very large spreadsheet in memory when it receives messages. My initial thought would be for a Function to be triggered by a queue that would then raise an event in the DF with the message. But I wondered how this would be implemented? Under the covers would the DF have to retrieve the spreadsheet from blob storage each time it processed a message?
If so, might I be better off implementing this in ACI and call into that from my message receiving Function?
Your thoughts would be much appreciated! Thanks
Yes, I quite often work with custom media transcoding tools that take longer than 5-10 minutes to run, but also require installing special software which you can't do on app service. So ACI is a good fit.Mark Heath
In your case it sounds like you want to keep the spreadsheet in memory to avoid having to re-load it? That introduces a fair amount of complexity as you'd only want one instance running and you start to lose the benefits of serverless as you'd need to keep the activity running.
The other option is as you say loading your spreadsheet from blob storage each time, but again you'd need to take care that you couldn't have two activity functions working on it at once.
I guess I'd want to know in this situation if it really needs to be a spreadsheet? Can it be a database instead, and then just provide a function that lets people download the current contents of the database as a spreadsheet
Thanks for the prompt response!
It's an existing integration solution so needs to be a spreadsheet.
I think I'm alright voiding instance issues by using the queue and associating the job with instance of the DF.
I guess my question was really about the way in which DF manages state - if it is going to have to fetch the whole partially complete spreadsheet from Blob and then push it back there for every message processed - I would have concerns over it's likely performance.
BTW the messages are likely to be in the thousands and will come quite quickly over 10 mins or so - hence queuing so as not to swamp it and to avoid instancing issues.
Nope, but you have secret environment variables that you can use.Simon J.K. Pedersen
Late reply - but ACI does support MSI now! Read more at aka.ms/aci/msiJustin Luk
Yes, that's great news! Although it's not called MSI anymore - "managed identities" seems to be the new name :)Mark Heath
Did you ever get time to write up the post describing the use of ACI as durable function activities?bcraun
not yet - I can start the ACI containers, but I still need to write the bit that checks whether they've finished running - once that's done I'll write the postMark Heath