This project consists of a frontend written in Node.JS and a service written in C# on top of .NET 6.
- Azure subscription
- Domain name to manage using Azure DNS
-
Launch the Azure Cloud Shell and login with your Azure subscription.
-
Clone this repository
git clone https://github.com/sabbour/contoso-names.git
-
Change into the
contoso-names
directory and runsetup.sh
while providing the required parameters. Note: Running this script will provision Azure resources that might incur billing.cd contoso-names chmod +x setup.sh ./setup.sh
This will take a few minutes to complete and will provision an Azure Kubernetes Service (AKS) cluster with the recommended add-ons enabled, an Azure Container Registry, an Azure Key Vault with a self-signed certificate, an Azure DNS Zone. The script will also download the cluster's credentials into the cloud shell.
For the last part with Web App Routing to function correctly, you need to provide a domain that is managed by Azure DNS. The script will create an Azure DNS zone and a wildcard certificate for *.domain.tld
.
You should make a note of the nameservers that were assigned to your new zone by running:
az network dns zone show --name <your domain> --resourcegroup <resource group> --query nameServers
Tell the parent zone where to find the DNS records for this zone by adding the corresponding NS records there. If the parent zone is running on Azure, you can do so by running the following command for each of the child name servers:
az network dns record-set ns add-record \
--zone-name <parent zone domain> \
--resource-group <parent zone resource group> \
--record-set-name <child zone> \
--nsdname <child zone nameserver>
If your parent zone is not on Azure DNS, you'll need to update the nameservers where you host the parent zone's DNS.
For example, if domain I chose is apps.azure.sabbour.me and retrieving its nameservers returns the following:
az network dns zone show --name apps.azure.sabbour.me --resource-group contoso-s2nsm --query nameServers
[
"ns1-04.azure-dns.com.",
"ns2-04.azure-dns.net.",
"ns3-04.azure-dns.org.",
"ns4-04.azure-dns.info."
]
I will then need to run the following command once for each of these nameservers on my parent zone's (azure.sabbour.me) DNS.
az network dns record-set ns add-record \
--zone-name azure.sabbour.me \
--resource-group azure.sabbour.me-rg \
--record-set-name apps \
--nsdname ns1-04.azure-dns.com. # also for ns2-04.azure-dns.net, ns3-04.azure-dns.org, ns4-04.azure-dns.info
-
Launch the Azure Cloud Shell and login with your Azure subscription.
-
Clone the frontend repository.
git clone https://github.com/sabbour/contoso-names-frontend.git
-
Change into the
contoso-names-frontend
directory and deploy the Kubernetes manifests.cd contoso-names-frontend kubectl create namespace contoso-names kubectl apply -f ./manifests --namespace=contoso-names
-
Give it a few minutes and retrieve the Kubernetes service's IP address.
kubectl get service contoso-names-frontend --namespace=contoso-names -o jsonpath="{.status.loadBalancer.ingress[0].ip}"
-
Now that you have the service's public IP address, navigate to http://[contoso-frontend IP address] in your browser. The user interface will load but you will receive an error because the backend service hasn't been deployed yet.
-
Open the service repository with GitHub Codespaces. This will fork the repository under your profile.
GitHub is going to build the codespace and in a few minutes you will be able to access it.
-
Install the latest version of the AKS Developer Tools extension, if it isn't already there.
-
Launch the command palette (
Ctrl + Shift + P
) and run theAzure: Sign in with Device Code
command to login to your Azure subscription. -
If you have access to multiple tenants, select the one you'd like to use by running the
Azure: Select Tenant
command. -
Run the
Azure: Select Subscriptions
command to select the Azure subscription you'd like to use. -
Download the AKS cluster configuration on the Kubernetes extension page by clicking the Kubernetes icon on the left, then expand your Azure subscription to find your cluster. Right-click and select Merge into Kubeconfig to download the cluster credentials.
Hit F5
to run the service in the codespace. This will build and launch the application in the codespace and tunnel the exposed endpoint back to your machine. You should now see the API endpoint.
Run the AKS Developer: Draft a Dockerfile from source code
command.
Provide the following inputs to the command:
- Source code location: Select the
/workspaces/contoso-names-service
- Programming language: C#
- C# version: 6.0
- Port: 80
This will generate an appropriate Dockerfile.
To build the container image, you can either click the Build container button in the notification, or you can also run the AKS Developer: Build a container with Azure Container Registry
command.
Provide the following inputs to the command:
- Dockerfile location: Select the
Dockerfile
file. - Tag image as:
contoso-names-service:latest
- Registry provider: Connect to an Azure registry, then pick your Azure Container Registry from the list
- Image base OS: Linux
This will run a Docker build using Azure Container Registry.
To deploy to Kubernetes, you need to have Kubernetes manifests for the deployment and service. You can either click the Draft Kubernetes Deployment and Service button in the notification, or you can also run the AKS Developer: Draft a Kubernetes Deployment and Service
command.
Provide the following inputs to the command:
- Output directory:
/workspaces/contoso-names-service/manifests
. - Format: Manifests
- Kubernetes namespace: Create a new namespace
contoso-names
and select it - Application name:
contoso-names-service
- Image type: Azure Container Registry
- Resource group: Select the resource group of the Azure Container Registry
- Container registry: Select the registry that you used to build the image
- Repository: Type in the image name
contoso-names-service
- Tag: Type in
latest
- Port: 80
This will generate deployment.yaml and service.yaml files.
Edit the service.yaml file to change the load balancer type to ClusterIP
since the frontend app will be calling this API over the internal DNS name.
To deploy to Kubernetes, you can either click the Deploy button in the notification, or you can also run the kubectl apply -f ./manifests
in the terminal.
Using the frontend app's service IP, open that in the browser again and you should see the app is now working. But there is a bug. It seems that there is some repetition in the generated names.
To debug where is this repetition in the generated name is coming from, you will use Bridge to Kubernetes to attach a debugger to the deployed application on the Kubernetes cluster. Note that you should only do this on a non-production deployment. Since this is the team's AKS development cluster, you should be ok here.
To use the Bridge to Kubernetes extension, you need to switch your Kubernetes cluster context to use the namespace which contains the service you want to debug. Click on default in the bottom tabs and type in contoso-names
in the command palette that will popup.
Launch the command palette again and run the Bridge to Kubernetes: Configure
command.
Provide the following inputs to the command:
- Service to redirect:
contoso-names-service
. - Local port: 8080
- Launch configuration: Choose the
.NET Core Launch (web)
configuration - Isolation: Choose Yes to isolate the traffic of your local version of the service from other developers on the cluster.
The extension will create a new launch configuration called .NET Core Launch (web) with Kubernetes. Make sure to switch to that configuration.
Place a breakpoint in Program.cs (line 31) and hit F5
to run the service in the codespace with the Bridge to Kubernetes debug launch configuration.
Run the Bridge to Kubernetes: Open Menu
command you should find a new option Go to contoso-names-frontend isolated show up. Click that and it will launch a browser with the isolation tag in the URL. This will allow the Bridge to Kubernetes routing manager on AKS to only route traffic to this hostname down to your code running in GitHub Codespaces.
Test the application, you should see the debugger attach and the breakpoint you placed getting hit.
You realize that you are referring to the adjective twice in the returned string. You stop the debugger and quickly fix that bug by referring to the noun the second time.
You hit F5
one more time to run your code that you just edited in GitHub Codespaces in the AKS cluster. Note that you didn't have to rebuild a Docker container, push it to a registry, or mess around with YAML files. You quickly see that your change fixes the problem.
You are now ready to commit this bug fix.
While it is fun to keep iterating on code, it is time to actually commit this bug fix, rebuild the container, and deploy a new version so that the rest of your team mates see the update.Instead of doing all this manually, you are going to use the extension to generate the GitHub Actions workflow.
Open the Azure portal, search for your AKS cluster, and open the Automated deployments blade.
Select the GitHub repository with your contoso-names-service code.
Select the Dockerfile to use as well as the Azure Container Registy name and image.
Select the Kubernetes manifest files to deploy and select the contoso-names namespace as the target Kubernetes namespace.
This will now setup the Azure Active Directory and OpenId Connect authorization required for GitHub to be able to authenticate to your AKS cluster. This will also create a pull request to include the generated GitHub Actions workflow file into the repository.
Click on View pull request to view the generated workflow on GitHub and approve the pull request.
Merge the pull request and look at the running pipeline. In a few minutes, the pipeline will run and a new image will be built and deployed to your cluster.
You will also be able to view details about the deployed workloads, including viewing live logs for pods in the portal.
You'll notice that you've been accessing the frontend over the its Kubernetes service's public IP address. Instead, you want to access this via a hostname and with an SSL/TLS certificate. Azure Kubernetes Service (AKS) provides a Web Application Routing add-on that uses nginx, integrated with Azure Key Vault for certificate storage, Azure DNS for DNS management, and Open Service Mesh (OSM) to secure intra cluster communication.
For this part, let's go ahead and configure the frontend deployment to use Web Application Routing.
-
Open the frontend repository with GitHub Codespaces. This will fork the repository under your profile.
-
As you did with the service repository previously, you'll need to install the AKS Developer Experience extension, sign-in with your Azure subscription, select the proper tenant, and download your Kubernetes cluster configuration.
-
Run the
AKS Developer: Draft a Kubernetes Ingress
command.Provide the following inputs to the command:
- Output directory:
/workspaces/contoso-names-frontend/manifests
- Port: 80
- Kubernetes namespace: Select
contoso-names
- Service:
contoso-names-frontend
- Hostname: This will be the public hostname the ingress and SSL certificate are configured with. Use the same name you used when creating the cluster.
- mTLS: Choose mutual TLS using Open Service Mesh
- Resource group: Select the resource group of the Azure Key Vault
- Key Vault: Select the Azure Key Vault holding your generated certificate
- Certificate: Choose the certificate that maps to the hostname
This will generate ingress.yaml and ingress-backend.yaml files.
- Output directory:
-
Open a terminal (
Ctrl + `
) then runkubectl apply -f ./manifests -n contoso-names
to deploy the new ingress configuration.