Azure Container Instances (ACI): start or stop on scheduled times

In my previous post, we created an azuredevops pipeline agent in ACI. If we were to run this container instance 24/7, it would be quite costly.

A Linux agent with 1 vCpu and 1 GB RAM in Australia East region costs $1.78 AUD at the time of writing this post. Running this agent 30 days costs $53.4 AUD. You can spin up a new VM with amount far less than that, of course you would still need to maintain and patch it.

If you are planning to use this agent only during Business hours, we can leverage Azure .Net SDK for ACI with Azure timer functions. It’s possible to setup timer functions which would star these agents in the morning and shut them down in evening. Let’s dive in.

Authenticating with Azure from SDK

Azure CLI provides a way to use File based authentication with SDK.

az ad sp create-for-rbac --sdk-auth > my.azureauth

This authentication file now can be used with SDK.

Create a new Azure Function app with Timer trigger and install Microsoft.Azure.Management.Fluent nuget package. Add following c# function.

private static IAzure GetAzureContext(ExecutionContext context)
{
	var azureAuthFile = Path.Combine(context.FunctionAppDirectory, AzureAuthFile);
	return Azure
		.Authenticate(azureAuthFile)
		.WithSubscription(SubscriptionName);
}

Above code expects the Auth File in FunctionAppDirectory. “AzureAuthFile” and “SubscriptionName” are Environment variables.

Starting containers

private static async Task Start(IAzure azure, ILogger log)
{

	var acis = ContainerGroupNames.Split(",");
	foreach (var aci in acis)
	{
		await azure
			.ContainerGroups
			.StartAsync(ResourceGroupName, aci);
		log.LogInformation($"${aci} has been started");
	}
}

ContainerGroupNames is an environment variable with a comma separated list of containers to start. ResourceGroupName is an environment variable storing name of the resource group where containers reside.

Stopping containers

private static async Task Stop(IAzure azure, ILogger log)
{

	var containers = azure
		.ContainerGroups
		.List()
		.ToList();

	var acis = ContainerGroupNames.Split(",");
	foreach (var aci in acis)
	{
		await azure
			.ContainerGroups
			.GetById(containers.FirstOrDefault(x => x.Name == aci)?.Id)
			.StopAsync();
		log.LogInformation($"${aci} has been stopped");
	}
}

Source code

You can find the complete source code here.

 

One thought on “Azure Container Instances (ACI): start or stop on scheduled times

Leave a Reply

Your email address will not be published. Required fields are marked *