2017 Global Azure Bootcamp Logo

I presented at the Cincinnati Azure User Group's instance of the 2017 Global Azure Bootcamp conference. The good folks of CAUG invited me to Cincinnati last month as a guest speaker for their session of the 2017 Global Azure Bootcamp.

The event turned out great and I especially enjoyed learning more about AzureML as well as Cortana Cognitive Services!

My Topics

The topic I was invited to talk about was Cloud Computing. As you can imagine, there are many different places I could take that! Heck, I could cover about 2 full days on this topic simply with what I'm familiar with and that still would only scratch the surface!

As such, I decided to focus on the topics necessary to be able to teach people how to accomplish three main things:

  1. Deploy an MVC site to an App Service driven by a SQL Database data store.
  2. Deploy Web API REST services documented by Swagger to an App Service consuming an AzureML Prediction Service (demonstrated by the presenter before me).
  3. Build a batch job in a Web Job using AutoREST to generate proxies based on the Swagger docs from the above-deployed Web API services and driven by Storage Queue messages. This batch job feeds data from the MVC app into the AzureML Prediction Service consumed by the Web API service.

The Goods

So for the presentation, I actually created a companion site/blog over at CloudStuff.Pro (which, btw, was my first experience using Ghost). That domain, blog, and entire site was created as a temporary, throw-away companion site so this link will ultimately die around the end of March 2018. Feel free to hit it up but I'm also duplicating all of the important things below (with some redundancy to this above post) in the two sections:

  1. My Global Azure Bootcamp Slides
  2. Cloud Computing Bootcamp Lab

My Global Azure Bootcamp Slides

My Topics to Cover

The topic I will be covering at the 2017 Global Azure Bootcamp is simply "Cloud Computing". This is an incredibly broad topic and I have a very limited amount of time to cover this so I am narrowing this down both based on my skills and experience (I assume you want to learn from me and not just see some canned slides from Microsoft, right?) as well as based on the topics of the other presenters. Todd Walker is doing some very interesting coverage of Machine Learning (which I use with great success in predicting future energy needs for EnerGenuity) and Ernie Stormann is covering the ever-impressive Cognitive Services which should have some really great demos!

Based on that coverage, I chose to focus my coverage primarily on Storage topics (where I most heavily use SQL Databases and Queues) as well as PaaS hosting offerings. Azure has some incredibly powerful IaaS options, which are exactly what some companies are looking for. But the far majority of software I'm involved with run on PaaS offerings and this is where my skills and experiences are shaping the topics I cover. I may not be an expert in every area of these topics but I hope I can at least teach you something as well as point you into the right direction if you have any questions.

My Slides

I'm going ahead and posting my slides prematurely. I'm sure there will be some changes to the content and this link will be updated later with the changes. However, I first want to warn you that there is a LOT of content in these slides! In fact, there's too much there. So I'm really going to skim over some of the content when I present so we can get into the meaty hands-on demos. But I wanted to leave all of this information in the slides for those who want to come back and continue their learning.

Some of these slides were created by others and some were created by me, so I cannot take credit for them all. I tried to smooth over the formatting from the various presentations but I'm no PowerPoint wiz and, well, I'm sure somebody else could do much better.

And without further ado, you can access my slides via this link. And remember, if you download these now and come to the Bootcamp, you'll probably want to re-download these later to get the updates/corrections/additions I make to the slides!

Presentation Slides

(Updated 4/21)

And lastly...

I look forward to seeing you on Saturday!

And I won't lie. I also look forward to some Gold Star for dinner - we don't have those here in Indy! And I know. I'm from Cincy. This isn't to say Gold Star is better than Skyline. But we do have Skyline here in Indy so I'm able to get Skyline whenever I want. But it's been years since I last ate at Gold Star. So even if one is better than the other, there's no denying that it's nice to have the other from time to time when the one is your only option! I'll leave you to decide which is better. I have my opinion but you won't get it. ;-)


Cloud Computing Bootcamp Lab

Azure Functions Info

