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 (for web app routing)
-
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
Provide the following inputs to the command:
- Location (default: eastus): Azure region to deploy the resources.
- Resource group (default: <random>-rg): Resource group name to host the resources
- Root Azure DNS name (default: <random>.contoso.com): Root Azure DNS zone. Will be created if it doesn't exist.
- Root Azure DNS resource group (default: <random>-rg): Existing Root Azure DNS zone resource group. If the Root Azure DNS zone doesn't exist, it will be created in the main resource group.
- Application subdomain name (default namesapp): Subdomain for this application.
This will take about 10 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 certificate for domain.tld
and *.domain.tld
. External-DNS on Kubernetes will create and manage any additional subdomains on that zone.
You should make a note of the nameservers that were assigned to your new zone by running the command below and updating your parent zone's nameservers.
az network dns zone show --name <your domain> --resourcegroup <resource group> --query nameServers
-
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 --namespace=contoso-names
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.
Learn more about how the magic behind Bridge to Kubernetes works.
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.
- Service mesh: For simplicity, choose No 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: Paste the Key Vault certificate URL that was displayed at the end of the setup script
This will generate an ingress.yaml file.
- Output directory:
-
Open a terminal (
Ctrl + `
) then runkubectl apply -f ./manifests --namespace=contoso-names
to deploy the new ingress configuration. -
In a few minutes, the external-dns controller that was deployed with the Web Application Routing add-on will synchronize the requested ingress hostname with Azure DNS.
-
You should now be able to access the application at the hostname you configured, for example at https://namesapp.azure.sabbour.me over the self-signed SSL certificate that was generated when you created the cluster. You can also upload your own SSL certificate into Azure Key Vault.
Additionlly, you can still debug through Bridge to Kubernetes in isolation mode by appending your isloation tag to the hostname, for exapmle at https://vscode-dff0.namesapp.azure.sabbour.me
When you are done, you can delete the resource group that is holding the resources by running:
az group delete --name <resource group name>