Skip to main content

Azure Functions

Azure App Service also supports the concept of web jobs. Web jobs offer a simple way to get your own background tasks, such as key processing, deployed to the same service in your hosting plan that are running the web application. So what we have with web applications and web jobs is a very programmer-friendly model that makes it super easy to create and deploy multiple websites along with background processing tasks and bundle them all up onto one server to keep your costs down, but with the flexibility to scale up as the demands of your application require. Azure Functions is actually built on top of the web jobs SDK and it's hosted on the App Service platform. So in many ways you can think of it as just another part of this same offering, but with a few additional powerful new capabilities 


Azure Functions is the idea of events and code. You simply supply some code, which is just a single function usually written either in C# or JavaScript, and you tell Azure Functions what event should trigger it. So for example, you can use Azure Functions to run a function every hour. So the event, or trigger in this case, is a scheduler. And I might use this sort of event trigger to run a nightly batch process that cleans up some data in my database. Another source of event that can trigger a function is new data becoming available. This might be a new message appearing on a queue or a new file being uploaded to Azure blob storage. And I might use this sort of event to trigger sending an email whenever a message appears on a particular queue. Another really useful example of an event that can trigger a function is an HTTP request. Whenever someone calls a specific URL, your function is executed and can respond to that request.

Another major benefit that Azure Functions offers is a consumption-based pricing model. With the more traditional Azure offerings we just discussed, virtual machines and web applications, you need at least one server running constantly, and you have to pay for that. But with Azure Functions, you have the option to select a pay-as-you-go pricing option. In other words, you only pay when your code is actually running. So if you're listening on a queue and no messages ever arrive, then you pay nothing. And the Azure Functions framework will automatically scale the number of servers running your functions to meet demand. So if there's no demand, there might actually be no servers at all actively running your code. But the framework is able to spin one up very quickly if needed. And so this pricing model can result in dramatic cost savings compared to the more traditional approach of paying a fixed monthly amount to reserve one or more servers.

https://docs.microsoft.com/en-us/azure/azure-functions/

https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-storage-table?tabs=csharp

https://docs.microsoft.com/en-us/azure/azure-functions/functions-triggers-bindings

https://docs.microsoft.com/en-in/azure/azure-functions/functions-scale?WT.mc_id=Portal-WebsitesExtension#consumption-plan  

We just need to write the code that shows how to respond to these events.



It follows a consumption based pricing model,  Another major benefit that Azure Functions offers is a consumption-based pricing model. With the more traditional Azure offerings we just discussed, virtual machines and web applications, you need at least one server running constantly, and you have to pay for that. But with Azure Functions, you have the option to select a pay-as-you-go pricing option. In other words, you only pay when your code is actually running. So if you're listening on a queue and no messages ever arrive, then you pay nothing. And the Azure Functions framework will automatically scale the number of servers running your functions to meet demand. So if there's no demand, there might actually be no servers at all actively running your code. But the framework is able to spin one up very quickly if needed. And so this pricing model can result in dramatic cost savings compared to the more traditional approach of paying a fixed monthly amount to reserve one or more servers.


Azure functions are charged based on the number of executions, cpu time and RAM allotted. So when we create a function we need to make sure that it completes quickly and also the memory requirement is low as more RAM will be needed.

Pricing













































Introducing Serverless Architecture

Azure Functions is a serverless platform, or at least it's serverless when you choose the consumption pricing tier. And the concept of serverless has grown rapidly in popularity over recent years, and many cloud providers are offering similar serverless platforms, such as Amazon's AWS lambda. Now, of course, in one sense the name serverless is a bit silly because of course there are servers needed to run your code. But one of the key ideas behind serverless is that we want to delegate the management and maintenance of our servers to third parties so that we, as developers, can focus exclusively on the business requirements. So in a serverless architecture, you'd rely on third party platform or Backend as a Service offerings wherever possible, so for example using Azure Cosmos DB for your database instead of provisioning your own database server on a virtual machine or using Auth0 for your logging and authentication rather than hosting your own identity service. 





We have one server that does everything. Instead write azure functions to handle things like listening to a queue.


After refactoring to azure functions. It is easy to scale up and maintain


we can have one event trigger the next function. for ex: once the license file is generated it is stored to blob storage using a function, another function takes this file and sends an email to the customer


https://tryfunctions.com/ng-min/try?trial=true -- for free


In Azure Functions the servers are managed for you. You don't need to install them, provision them or patch them. You simply provide your function code, and the platform ensures that there's an available server to run it on. So serverless means that the servers are abstracted away from us, meaning we can spend less time thinking about servers, and more time focusing on what really matters to our business. Secondly, Azure Functions offers a serverless per-second billing model based on consumption. In other words, you're only paying while your functions are actually running, and so that means if you went a month without any of your functions running, you'd pay nothing at all. And Azure Functions even comes with a generous monthly free grant, so you can actually run your functions many thousands of times a month before you start paying anything, and this allows for some really dramatic cost savings, and it's great for prototyping. You don't need to pay lots of money up front in order to validate a new product idea. 


