In lesson 5.3, we set up a continuous delivery pipeline for our SimpleRPG game Blazor app. We also need to set up a deployment pipeline for our game services. This pipeline will release the latest game services build to our Azure account and Functions App resource. The specific steps of this deployment script will be different from lesson 5.3, but the mechanism for creating a Release pipeline in Azure DevOps will be the same. We will create the Functions App resource in Azure, review how to create and configure a Release pipeline to target that resource, and we will use the ‘Deploy Functions App’ task to do the heavy lifting.
This release pipeline will give us the ability to create releases to our production environment for whichever build we wish. With the action of creating a new release in Azure DevOps, we get our latest service code released to Azure.
Create Azure Functions App Resource
First, we need to create an Azure Function App resource in our Azure subscription. This resource will be the container for our build, but it needs to exist for our deployment to work.
1. Go to the Azure portal (Home – Microsoft Azure).
2. Click on the ‘Create a resource’ button in the top button bar.
3. Click the ‘Function App’ element in the list.
4. In the ‘Basics’ tab, set the following configuration:
- ‘Subscription’ should auto-populate to the current subscription (only need to change if we have multiple Azure subscriptions).
- For ‘Resource Group’, select the resource group we created in Lesson 5.3 of this tutorial – ‘simplerpg-rg’. We could create a different resource group for the services, but we want all of the resources for this tutorial in one place to track the usage, costs, and be able to manage it as one logical unit.
- For ‘Function App name’, type ‘simple-rpg-services’. This needs to be unique and will become part of our Function App url.
- For ‘Version’, select the same version we were using in our developer environment (v3.1).
- For ‘Region’, select the closest region to your potential customers… ‘West US 2’ for now.
- And move to the ‘Hosting’ tab.
4. In the ‘Hosting’ tab, set the following configuration:
- For ‘Storage account’, create a new one called simplerpgv2. (Note: no special characters are allowed in this name). We had previously created simplerpgv1 for our Blazor game hosting. We want to keep that one separate because that version will remain self-contained and not make service calls. Our updated game release and services will all be in the simplerpgv2 storage account.
- For ‘Operating System’, select the Linux option. Azure Functions can run in either environment and costs are the same, but we want to show this capability.
- For ‘Plan type’, leave the selection at ‘Consumption’. We want to run in a serverless environment so that we are only paying for the compute and bandwidth that we use. And, Azure Functions App are free for the first 1 million requests per month, which is great for new projects.
- And move to the ‘Review and create’ tab.
5. After reviewing all of the configuration changes that we made, we can click the ‘Create’ button.
This will launch a process to create our Function App resource. Doing so will take a couple of minutes. We will get a notification when the job is complete. Then, we can look at the resource.
There are many tabs and links to follow here. Anyone unfamiliar with Azure should look around various pieces, like App keys and the Functions tabs. These are additional capabilities that we will look at there in the future. But take not of the service url shown in top right of this Essentials section. That is the public url for our Azure Function services.
But for now our resource exists and is ready for us to deploy to.
Create Release Pipeline in DevOps
After completing our one-time Azure resource setup, we can move to defining our release pipeline.
1. In Azure DevOps, navigate to the ‘Releases’ tab.
2. Click the ‘New’ flyout menu and then ‘New release pipeline’.
3. On the ‘Select template’ screen, select the Empty job.
4. On this screen, rename the pipeline to ‘simple-rpg-services-cd’ and name the stage ‘Release to Azure’. These can be set to anything, but it is important to easily identify the pipelines when you have multiple in your project. After setting the names, we close the screen.
5. This takes us to the main pipeline layout. Let’s start by clicking the ‘Add an artifact’ box.
6. In the flyout, select the ‘Build’ option at the top. Then in the ‘Source’ combo-box, pick our service build pipeline (simple-rpg-services-ci). The rest of the settings can remain the default. Finally, click the ‘Add’ button at the bottom of the page.
7. Then switch to the ‘Tasks’ tab at the top of the release diagram.
6. Click the ‘+’ button on the Agent job and then search for ‘Azure Functions App’ in the task list flyout. Then click the ‘Add’ button to place it in the pipeline.
7. This will place the task in our Agent job list, but without any configuration.
Configure Deploy Azure Function Task
Now that we have the Deploy Azure Function task, we need to configure all of the settings to tie this deployment task with our Azure instance.
- Make sure to select the Azure Function task in the list, so its ‘Configuration’ flyout opens up.
- Set the ‘Display name’ to ‘Deploy Azure Function App’.
- Select your Azure Subscription for deployment… this will depend on your Azure trial account.
- Select the ‘App type’ to be ‘Function App on Linux’ (Function App on Windows is also an option) to match what we set in the Functions App resource definition.
- Select the ‘App name’ that we created earlier in this lesson: ‘simple-rpg-services’.
- Note: we can also deploy to a particular slot… Slots are used to support two versions of the service. The production slot continues to take the live traffic. A staging slot can be defined and the pipeline could deploy to that slot. Then testing could be done on the service using the direct url to the staging instance. Once the testing verified the service functionality, we could swap slots and promote the staging version to be the production slot and start taking live traffic. This shows the power that Azure provides for releases, but we won’t make use of that for our tutorial.
- In the ‘Package or folder’ selector, navigate the drop folder structure to get to the ‘SimpleRPG.Game.Service.zip’ file (which was created by our build pipeline from lesson 5.11). Note that this deployment task takes the compressed build output and deploys that to Azure.
- For ‘Runtime stack’, we select .NET (as of the current date, Azure Functions only support .NET Core 3.1, but .NET 5 support is already in preview and coming soon).
- Click the ‘Save’ button at the top of the page to persist these settings.
- Finally, return to the ‘Pipeline’ tab.
At this point, our build pipeline is created and the Azure Functions deployment task is configured. We are ready to run our first release.
Run First Release to Azure
Running releases is exactly the same as we did in lesson 5.3. With the ‘simple-rpg-services-cd’ pipeline selected, click the ‘Create Release’ button.
In the resulting ‘New release’ flyout, just click the Create button (to accept all of the defaults). You will see the release run:
When it completes, you will see the following success message.
Congrats! Our deployment to Azure succeeded and our service is now accessible publicly. Let’s run our service endpoint (https://simple-rpg-services.azurewebsites.net/api/location) and see if we can return some locations:
As we can see, our LocationTemplate service call worked as expected and returned the locations that we saw in earlier lessons. As we can see, the localhost portion of the url was replaced by our real service url (https://simple-rpg-services.azurewebsites.net/), but the rest of the service routing behaves exactly the way it did when the services were running locally in our development environment.
In the last two lessons, we have taken our Azure Functions services project from our local development environment to our git repository, created a build pipeline to build and test every commit and pull-request in the simplerpg-service repo. Then, we created a deployment pipeline that takes a particular build (or the latest build) and deploys it to our Azure environment. Finally, we can start releases for the builds that we desire. And, the release will drive the actual fully-automated deployment… not every build in the main branch needs to be deployed. It is up to us to pick the builds that we want to deploy. Now we can take game services code changes automatically from our code commit to build to deployment in Azure.