Build and Host a Multiplayer Web Game. Completely FREE. (Part II)

In this post, we are going to publish our WebGL game by uploading it to Azure cloud. In the previous part, we created a web game in Unity and built it with the help of GitHub Actions. Here, we’ll go on to upload the completed game to the cloud.

Building Your Cloud Infrastructure

Our main aim is to create an AppService in the Microsoft Azure cloud so as to be able to host our WebGL game and we will be making use of Terraform to build the resources.

If you haven’t carried out the steps so far, create an Azure account, and download Terraform. You will also need the Azure CLI, to manage Azure from the command line.

Let’s start by creating a sub-folder “infra” into your Unity’s game folder. We will store the infrastructure code here. Then, log in to our Azure account:

az login

We have to create a storage account for Terraform in Azure. Terraform stores the state of the infrastructure in a file. This could also be local on your machine, but we want to execute Terraform from GitHub Actions.

az group create --location westeurope --resource-group mygamesa-rg az storage account create --name mygamestorageacc --resource-group mygamesa-rg az storage container create --name mygamestoragecontainer --account-name mygamestorageacc

Create a main.tf file and add the following code to it:

terraform { required_providers { azurerm = { source = "hashicorp/azurerm" version = "=2.98.0" } } backend "azurerm" { resource_group_name = "mygamesa-rg" storage_account_name = "mygamestorageacc" container_name = "mygamestoragecontainer" key = "mygame.terraform.tfstate" } } provider "azurerm" { features {} } resource "azurerm_resource_group" "this" { name = "mygame-resources" location = "West Europe" } resource "azurerm_app_service_plan" "this" { name = "mygame-appserviceplan" location = azurerm_resource_group.this.location resource_group_name = azurerm_resource_group.this.name sku { tier = "Standard" size = "F1" } } resource "azurerm_app_service" "this" { name = "mygame-app-service" location = azurerm_resource_group.this.location resource_group_name = azurerm_resource_group.this.name app_service_plan_id = azurerm_app_service_plan.this.id }
Code language: JavaScript (javascript)

Terraform can be used to create infrastructure for a variety of cloud providers. As we build it now for Azure, you have to configure the Azure (azurerm) provider. You inform Terraform in the backend block to put the state file in the storage we established earlier.

You have to declare the attributes of the Azure services you intend to build in each resource block. We create a resource group which is a logical grouping of all related resources. We also create a free (F1) app service plan and and AppService named mygame-app-service. We will upload our WebGL application to here.

The Terraform will make sure that the resources you have in Azure are the same as what you see in your state file. Let’s execute the following commands to deploy the resources:

terraform init terraform apply

Check the Azure portal, if Terraform successfully deployed the AppService.

Deploy the Infrastructure with GitHub

We want to execute our Terraform script from GitHub. At first, extend our .gitignore file, so that Git uploads only the script files:

*.lock.hcl *.tfstate *.tfstate.backup **/.terraform/*
Code language: JavaScript (javascript)

Create a new workflow, which will execute Terraform on our script. Earlier we did that locally, now it should work in GitHub. Create a new file .github/workflows/Terraform.yml:

name: Terraform on: [workflow_dispatch] env: ARM_CLIENT_ID: ${{secrets.AZURE_CLIENT_ID}} ARM_CLIENT_SECRET: ${{secrets.AZURE_CLIENT_SECRET}} ARM_SUBSCRIPTION_ID: ${{secrets.AZURE_SUBSCRIPTION_ID}} ARM_TENANT_ID: ${{secrets.AZURE_TENANT_ID}} jobs: buildInfrastructureWithTerraform: name: Build Infrastructure with Terraform defaults: run: working-directory: ./infra runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v2 - name: Terraform Setup uses: hashicorp/setup-terraform@v1 with: terraform_version: 1.1.7 - name: Terraform Format run: terraform fmt -check - name: Terraform Init run: terraform init - name: Terraform Validate run: terraform validate -no-color - name: Terraform Apply run: terraform apply -auto-approve
Code language: HTTP (http)

By default, Terraform has no access to Azure. We need to create a service principle in Azure and grant at least a contributor role to it on our subscription:

az account show --query=id az ad sp create-for-rbac --name "github-action" --role contributor --scopes /subscriptions/<subscription_id> --sdk-auth { "clientId": "<clientId>", "clientSecret": "<clientSecret>", "subscriptionId": "<subscriptionId>", "tenantId": "<tenantId>", "activeDirectoryEndpointUrl": "https://login.microsoftonline.com", "resourceManagerEndpointUrl": "https://management.azure.com/", "activeDirectoryGraphResourceId": "https://graph.windows.net/", "sqlManagementEndpointUrl": "https://management.core.windows.net:8443/", "galleryEndpointUrl": "https://gallery.azure.com/", "managementEndpointUrl": "https://management.core.windows.net/" }
Code language: PHP (php)

Terraform requires four environment variables set for it to be able to access Azure. Copy these values from the output of the above command into the related secrets in GitHub (Settings > Secrets > Actions):

ARM_CLIENT_ID: ${{secrets.AZURE_CLIENT_ID}} ARM_CLIENT_SECRET: ${{secrets.AZURE_CLIENT_SECRET}} ARM_SUBSCRIPTION_ID: ${{secrets.AZURE_SUBSCRIPTION_ID}} ARM_TENANT_ID: ${{secrets.AZURE_TENANT_ID}}

Then commit and push your code to the GitHub repository. This also will now contain the Terraform infrastructure code and the new workflow.

Start the Terraform workflow manually from GitHub (Actions > Terraform > Run workflow) and check if it runs with no issue. 

Deploy The Client with GitHub

In this step, we will implement the deployment workflow of our game in GitHub Actions. You can add this step right after you build the workflow, too. In this example, we will separate them, and configure manual start for the workflows.

Create in your project folder a file such as .github/workflows/DeployClient.yml. Copy this into it:

name: Deploy WebGL Client on: workflow_dispatch: {} jobs: deployClientToAppService: name: Deploy Client to App Service runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Download artifact uses: dawidd6/action-download-artifact@v2 with: workflow: BuildClient.yml workflow_conclusion: success name: mygame path: build/ - name: copy file uses: canastro/copy-file-action@master with: source: "WebConfig/web.config" target: "build/WebGL/web.config" - name: Deploy Client to App Service uses: azure/webapps-deploy@v2 with: app-name: 'mygame-app-service' slot-name: 'production' publish-profile: ${{ secrets.AZURE_PUBLISH_PROFILE }} package: build/WebGL/
Code language: JavaScript (javascript)

By using the workflow_dispatch, we’ll only be able to start the workflow manually from GitHub. By default, GitHub supports passing files between jobs, but not between workflows. As the result of our build was uploaded in another workflow, we have to use a special action from GitHub Marketplace (dawidd6/action-download-artifact@v2), so that we will be able to download the built artifact from the BuildClient.yml workflow.

To avoid a WebGL-specific issue, you need to carry out some extra steps. Create a WebConfig folder in your project folder, and create a web.config file:

<configuration> <system.webServer> <staticContent> <mimeMap fileExtension=".unityweb" mimeType ="TYPE/SUBTYPE" /> </staticContent> </system.webServer> </configuration>
Code language: HTML, XML (xml)

We will commit and push this file to GitHub, and the workflow will copy it (by using canastro/copy-file-action@master) next to our web game build. Also, set the Decompression Fallback checkbox in Unity Editor > File > Build Settings… > Player Settings… > Player > Publishing Settings.

Finally, we deploy the build folder to Azure. By default, GitHub has no access to Azure AppService. We can simply download the publish profile in Azure Portal > App Services > mygame-app-service > Get publish profile. Copy the content of this file into the AZURE_PUBLISH_PROFILE secret, in GitHub > Actions > Settings > Secrets > Actions.

Now push your code with Git to your GitHub repository. Under the Actions, find your new workflow, and click on Run workflow.

If the workflow run with no error, you can test if you can reach the game by typing the hostname in your browser:

az webapp config hostname list --webapp-name mygame-app-service -g mygame-resources --query=[0].name "mygame-app-service.azurewebsites.net"
Code language: PHP (php)

Conclusion

We used GitHub Actions and Terraform to upload our WebGL game to Azure in this second part of the series, completing the CD (Continuous Deployment) section of our CI/CD pipeline. In the next article, we’ll create and upload a server in Azure. Players will be able to play the game in multiplayer mode as a result of this. Keep an eye out for updates.

Leave a Comment

Your email address will not be published. Required fields are marked *