Thirdly, Azure Functions automatically scales in response to demand. Say you had a function that was triggered by a queue message, and suddenly hundreds of messages were placed into that queue, rather than having to wait for a single server to process each message in turn, Azure Functions will automatically, behind the scenes, scale to multiple servers to allow you to work through that backlog rapidly. And the same is true for HTTP-triggered functions. The greater the load on your Web API, the more servers behind the scenes will be running to meet the demand. But all of that happens automatically, you don't need to do anything special to enable it, so serverless development is typically simpler, cheaper, and more scalable than a traditional approach of creating an application and hosting it on a dedicated virtual machine.

When we create a storage explorer , a storage account also gets created. It holds all the files , logs and other data that is needed by the function app




Creating an Azure Function

1. Go to azure portal and click on resource group and search function apps. Function apps are like containers for azure functions.






Select the plan as Consumption(default) to use the pay as u go pricing model.


When creating a function in the Azure portal.

We get 4 files listed in the portal.

1. subscription plan details
2. azure function
3. Application insights ..like appdynamics


Click on the second one and add a new portal azure function.




Choose the binding needed and create.






A default function is created that reads data from header or body and returns a response.

when we view the files that are created when we create the azure function , we can find that we have a few files.. Run.csx contains the code , and we have the function.json file. In the  functions.json file we can see the configurations for that function.. like the method types that can be used to call the function.. the type of trigger that the functions is binded to. the auth level etc


On the right hand side we can see options called integrate manage and monitor.. whatever changes we make to the integrate section will be reflected on the functions.json.. manage section can be used to delete and configure the azure function and its security features.


Creating using VS




Create a new Azure function and select an empty binding.. Then right click and add a new Azure Function.




Run the project


a cmd will pop up with the url where the function can be accessed.. If we check the bin we can find the functions.json.

Functions


        [FunctionName("Function1")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
            [Queue("demoq", Connection = "QueueSetting")] TextWriter textWriter,
            ILogger log)

        {
            log.LogInformation("C# HTTP trigger function processed a request.");

            string name = req.Query["name"];

The triggers will have the word trigger in the name itself. The attribute will contain properties to connect to the source. Ex: a QueueTrigger will have arguements that will accept the connection string. The response in this case is written to a Queue called demoq and the Connectionstring has the connection string of the queue.







Create a REST API using Azure functions


public static class StudentApi
    {
        static List<Student> Students = new List<Student>();
      
        [FunctionName("CreateStudent")]
        public static async Task<IActionResult> CreateStudent(
            [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "Student")] HttpRequest req,
            ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");

            string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
            Student data = JsonConvert.DeserializeObject<Student>(requestBody);

            try
            {
                // Add to DB, instead just add to static list
                data.StudId =  Guid.NewGuid();
                Students.Add(data);
                return new OkObjectResult(data);
            }
            catch (Exception ex)
            {
                log.LogInformation(ex.Message);
                return new BadRequestObjectResult(ex.Message);
            }

        }

        [FunctionName("GetStudent")]
        public static IActionResult GetStudent(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "Student")] HttpRequest req,
            ILogger log)
        {
            log.LogInformation("Get Student list");

            try
            {
                return new OkObjectResult(Students);
            }
            catch (Exception ex)
            {
                log.LogInformation(ex.Message);
                return new BadRequestObjectResult(ex.Message);
            }

        }

        [FunctionName("GetStudentById")]
        public static IActionResult GetStudentById(
       [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "Student/{id}")] HttpRequest req,
       ILogger log,Guid id)
        {
            log.LogInformation($"Get Student {id}");

            try
            {
                var student = Students.FirstOrDefault(i => i.StudId == id);
                if (student == null) return new NotFoundObjectResult(student);
              
                return new OkObjectResult(student);
            }
            catch (Exception ex)
            {
                log.LogInformation(ex.Message);
                return new BadRequestObjectResult(ex.Message);
            }

        }

    }

    internal class Student
    {
        public Guid StudId { get; set; }
        public string StudName { get; set; }
        public string Address { get; set; }
    }

Once these are deployed, just run the app and we can find the URLS for the endpoints


Enable CORS locally. works only on local machine



AZURE FUNCTIONS WITH TABLE STORAGE


Add microsoft.azure.webjobs.extensions.storage nuget

Monitoring Functions























Securing Functions





















How Can I Secure My Functions?
One very important question when you deploy your functions to production is how can you make sure that they're properly secured? And for most trigger types, your functions are already inherently secure by virtue of the fact that only authorized users can perform the action that triggers the function. For example, if I've got a queue-triggered function, then that can only be triggered by someone who's already got permission to post a message to that queue. But for HTTP-triggered functions, how can you prevent someone who knows the URL of your function from just calling it? Well, there are several options available to us. The most obvious one, which is built right into Azure Functions, is the concept of function keys. 