Azure Functions are an open source platform built on top of Azure Web Jobs. Functions provide an event-driven model to create very small pieces of functionality. Functions can be hosted either inside of an App Service Plan or via a Serverless model. Functions can be developed in a variety of different languages (C#, PowerShell, JavaScript, PHP, Node, F#, Python, .bat, bash, .exe, and more).

Pricing

Functions have three different pricing models based on two different metrics. The metrics are:

  1. Execution Count
  2. Execution Time measured in GB-seconds (rounded to the nearest 128MB of memory up to a maximum of 1,536MB)

The pricing models are:

  1. Free (first 1,000,000 executions and first 400,000 GB-s are free each month) 2. Serverless ($0.000016 per GB-s and $0.20 per million executions) 3. App Service plan (no additional cost to the App Service Plan)

Development

There are three different development models with Functions. Unfortunately, the tooling situation for Azure Functions is still ... maturing.

  1. Online (we will use this for this lab) 2. Visual Studio (currently, it's complicated - more info)
  2. Manual/Other (.bat, .exe, etc.)

Lab Steps

Section 1: Playing Around

Okay, enough with the theory. Let's play with some technology!

https://functions.azure.com/try

Select Timer, choose C#, and click the Create this function button.

Step 1.2: Login

Sign in with whatever authentication provider you choose. This is only so you can get back to your Functions if you close your browser and come back while they're still alive.

*NOTE: These functions we're creating with this totally free trial will only live for a very short period of time - one hour. If you wish to have them live longer, then you'll need to create the Functions from within your Azure Subscription. The steps should mostly be pretty similar but there may be some differences.

Step 1.3: Run the Function

By default, you'll have a Function that is mostly useless but will log the current date and time. Click on the Run button at the top to see it execute.

Step 1.4: Add a new Function

Next, we're going to add a new function. On the left side is a treeview. At the level of the word "Functions" is a large plus sign. Click on that and select the GenericWebHook-CSharp template. Name it "HelloWorld" and click the Create button.

Step 1.5: Explore the Integrate screen In the left pane, click on the Integrate menu item and observe the following things:

  1. Notice the Trigger is HTTP (req) and the output is *HTTP (res) (these stand for request and response).
  2. All HTTP methods are allowed. You can limit this to only listen to specific verbs.
  3. Route template is empty - you can use this to change the endpoint at which this Function is listening to.
  4. Output allows additional bindings to be selected. You could also output to a queue or any other output-compatible bindings.

Step 1.6: Explore the Manage screen

In the left pane, click on the Manage menu item and observe the following things:

  1. Function can be enabled, disabled, and deleted.
  2. The Function has keys associated: both Function Keys and Host Keys. These can be renewed or revoked and additional keys can be added.

Step 1.7: Test the Function

Click on your Function name to get back to the main Function screen, which should be "HelloWorld" unless you named it differently. From here, in the right pane, ensure the Test tab is selected and notice that it by default is attempting to post the name "Azure Functions" for first and last names. Click on the Run button at the top and see it log that it runs but return "Hello Azure Functions!" in the response based on the C# code. Notice that this was a POST request that was sent to test the Function.

Step 1.8: Change the Function to GET Only

  1. Click on the Integrate tab on the left and change the Allowed HTTP Methods field to "Selected Methods" and disable everything except for GET.
  2. Save the changes.
  3. Go back to the main Function screen.
  4. Notice that in the Test window on the right that the HTTP Method is no longer Post. Ensure GET is selected here.
  5. Click Run again and observe the failure. This is because the first/last names are being passed in via the Request Body, which isn't valid input for a GET request.
  6. Add the "first" and "last" properties as Query Parameters and try again.
  7. Click Run again and observe the failure. This is because the C# code is trying to pull the data from the Body and not the Querystring.
  8. Replace the contents of the function with the following code, which pulls the inputs from the Querystring instead, and test one last time for it to succeed:
    log.Info($"Webhook was triggered!");

    var parameters = req.GetQueryNameValuePairs()
                       .ToDictionary(kv => kv.Key, kv=> kv.Value, 
                            StringComparer.OrdinalIgnoreCase);

    if (parameters["first"] == null || parameters["last"] == null) {
        return req.CreateResponse(HttpStatusCode.BadRequest, new {
            error = "Please pass first/last properties in the query parameters"
        });
    }

    return req.CreateResponse(HttpStatusCode.OK, new {
        greeting = $"Hello {parameters["first"]} {parameters["last"]}!"
    });

Section 2: A long time ago in a galaxy far, far away....

Okay, here we're going to wrap SWAPI (the Star Wars API). We're going to leverage the RestSharp Nuget package to help us do this.

Step 2.1: Pulling Nuget Dependencies First, we need to expose some more advanced functionality of Functions. To start off:

  1. Go to your Function's main screen
  2. Click on View Files in the right pane 3. Expand the "HelloWorld" node if it isn't already 4. Add a new "Project.json" file and put the following content into it:
{
  "frameworks": {
    "net46":{
      "dependencies": {
        "RestSharp": "105.2.3"
      }
    }
  }
}

Step 2.2: Referencing pulled Nuget Dependencies Now that we have pulled the Nuget package, let's reference it in code.

  1. Select the run.csx file again under the View Files tab.
  2. At the top of the file, add #r "System.Web" to add a new reference that is part of the Framework but not automatically referenced. (This is similar to if you were in Visual Studio and right-clicked on "References" to "Add Reference" and chose part of the .NET Framework that wasn't yet referenced.) 3. Add using statements for System.Web, Newtonsoft.Json.Linq, and RestSharp.
  3. Click the Save button and ensure you see Compilation succeeded. If not, go back and fix the errors before moving forward.
  4. Replace the contents of the Run function with the following code and save it to ensure it compiles successfully.
    log.Info($"Webhook was triggered!");

    var parameters = req.GetQueryNameValuePairs()
                       .ToDictionary(kv => kv.Key, kv=> kv.Value, 
                            StringComparer.OrdinalIgnoreCase);

    if (parameters["name"] == null) {
        return req.CreateResponse(HttpStatusCode.BadRequest, new {
            error = "Please pass a \"name\" property in the query parameters"
        });
    }

    var name = parameters["name"].Trim();

    var client = new RestClient("http://swapi.co/api/");
    var request = new RestRequest(string.Format("people/?search={0}", HttpUtility.UrlEncode(name)));
    var response = client.Execute(request);
    var results = response.Content;

    var people = JObject.Parse(results)["results"].ToArray();
    var names = new List<string>(people.Length);

    foreach (var p in people)
    {
        names.Add(p["name"].ToString());
    }    

    return req.CreateResponse(HttpStatusCode.OK, new {
        StarWarsData = string.Join(", ", names)
    });

Step 2.3: Test away!

Now go to the Test window, pass in a query parameter with "name" as the name and any text you want for the value. To get started, first search on "ha" (no quotes) and you should see a few results.

Section 3: FAQ

As you can see, it is very quick and easy to throw together a little code and get something running online.

What about scaling?

This Serverless hosting of a Function (if it weren't in the Trial environment) would scale to very high levels based on dynamically-changing loads. In an App Service Plan, the scaling could change based on however you configure your auto-scaling. Here is a blog post with some in-depth analysis on scaling up to handle ~500 requests per second.

What should I expect in an Azure Subscription if this was just a Trial environment?

The UI inside of an Azure Subscription is nearly identical to what you worked with in this Lab.

What about source control and an IDE or Text Editor other than the Azure Portal?

This is obviously not how you want to work with complex systems - instead you probably want some source control, versioning, and automated deployments. Those concerns obviously change things a bit but only in the obvious ways. Here is some more information on those topics.

What is this .csx extension?

.CSX is a C# Scripting file. It's a bit different than typical C#. If you look at the Function code we were editing, it looked very familiar but you may have noticed that there was no class - the function simply existed instead of a class existing. For more on .csx code, there are some great links as part of this StackOverflow answer.

Can I upload my own DLLs?

Yup. You'd use #r "MyAssembly.dll" at the top of your file and put your DLLs into the bin folder (which you may have to create as you did the project.json file). Nuget packages are a bit easier but DLLs work just fine as well.

I finished early, what can I do now?

Go recreate this inside of your Azure Subscription and deploy it both to a Serverless instance and to an App Service Plan. You can get started by creating a "Function App" from the Marketplace (just click the big green PLUS sign in the top-left of the Portal after you sign in).