Until now we have worked with docker images that others have created, now we are going to do a code change on our own code base and push the changes to Container Apps using GitHub Actions. We are now going to use a Azure CLI command to create a GitHub Action that builds the Queue Reader C# project and pushes the image to Azure Container Registry and deploys it to our Container App.
First, we need to create a service principal that can be used from the GitHub action to deploy the changes we are introducing.
Note
If you are not able to create a service principal in the Azure Active Directory that is connected to your subscription, you will unfortunately not be able to do this part of the lab
Azure CLI using Bash
az ad sp create-for-rbac \
--name <SERVICE_PRINCIPAL_NAME> \
--role "contributor" \
--scopes /subscriptions/<SUBSCRIPTION_ID>/resourceGroups/<RESOURCE_GROUP_NAME> \
--sdk-auth
The return value from this command is a JSON payload, which includes the service principal's tenantId
, clientId
, and clientSecret
.
Set the variables in bash.
spClientid=[Replace with the clientId of the service principal]
spClientSecret=[Replace with the clientSecret of the service principal]
tenantid=[Replace with the tenantId of the service principal]
PowerShell
$sp = New-AzADServicePrincipal -DisplayName <SERVICE_PRINCIPAL_NAME>
New-AzRoleAssignment -ApplicationId $sp.ApplicationId -RoleDefinitionName 'Contributor' -ResourceGroupName <RESOURCE_GROUP_NAME>
$spClientId = $sp.ApplicationId
$spClientSecret = $sp.PasswordCredentials.SecretText
$tenantId = (Get-AzContext | Select-Object -ExpandProperty Tenant).Id
Now we need a GitHub Personal Access Token (PAT) so we can authenticate against GitHub from Azure CLI.
Go to github.com --> Settings --> Developer Settings --> Personal access tokens and click on Generate new token button.
Password prompt might appear. Enter password.
In the Note textbox enter a name for the PAT, such as ca-pat. Give the PAT the following scopes:
- repo (Full control of private repositories)
- workflows (Update GitHub Action workflows)
Click Generate token, copy the generated token and assign the variable.
Bash
ghToken=[Replace with the PAT]
Set the "repoUrl" variable, replace with the GitHub account name.
repoUrl=https://github.com/<OWNER>/ukth-appinn-containerapps-orderapi
PowerShell
$ghToken=[Replace with the PAT]
Set the "repoUrl" variable, replace with the GitHub account name.
$repoUrl="https://github.com/<OWNER>/ukth-appinn-containerapps-orderapi"
Now we need to get information about the Azure Container Registry that we created in the beginning.
Bash
acrUrl=$(az acr show -n $acr -g $resourceGroup --query 'loginServer' -o tsv)
acrUsername=$(az acr show -n $acr -g $resourceGroup --query 'name' -o tsv)
acrSecret=$(az acr credential show -n $acr -g $resourceGroup --query passwords[0].value -o tsv)
PowerShell
$acrUrl = Get-AzContainerRegistry -Name $acr -ResourceGroupName $resourceGroup | Select-Object -ExpandProperty LoginServer
$acrCreds = Get-AzContainerRegistryCredential -Name $acr -ResourceGroupName $resourceGroup
$acrUsername=$acrCreds.Username
$acrSecret=$acrCreds.Password
Now all the variables are set so we can run the Azure CLI command, make sure you are located at the root of the repo and run the following command.
Azure CLI using Bash
az containerapp github-action add \
--repo-url $repoUrl \
--context-path "./queuereaderapp/Dockerfile" \
--branch main \
--name queuereader \
--resource-group $resourceGroup \
--registry-url $acrUrl \
--registry-username $acrUsername \
--registry-password $acrSecret \
--service-principal-client-id $spClientid \
--service-principal-client-secret $spClientSecret \
--service-principal-tenant-id $tenantid \
--token $ghToken
Azure CLI using PowerShell
Note
Whilst most Azure tasks can be done using native Azure PowerShell commands this is an exception. Hence we will be using AZ CLI tool for this. If you havent logged in to Azure CLI you can run the following commands# Login into Azure CLI az login --use-device-code # Check you are logged into the right Azure subscription. Inspect the name field az account show # In case not the right subscription az account set -s <subscription-id>
az containerapp github-action add \
--repo-url $repoUrl \
--context-path "./queuereaderapp/Dockerfile" \
--branch main \
--name queuereader \
--resource-group $resourceGroup \
--registry-url $acrUrl \
--registry-username $acrUsername \
--registry-password $acrSecret \
--service-principal-client-id $spClientid \
--service-principal-client-secret $spClientSecret \
--service-principal-tenant-id $tenantid \
--token $ghToken
The command will create a GitHub Action and run it, it takes a couple of minutes, please check the status at github.com --> Actions and see the progress of the GitHub Action after it has been created by the Azure CLI command.
Dive into the logs and locate the latestRevisionName, then go to the Azure portal and verify that the revision name is the same for the queuereader Container App.
Now it’s time to do a code change and validate that it has been deployed.
Open VS Code --> queuereaderapp folder --> Open Worker.cs and scroll down to line number 58, where we are writing to the log.
logger.LogInformation($"Message ID: '{message.MessageId}', contents: '{message.Body?.ToString()}'");
Below this line insert the following code.
logger.LogInformation("This is a new log message!");
Then open the Terminal in VS Code and make sure you are in the queuereaderapp folder. Run this command.
dotnet build .
Make sure that the build was succeeded.
Commit the change in VS Code.
After the commit, the previous created GitHub Action starts, follow the progress at github.com --> Actions.
After the deployment has succeeded, please verify that the revision number has changed using the Azure portal.
Now it’s time to validate that the changes we made has taken affect. Send a message to the API.
Bash
curl -X POST $dataURL?message=mynewlogmessage
PowerShell
Invoke-RestMethod "$($dataURL)?message=mynewlogmessage" -Method Post
Validate the change by looking in Log Analytics.
ContainerAppConsoleLogs_CL
| where ContainerAppName_s has "queuereader" and ContainerName_s has "queuereader"
| where Log_s has "Message"
| project TimeGenerated, Log_s
| order by TimeGenerated desc
| limit 50
Here you should see one row with the text "This is a new log message!".
You have now configured a simple CI/CD pipeline to automatically deploy code changes to the application.
Next step is to enhance security by protecting our HTTP API using API Management.
That will be covered in Challenge 6
- Challenge 1: Setup the environment
- Challenge 2: Deploy Container Apps Environment and troubleshoot Container Apps
- Challenge 3: Split traffic for controlled rollout
- Challenge 4: Scale Container Apps
- Challenge 5: Configure CI/CD for Container Apps
- Challenge 6: Protect Container App with API Management
- Challenge 7: Enable Container App authentication