Deploy an application in Azure Container Instances (ACI) through GitHub Actions.
Having been only one or two years in the market, GitHub Actions has drawn a respectable amount of popularity. Housing >80% of the source-codes in the community and with the increasing need for CI/CD, GH actions was rather late to the race but growing rapidly. Many teams are migrating their workflows to GH actions.
Talking about migrations, containers have become the preferred way to package & deploy cloud applications. Azure’s Container Instances (ACI) brings a minimal orchestration alternative to their Kubernetes Service (AKS), which can be ideal for small & mid-sized applications.
Today, I will guide you to deploy your application in ACI through GitHub Actions.
This post is divided into 3 sections.
Section#1 talks about dockerizing an (NodeJs) application;
Section#2 will help you to setup Azure credentials in GitHub secrets;
Section#3 will help you create a GitHub workflow to deploy your docker image to Azure Container Instances.
Section#1: Dockerize an application
In this section, I will dockerize an existing NodeJs application, create a docker image of it and verify that it works perfectly in local. Skip this section if your application is already dockerized.
Step#1: Add Dockerfile to your application
I have a NestJs application which I am Dockerizing. This application launches at port 80 by default. Adding a Dockerfile to build image.
Step#2: Verify in local
Build & run the docker image in local and verify that it works fine.
$ docker build -t hello-world:1.0.0 .
$ docker run -p 80:80 hello-world:1.0.0
Section#2: Setup Azure credentials in GitHub secrets
This Section will guide you though creating a Resource Group scoped Service Principal and saving its credentials to GitHub secrets. These secrets will then be used in GitHub Actions to authenticate to Azure in the workflow. Feel free to skip this section if you already have completed these steps.
Step#1: Install Azure CLI in your local
We will be creating all the resources using Azure CLI and is mandatory to be installed in your local machine before moving forward.
Use this link to download Azure CLI.
Step#2: Login to Azure CLI interactively
$ az login --tenant <tenant_id>
If you associate with a single tenant then the tenant argument can be avoided. Otherwise, replace <tenant_id> in the command with your Azure Tenant ID and run in terminal. Azure CLI will use your default browser to log you in.
Step#3: Create a resource group
A resource group is a logical collection of resources in Azure.
$ az group create -l centralindia -n TestGroup
Create a resource group with a name and location of your choice. I am creating ‘TestGroup’ in ‘centralindia’.
Step#4: Create a Service Principal
An Azure service principal is an identity created for use with applications, hosted services, and automated tools to access Azure resources. It assumes some roles within which it can take actions.
To create a service principal, make sure that you have enough permissions (Application Administrator) or your tenant owner has allowed any user to register application.
$ groupId=$(az group show --name TestGroup --query id --output tsv)$ MSYS_NO_PATHCONV=1 az ad sp create-for-rbac --name TestApp --role contributor --scope $groupId --sdk-auth
In the first command, use the name of your resource group you created in the previous step.
Put the name of the service principal in the second command of your choice. I have named it ‘TestApp’.
Save the JSON of the service principal generated by Azure.
Step#5: Create GitHub secrets
In your browser, go to your GitHub repo -> settings -> secrets and create the following secrets. These secrets will be used by GitHub actions to authenticate to Azure.
AZURE_CREDENTIALS => <the json generated above>
AZURE_USERNAME => <clientId of the service principal>
AZURE_PASSWORD => <clientSecret of the service principal>
Section#3: Create GitHub workflow to create Container Instance
This section creates a GitHub workflow that builds an image of your application, pushes to Azure Container Registry and uses it to deploy an Azure Container Instance.
Step#1: Configure workflow.yml
In your local, go to your repository/.github/workflows and create workflow.yml. Configure it to run a build every time changes are pushed to the master branch.
on:
push:
branches:
— master
name: Build & Deploy to ACI
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
Now, in workflow.yml, add the following steps.
Step#2: Checkout the latest code
Add the first step to checkout the latest code from master branch.
- name: ‘Checkout GitHub Action’
uses: actions/checkout@master
Step#3: Login to Azure CLI
Add the next step to login to Azure using the saved Azure Credentials.
- name: ‘Login to Azure’
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
Step#4: Create Azure Container Registry
In the next step, create a Container Registry. This will create the registry only if it does not exist.
- name: ‘Create Azure Registery’
run: az acr create — resource-group TestGroup — name testgroupregistry — sku Basic
Step#5: Build and Push
In this step, build the docker image and push to the azure container registry. Choose the name of your docker image accordingly.
Note: The clientId and clientSecret of the service principal generated before can be used to login to the registry.
- name: 'Build & Push'
uses: azure/docker-login@v1
with:
login-server: testgroupregistry.azurecr.io
username: ${{ secrets.AZURE_USERNAME }}
password: ${{ secrets.AZURE_PASSWORD }}
- run: |
docker build . -t hello-world:${{ github.sha }}
docker tag hello-world:${{ github.sha }} testgroupregistry.azurecr.io/samples/hello-world:${{ github.sha }}
docker push testgroupregistry.azurecr.io/samples/hello- world:${{ github.sha }}
Step#6: Deploy to Azure Container Instances
Create an Azure container instance using the image. Choose the variables for your instance accordingly and correctly specify the image URL. This step only deploys the new image if the ACI is already created.
- name: 'Deploy to Azure Container Instances'
uses: 'azure/aci-deploy@v1'
with:
resource-group: TestGroup
dns-name-label: helloworlddevtest
image: testgroupregistry.azurecr.io/samples/hello-world:${{ github.sha }}
cpu: 1
memory: 1
registry-username: ${{ secrets.AZURE_USERNAME }}
registry-password: ${{ secrets.AZURE_PASSWORD }}
name: helloworlddev
location: 'central india'
Step#7: Push the changes
This will auto trigger the workflow. Navigate to <your_repo_url>/actions to view your workflow jobs & builds.
Step#8: Verify
Login to Azure Portal, Navigate to the created container instance, Locate the FQDN and browse.
Alternatively, the ‘Deploy to Azure Container Instance’ step in the workflow also prints the URL of the instance.