Azure Resume Challenge

Dan Hearn
7 min readJan 18, 2024

--

With trying to get more hands on with Azure, I tackled the resume challenge at cloudresumechallenge.dev as well as this video. It consisted of many Azure services such as blob storage, CosmosDB, Azure Functions App, and Azure CDN as well as GitHub CI/CD. So come along for the ride and hopefully learn as much as I did.

First thing I did was make sure I had all the extensions and prerequisites set up as well as set up the folder structure locally so that I could easily access which ever part I needed. Aside from setting up my Azure account with an active subscription (outside of this post) I was using Visual Studio Code for an editor. The other prerequisites are as followed:

  1. .NET Core 3.1 SDK - The video was a few years old at this point but I was able to use Version 7 with no problems.
  2. Azure Function Core Tools - Allows the development of Azure Functions
  3. Azure Storage Extension - Used to easily deploy from VS Code to Azure Storage account
  4. Azure CLI - Adds the Azure CLI commands to manage resources
  5. C# Extension - Adds tools and support for C# to VS Code

For the file structure it was pretty straight forward, a frontend folder for HTML, CSS and JavaScript as well as a backend folder for the API, functions and a few other files.

Building the frontend

I then made a new repository on GitHub and cloned the repository that was provided in the video that consisted of required files as well as the HTML and CSS template. After updating the HTML to match my info and resume, the next part was to use JavaScript to create the counter function.

const getVisitCount = () => {
let count =30;
fetch(functionApiURL).then(response => {
return response.json()
}).then(response => {
console.log("Website called function API.");
count = response.count;
document.getElementById("counter").innerText = count;
}).catch(function(error){
console.log(error);
});
return count;
}

The way the function works is by fetching the data from the API, in this case the response would be the amount of views, and returns that value to a JSON file and changes the count to match. It then goes into the document and changes the element “counter” which is where the viewer count is displayed on the webpage. The last part is if there is some kind of error it will say there is an error, if not it will return the count. Since the API is not created yet this is as much that can be done until then but will come back to this function later on.

Building the backend

With the HTML changed to match my resume and starting the counter function, it’s time to head over to the Azure portal and set up the required services.

CosmosDB Account

Created a new CosmosDB account as well as a new resource group that I would store everything for this project named azureresume-rg and azureresume for the database name. Used the Core (SQL) API and for capacity I used serverless as the project does not need to be on all the time and helps with cost and usage. After it deployed I then created a new database inside the account and created a container with the ID as Counter. Once the database and container were setup I then added and item to the container that would represent the number of views to the site, in this case the count would be 0. With this setup we can now use this database within the function.

Azure Functions

Now that the database is setup I moved on to create the function that is triggered by an event, in this case a https request. This was done with a template that is part of Azure functions and with the extension enabled in VS Code it was a straightforward process. I created a new project in my backend folder and chose C# for the language, .NET 7, and https trigger for the template. In order for the function to work with CosmosDB, a binding needs to be setup. Following the documentation here, you first need to install the proper extensions to work with whatever language you are using, in this case C#. Using the .NET CLI I was able to install the following package using nuget.

dotnet add package Microsoft.Azure.Functions.Worker.Extensions.CosmosDB --version 4.5.0

The last step needed in order to start adding bindings was to setup a private key pair with the local.settings.json file. This file stays on the local machine and is ignored when pushing to GitHub and is why the connection string is needed. In the json, name the connection string then paste in the key from the Azure portal found under the keys tab within the database that was created earlier. You can then add the connection within the function by adding the database name, container name, connection string name as well as the ID and partition key from in the container.

public static class GetResumeCounter
{
[FunctionName("GetResumeCounter")]
public static HttpResponseMessage Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
[CosmosDB(databaseName: "azureresume", collectionName: "Counter", ConnectionStringSetting = "AzureResumeConnectionString", Id = "1", PartitionKey = "1")] Counter counter,
[CosmosDB(databaseName: "azureresume", collectionName: "Counter", ConnectionStringSetting = "AzureResumeConnectionString", Id = "1", PartitionKey = "1")] out Counter updatedCounter,
ILogger log)

This is the finished code setting up the connection string where the https trigger gets the data from the database and also the post where it will send the updated data and the log is for debugging.

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

updatedCounter = counter;
updatedCounter.Count += 1;

var jsonToReturn = JsonConvert.SerializeObject(counter);

return new HttpResponseMessage(System.Net.HttpStatusCode.OK)
{
Content = new StringContent(jsonToReturn, Encoding.UTF8, "application/json")
};
}
}

The second half shown above is where the updated counter that the https post request triggers and adds 1 to the count, adds the updated variable via json, then returns the updated string to content and giving us the new count. In order to set this up locally for testing and making sure everything is working as intended, I needed to connect the frontend with the backend using CORS. Basically what this does is allow sharing of restricted resources, like the counter function, to be shared to the webpage that anyone could see. Adding CORS into the local.settings.json file you can specify what resources you want to be displayed. I then ran the function locally in VS Code and doing so the output gave me a local host URL and added this to the function API in the main.js file. Now I could open the index.hrml file into my browser and see the working site with the counter, and made sure that refreshing the page would update the counter and it did meaning everything was working.

Deploying to Azure

Deploying the function app

Once I was done with how everything was looking and testing the functionality of the site locally, it was time to deploy to Azure. The main deployment and setup was done within VS Code using Azure CLI but I did have to use the portal as well. From the Azure tab within VS Code I was able to choose my project, click the blue arrow in the resources tab and follow the prompts to deploy. In the step-by-step I selected my subscription, then advanced function app and named the app as well as picked, .NET 7 for runtime stack, Linus for OS, consumption for hosting plan, the resource group that I created earlier, created a new storage account, and lastly choose a region closest to me.

Now that everything is deployed, we need to add a matching key pair within the function app in the portal so that the local.settings.json can be used within CORS. Going into the function app in the portal and in the configuration tab, make a new app setting, name it and paste in the connection string value from the json file into the value. After saving the setting, go into the function app again and copy the URL found on the top bar, and add this into the main.js file. This is now the production URL and the previous is left for local testing and debugging.

Adding a custom domain

In order to deploy the frontend and use a custom domain I used Azure blob storage for static web app and Content Delivery Network (CDN). In VS Code I used the Azure Storage extension to deploy my frontend, creating a storage account and once that was complete, the site was fully deployed on Azure. I went into the storage account and copied the provided URL, pasted it in my browser and my resume was displayed and functioning correctly. Now it was time to replace the generated URL with a custom domain that was a bit easier to remember.

I used namecheap.com to purchase my custom domain for my site but any DNS provider would suffice. Back in the portal I went into the storage account that was created for the front end and added a new endpoint to Azure CDN. Provisioning took some time but once deployed, I added the newly created endpoint URL to a CNAME record in namecheap, went back into the endpoint overview and created a custom domain. Here is where I added my new custom domain name and waited for the CDN to deploy. I was now able to type the new URL in the browser to see my site but at this stage it wasn’t fully working. I could not access it over http but could if I typed https in front and saw warnings about the certificate and the counter function was not working. For the certificate I configured the custom domain https feature that would be managed by CDN and the counter was not working because I now needed to update the CORS in the function to reflect the new domain. So back in the function app in the portal I added the new domain in the CORS tab, refreshed the browser, and now the counter function was working.

I now had my fully functioning resume site deployed in Azure and you can see that here at danhearn.me. Doing this project I learned a great amount about Azure services and will keep updating the site as I learn. I did also setup CI/CD with GitHub so that updating and making changes to the site will be more streamlined and efficient but will go into that in another post.

--

--