Blog Post

Apps on Azure Blog
5 MIN READ

Scale up AppServicePlan from Azure Function App

Prashant Pratap's avatar
Apr 02, 2019
First published on MSDN on Dec 01, 2017

In this blog post we are going to demo how to programmatically change AppServicePlan properties. For example, we are going to change the pricing tier (Scale Up) from a console app and also from a Azure Function App.

Here are main steps :

  • Create a Service Principal account
  • Use Resource Explorer to get details on your existing AppServicePlan
  • Create a console app or Azure Function App
  • Step 1 : Service Principal Account

    As our console app or function app is going to access Azure resources, we need to set up an account for them. This account is called Service Principal account.  Please click here for more details on Service Principal.  We can create a Service Principal account using these PowerShell cmdlet



    [code language="powershell"]

    Login-AzureRmAccount
    $sp = New-AzureRmADServicePrincipal -DisplayName wabacuser -Password "yourpassword"
    Sleep 30
    New-AzureRmRoleAssignment -RoleDefinitionName Contributor -ServicePrincipalName $sp.ApplicationId
    Get-AzureRMADServicePrincipal -SearchString "wabacuser" |fl



    [/code]


    From these cmdlet output, copy TenantID.

    Step 2 : Resource Explorer

    Best way to learn Azure ARM APIs is using Resource Explorer : https://resources.azure.com/ . In Resource Explorer you can list existing Azure resources and their properties. In this blog post, we are going to work on the existing AppServicePlan, so log into Resource Explorer and follow these steps:

  • Expand your subscription
  • Expand resourceGroup node
  • Expand your resource group
  • Expand providers node
  • Expand Microsoft.Web node
  • Expand serverfarms node
  • Expand your AppServicePlan
  • Click GET button
  • Note the SKU property (name is set to S2)
  • And also copy the URL next to the GET button
  • Step 3a : Console App

    Open Visual Studio, and create a empty .NET Console App. Add Active Directory Authentication Library from NuGet : https://www.nuget.org/packages/Microsoft.IdentityModel.Clients.ActiveDirectory/

    Next, add following code to program.cs file


    [code language="csharp" highlight="14,15,16,17,18,19,20,30"]
    using Microsoft.IdentityModel.Clients.ActiveDirectory;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net.Http;
    using System.Net.Http.Headers;
    using System.Text;
    using System.Threading.Tasks;

    namespace FAppARM
    {
    class Program
    {
    static string tenantId = "tenand id from above PowerShell cmdlets";
    static string username = "http://wabacuser";
    static string password = "yourpassword";
    static string token = string.Empty;
    static string subscription = "your subscription id";
    static string resourceGroup = "your resource group name";
    static string appServicePlan = "your app service plan name";

    static HttpClient httpClient = new HttpClient();
    static void Main(string[] args)
    {
    var t = GetToken();
    t.Wait();
    var url = $"https://management.azure.com/subscriptions/{subscription}/resourceGroups/{resourceGroup}/providers/Microsoft.Web/serverfarms/{appServicePlan}?api-version=2016-09-01";
    var t2 = Get(url);
    t2.Wait();
    var t3 = Put(url, "{ \"location\":\"South Central US\",\"Sku\":{\"Name\":\"S1\"}}");
    t3.Wait();
    }

    public static async Task GetToken()
    {
    string url = "https://login.windows.net/" + tenantId;
    var authContext = new AuthenticationContext(url);
    var credential = new ClientCredential(username, password);
    var t = await authContext.AcquireTokenAsync("https://management.azure.com/", credential);
    token = t.AccessToken;
    return token;
    }

    static async Task Get(string url)
    {
    httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
    return await httpClient.GetStringAsync(url);
    }

    static async Task Put(string url, string jsonData)
    {
    httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
    StringContent postData = new StringContent(jsonData, System.Text.Encoding.UTF8, "application/json");
    var t = await httpClient.PutAsync(url, postData);
    return await t.Content.ReadAsStringAsync();
    }

    static async Task Post(string url, string jsonData)
    {
    httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
    StringContent postData = new StringContent(jsonData, System.Text.Encoding.UTF8, "application/json");
    var t = await httpClient.PostAsync(url, postData);
    return await t.Content.ReadAsStringAsync();
    }
    }
    }

    [/code]

    In the line # 30, we are going to set the scale out to S1 .

    Now run this console app and then go back to Resource Explorer, check the Sku property.

    Step 3b: Function App

    Log into Azure portal at https://portal.Azure.com and create a new C# HTTP trigger Function App.

    Click on the View files menu from the blade at right. Next click on Add and set file name to project.json. Add these lines in this file. This will tell Function Runtime to download the ADAL NuGet package

    [code language="csharp"]
    {
    "frameworks":{
    "net46":{
    "dependencies":{
    "Microsoft.IdentityModel.Clients.ActiveDirectory":"3.17.2"
    }
    }
    }
    }
    [/code]

    Next, add this below code in the run.csx:

    [code language="csharp" highlight="7,8,9,10,11,12,13,25"]


    using System.Net;
    using Microsoft.IdentityModel.Clients.ActiveDirectory;
    using System;
    using System.Net.Http;
    using System.Net.Http.Headers;

    static string tenantId = "your tenant id";
    static string username = "http://wabacuser";
    static string password = "your password";
    static string token = string.Empty;
    static string subscription = "your subscription";
    static string resourceGroup = "your resource group name";
    static string appServicePlan = "your service plan";

    static HttpClient httpClient = new HttpClient();

    public static async Task Run(HttpRequestMessage req, TraceWriter log)
    {
    log.Info("C# HTTP trigger function processed a request.");

    token = await GetToken();

    var url = $"https://management.azure.com/subscriptions/{subscription}/resourceGroups/{resourceGroup}/providers/Microsoft.Web/serverfarms/{appServicePlan}?api-version=2016-09-01";
    var str = await Get(url);
    var str1 = await Put(url, "{ \"location\":\"South Central US\",\"Sku\":{\"Name\":\"S2\"}}");

    return req.CreateResponse(HttpStatusCode.OK, "DONE");
    }

    public static async Task GetToken()
    {
    string url = "https://login.windows.net/" + tenantId;
    var authContext = new AuthenticationContext(url);
    var credential = new ClientCredential(username, password);
    var t = await authContext.AcquireTokenAsync("https://management.azure.com/", credential);
    token = t.AccessToken;
    return token;
    }

    static async Task Get(string url)
    {
    httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
    return await httpClient.GetStringAsync(url);
    }

    static async Task Put(string url, string jsonData)
    {
    httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
    StringContent postData = new StringContent(jsonData, System.Text.Encoding.UTF8, "application/json");
    var t = await httpClient.PutAsync(url, postData);
    return await t.Content.ReadAsStringAsync();
    }

    static async Task Post(string url, string jsonData)
    {
    httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
    StringContent postData = new StringContent(jsonData, System.Text.Encoding.UTF8, "application/json");
    var t = await httpClient.PostAsync(url, postData);
    return await t.Content.ReadAsStringAsync();
    }

    [/code]

    In the line#25, we are now changing it to back to S2 . Execute this function and check the Sku property in the Resource Explorer

    Updated Aug 24, 2020
    Version 2.0
    No CommentsBe the first to comment