Navigate / search

How to enable/disable Azure Function programmatically

Today I would like to write about something different. I am curious… Have you ever thought about enabling/disabling Azure Function by code? In such scenario, we would be able to decide about the state of the function directly from our application. I believe that you can find a lot of useful scenarios for such behaviour. I will provide two of them.

The first one. We have some resource that is not so fast and we would like to reduce the frequency of using it during the day. In such scenario, we can use Azure Storage Queue as a buffer for actions to compute. And turn on Azure Function only for a night and then in the morning turn it off again.

Another one is strictly connected with a question that I hear quite often during meetups or hackathons. Are we able to turn off function when we use all free capacity that is provided by Azure? People that are offering some small solution for public access would like to avoid the situation when they will need to pay for it.

Providing code that will deliver such service is quite an easy task. We need to update one value in functions.json file. You will find there a property disabled that defines if the function is running or is it stopped:

In my solution I have prepared separate function that will be used to run or stop any function that you will select. You need to provide only correct parameters that will point function which you would like to change. Then we need to figure out how we can change function.json file. I will use kudu REST API. And we need to combine everything to working solution.

The algorithm is straightforward:

  1. download and deserialise json file
  2. update disabled parameter and upload a new file to cloud.

And that is all:

#r "Newtonsoft.Json"

using System.Net;
using Newtonsoft.Json;

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req)
{
  dynamic data = await req.Content.ReadAsAsync<object>();
  string username = data?.username;
  string password = data?.password;
  string functionSiteRoot = data?.functionSiteRoot;
  string functionName = data?.functionName;
  bool isDisabled = data?.isDisabled;

  WebClient webClient = new WebClient
  {
    Headers = { ["ContentType"] = "application/json" },
    Credentials = new NetworkCredential(username, password),
    BaseAddress = functionSiteRoot
  };

  var functionJson = JsonConvert.DeserializeObject<FunctionSettings>(webClient.DownloadString($"{functionName}/function.json"));
  functionJson.disabled = isDisabled;
  
  webClient.Headers["If-Match"] = "*";
  webClient.UploadString($"{functionName}/function.json", "PUT", JsonConvert.SerializeObject(functionJson));

  return req.CreateResponse(HttpStatusCode.OK);
}

internal class FunctionSettings
{
  public bool disabled { get; set; }
  public List<Binding> bindings { get; set; }
}

internal class Binding
{
  public string name { get; set; }
  public string type { get; set; }
  public string direction { get; set; }
  public string queueName { get; set; }
  public string connection { get; set; }
  public string accessRights { get; set; }
  public string schedule { get; set; }
}

Now we can run our function by sending POST request, e. g. with Postman:

I think that all parameters clear for you. Most of them we will take from PublishSettings of function that we would like to control.

I would like to share with you with a small hint. Remember that when you are copying this code you should also create project.json file with the following content:

{
  "frameworks": {
    "net46":{
      "dependencies": {
        "Newtonsoft.Json": "9.0.1"
      }
    }
  }
}

It is needed because we are using an external library in our function.

Comments

avatar
Michał Jankowski
Reply

You are right.

Also in Functions v2 it works in a different way.

Leave a comment

name*

email* (not published)

website

This site uses Akismet to reduce spam. Learn how your comment data is processed.

.