For each HTTP-triggered Azure function, you can choose an authorization level, and the three main options to choose between are anonymous, function, and admin. Anonymous means that the Azure Functions runtime will allow all calls to your function without any credentials required, so you'd only use this if you really were happy for anyone to call your function or maybe if you're going to implement your own custom validation logic in the function code itself. The function authorization level means that the caller must supply a secret code that's specific to that particular Azure function. It can be provided either as the code query string parameter or with the x-functions-key HTTP header. And the admin authorization level means that the caller must supply a secret code that's specific to the function app as a whole, and this is useful if you've created several HTTP-triggered functions that together make up an API and you don't want your caller to have to provide separate codes for each endpoint. The Azure Functions portal provides a user interface that allows you to generate new function and admin keys, as well as cycle or revoke them. 

And this means that it's possible to give each client of your API their own personalized key. Now, function keys are fine for server-to-server calls where the caller can be trusted to keep a secret, but that's not always possible. Fortunately, there are some alternative ways you can secure your HTTP-triggered functions. For example, you can also enable an Azure App Service feature called Easy Auth, which requires a valid OAuth token before accepting a call. This feature applies to your entire function app, and it can be configured to use Azure Active Directory, Google, Facebook, or several other identity providers. If you're interested in seeing a demo of how to configure Easy Auth with Azure Functions, then do check out another course I've created here on Pluralsight. It's in the Microsoft Azure Developer: Create Serverless 

Functions course. And the demo can be found here. However, Easy Auth isn't always an ideal choice because it globally applies to all functions, and also because it redirects you to a login page whenever you make an unauthorized call, which is only really useful when your consumers are accessing your functions from a web browser. Other security options include simply validating the HTTP headers yourself, and this gives you complete freedom to perform your own custom bearer token validation. But of course, the usual security considerations apply here. Generally, it's very risky to implement your own security code, so you should only do this if you're really sure you know what you're doing. 

One other option worth considering is to put an Azure API Management service in front of your function app, and this gives you access to additional security features that API Management offers to authorize callers. And then API Management, once it's authorized the callers, can pass on the calls to your function app simply using the function keys, which never need to be revealed to the clients. So there are plenty of security choices available to you. Let's see in our next demo how we can configure function keys.

Authentication





















Bindings

Time triggered





















So for example, this CRON expression will execute next at 6:30 in the evening. This second example will execute at 15 minutes past midday and 10 seconds on the ninth day of February. We can create schedules that reoccur by using step values. Here, we can see the value for minutes is this */5. This will mean our function will be triggered once every 5 minutes. 

We can specify days of the week. So in this example, we're going to execute the function once every 15 minutes, so 4 times an hour, but only on days 1 and 3. The value of 0 represents Sunday, so this is saying we want to execute this function only on Mondays and Wednesdays. We can also specify ranges for the weekday. Here we're saying we want to execute the function every half an hour, but only on working days, so that's Monday through Friday inclusive. 

Routing in functions

change the route and set the parameters as part of the route template rather than query strings.

select function app -> integrate -> click on the input binding and add a route parameter.

















Comments

Popular posts from this blog

App Role assignment to service principal --

 Using Ms Graph Rest API's Permissions One of the following permissions is required to call this API. To learn more, including how to choose permissions, see  Permissions . Permission type Permissions (from least to most privileged) Delegated (work or school account) AppRoleAssignment.ReadWrite.All and Application.Read.All, AppRoleAssignment.ReadWrite.All and Directory.Read.All, Application.ReadWrite.All, Directory.ReadWrite.All Delegated (personal Microsoft account) Not supported. Application AppRoleAssignment.ReadWrite.All and Application.Read.All, AppRoleAssignment.ReadWrite.All and Directory.Read.All, Application.ReadWrite.All, Directory.ReadWrite.All Create 2 app registrations. App role owner will contain the app role that will be assigned to a service principal. The  reader role in approleowner will be added to the approlesubscriber Setup postman to use the Oauth auth flow to get a token for MS Graph. ClientId:   Application (client) ID for approlesubscrib...

ASp.net core 3.1 identity

It is just an extension to cookie authentication. We get a UI, Tables, helper classes, two factor authentication etc. Even EF and its database constructs. So instead of writing code for all of this we can just use these in built features. Extending Default Identity Classes Add a class that inherits from    public class AppUser : IdentityUser     {         public string Behavior { get; set; }     } Also change the user type in login partial.cs under shared folder Then add migrations and update db using migrations. We can customize further.  services.AddDefaultIdentity<AppUser>(options =>              {                 options.SignIn.RequireConfirmedAccount = true;                 options.Password.RequireDigit = false;           ...

Get user groups

 string[] scopes = new string[] { "https://graph.microsoft.com/.default" };             string clientId = "";             string tenantId = "";             string secret = "";                        var options = new TokenCredentialOptions             {                 AuthorityHost = AzureAuthorityHosts.AzurePublicCloud             };             // https://learn.microsoft.com/dotnet/api/azure.identity.clientsecretcredential             try             {                 var clientSecretCredential = new ClientSecretCredential(                        ...