Introduction
Building a cloud-native environment is only part of the engineering process. A complete project also needs version-controlled implementation artifacts, a reproducible record of the work, and a deliberate cleanup strategy that prevents unused cloud resources from continuing to incur charges.
In this final mission, I published the Kubernetes manifests to GitHub, verified that the lab namespace could be removed, deleted the Azure resource group, checked the status of the associated resource groups, and removed the obsolete Kubernetes context from the local kubeconfig.
The objective was to preserve the implementation as portfolio evidence while ensuring that the temporary Azure environment was decommissioned.
What This Part Covers
- Committing the Kubernetes manifests to Git.
- Publishing the repository to GitHub.
- Verifying namespace removal.
- Deleting the Azure resource group.
- Checking that the AKS-managed resource group was removed.
- Deleting the obsolete Kubernetes context.
- Confirming what remains available after the cloud environment is deleted.
1. Review the Kubernetes Manifests
The project contains nine Kubernetes manifest files covering the workloads and resources implemented throughout the lab.
The files are organized under the manifests/ directory:
ls manifests
The output showed:
01-pod.yaml
02-deployment.yaml
03-service-clusterip.yaml
04-service-loadbalancer.yaml
05-configmap.yaml
06-statefulset.yaml
07-daemonset.yaml
08-job.yaml
09-cronjob.yaml
The manifests capture the main resources from the project:
| Manifest | Resource |
|---|---|
01-pod.yaml |
Standalone Pod |
02-deployment.yaml |
Deployment |
03-service-clusterip.yaml |
Internal ClusterIP Service |
04-service-loadbalancer.yaml |
LoadBalancer Service |
05-configmap.yaml |
ConfigMap |
06-statefulset.yaml |
Headless Service and StatefulSet with persistent storage |
07-daemonset.yaml |
DaemonSet |
08-job.yaml |
Batch Job |
09-cronjob.yaml |
Scheduled CronJob |
Keeping these resources in version control preserves the configuration used throughout the lab. The manifests provide a reference for the implementation and can be reviewed independently of the Azure environment in which they were deployed.
2. Commit the Manifests to Git
I committed the workload manifests with a message describing the implementation:
git commit -m "feat: AKS workloads (pods, deployment, services, config, statefulset, daemonset, job, cronjob)"
Git confirmed the commit:
[main 610883d] feat: AKS workloads (pods, deployment, services, config, statefulset, daemonset, job, cronjob)
9 files changed, 206 insertions(+)
The commit created the nine manifest files in the repository.
A descriptive commit message makes the change easier to identify in the project history. It also establishes a clear record of the implementation being preserved for the portfolio.
3. Configure the GitHub Remote
I configured the local repository to use the GitHub repository:
https://github.com/rahimahisah17/aks-kubernetes-lab.git
The command used was:
git remote add origin https://github.com/rahimahisah17/aks-kubernetes-lab.git 2>/dev/null || git remote set-url origin https://github.com/rahimahisah17/aks-kubernetes-lab.git
This command adds origin when it does not already exist or updates its URL when the remote has already been configured.
Using a remote allows the local Git repository to publish commits to GitHub and maintain a shared record of the implementation.
4. Push the Project to GitHub
With the remote configured, I pushed the main branch:
git push -u origin main
The command completed successfully:
Enumerating objects: 19, done.
Counting objects: 100% (19/19), done.
Compressing objects: 100% (18/18), done.
Writing objects: 100% (19/19), 3.70 KiB | 84.00 KiB/s, done.
Total 19 (delta 2), reused 0 (delta 0), pack-reused 0
To https://github.com/rahimahisah17/aks-kubernetes-lab.git
* [new branch] main -> main
branch 'main' set up to track 'origin/main'.
The push published the branch and configured it to track origin/main.
The project repository is available here:
Publishing the manifests ensures that the configuration remains accessible even after the cluster and its cloud resources have been deleted.
The repository also serves as portfolio evidence of the project implementation, including the manifest structure and version-control history.
5. Delete the Kubernetes Lab Namespace
After the GitHub push succeeded, I removed the namespace containing the lab workloads:
kubectl delete namespace k8s-lab
Kubernetes returned:
namespace "k8s-lab" deleted
I then inspected the remaining namespaces:
kubectl get namespaces
The output listed the remaining namespaces:
NAME STATUS AGE
default Active 5h9m
kube-node-lease Active 5h9m
kube-public Active 5h9m
kube-system Active 5h9m
The k8s-lab namespace was no longer present.
Deleting a namespace removes the Kubernetes resources contained in it, subject to their deletion and finalization behavior. This removed the dedicated lab namespace and its namespaced workloads from the cluster.
However, deleting a Kubernetes namespace does not itself decommission the AKS cluster or remove every Azure resource associated with it. The Azure resource group therefore needed to be deleted separately.
6. Delete the Azure Resource Group
The Azure environment used the following configuration:
RESOURCE_GROUP=rg-aks-lab
CLUSTER_NAME=aks-lab
LOCATION=westeurope
NODE_SIZE=Standard_D2s_v3
I first attempted to delete the resource group using the environment variable:
az group delete --name $RESOURCE_GROUP --yes --no-wait
The command returned an error:
argument --name/-n/--resource-group/-g: expected one argument
The variable was not populated in that shell because I switched to another terminal, so Azure CLI did not receive a resource group name.
I then supplied the resource group name explicitly:
az group delete --name rg-aks-lab --yes --no-wait
This issued the resource group deletion request.
The --yes option skips the interactive confirmation, while --no-wait returns without waiting for the deletion operation to finish. As a result, the command's return does not, on its own, establish that the resources have already disappeared.
For cleanup operations, verification is essential because Azure resource deletion can continue asynchronously after the command returns.
7. Verify the Azure Resource Group Cleanup
The AKS deployment had a primary resource group and an AKS-managed resource group. I checked for both using:
az group list --query "[?starts_with(name, 'rg-aks-lab') || starts_with(name, 'MC_rg-aks-lab')].name" --output tsv
An initial check still showed:
rg-aks-lab
MC_rg-aks-lab_aks-lab_westeurope
This indicated that the deletion process had not yet removed both resource groups from the listing.
I repeated the check after the deletion process had progressed:
az group list --query "[?starts_with(name, 'rg-aks-lab') || starts_with(name, 'MC_rg-aks-lab')].name" --output tsv
The subsequent output was empty, confirming that neither matching resource group remained in the returned list.
The verification covered both the main lab resource group and the resource group created by AKS to manage supporting infrastructure.
This distinction matters because AKS can create Azure resources outside the visible workload definitions in the Kubernetes manifests. A complete cleanup check should account for the managed infrastructure, rather than checking only the primary resource group.
8. Remove the Obsolete Kubernetes Context
With the AKS environment decommissioned, I removed its local Kubernetes context:
kubectl config delete-context aks-lab
The command returned:
warning: this removed your active context, use "kubectl config use-context" to select a different one
deleted context aks-lab from /home/rahimahisah/.kube/config
The context had stored the connection configuration used by kubectl to access the aks-lab cluster.
Removing it cleans up the local kubeconfig after the cluster has been deleted. The warning also notes that the removed context had been active, so another context would need to be selected before using kubectl against a different cluster.
This step removes the local connection entry; it does not delete the local repository, manifests, or GitHub project.
9. What Remains After Cleanup?
The cleanup separates the cloud environment from the project artifacts.
| Component | Final state |
|---|---|
k8s-lab namespace |
Deleted |
Main Azure resource group rg-aks-lab
|
No longer present in the verification listing |
| AKS-managed resource group | No longer present in the verification listing |
Local aks-lab kubeconfig context |
Deleted |
| Local project directory | Preserved |
| Kubernetes YAML manifests | Preserved locally |
| Git commit history | Preserved in the repository |
| GitHub repository | Published and available |
This separation is important for cloud labs. The resources used to demonstrate the implementation can be removed without discarding the configuration, documentation, and version-control history that make the work reproducible and useful as portfolio evidence.
Although the Azure resource groups were removed from the verification listing, the final Azure bill remains the authoritative source for confirming any outstanding or previously accrued charges. Deletion stops the continued use of the deleted resources, but it does not erase charges already incurred.
10. Operational Takeaways
This final mission brought together version control, cloud resource lifecycle management, and verification.
The main takeaways were:
- Version-controlled infrastructure: Kubernetes manifests provide a durable record of the resource configuration used in the lab.
- Repository publishing: Pushing the project to GitHub preserves the implementation beyond the lifetime of the AKS cluster.
- Namespace cleanup: Removing the lab namespace deletes its dedicated Kubernetes workloads and resources.
- Azure resource cleanup: Deleting the primary resource group initiates removal of the cluster and related Azure resources.
-
Asynchronous deletion: Commands using
--no-waitrequire a separate verification step to confirm the resources have disappeared. - Managed-resource awareness: AKS can create a separate managed resource group that should be included in cleanup verification.
- Local configuration hygiene: Removing an obsolete kubeconfig context prevents local configuration from retaining an unnecessary connection entry.
- Cost awareness: Cloud cleanup should be verified rather than assumed, and actual billed amounts should be checked independently.
Conclusion: From Cluster Provisioning to Decommissioning
The nine-part series brought together AKS provisioning, Kubernetes workloads, networking, configuration, persistent storage, batch processing, scheduled automation, and cost optimization.
In this final mission, I committed the nine workload manifests, pushed the project to GitHub, deleted the k8s-lab namespace, issued the Azure resource group deletion request, verified that the primary and AKS-managed resource groups were no longer listed, and removed the obsolete Kubernetes context.
The result is a preserved project repository without the temporary cloud infrastructure used to run it.
The central operational principle is straightforward: infrastructure work is not complete until its implementation has been preserved and its temporary resources have been deliberately decommissioned. Version-controlled manifests retain the engineering evidence, while verified cleanup helps prevent unnecessary ongoing resource consumption.
This article is Part 9 of the nine-part series, “Kubernetes on AKS: From Zero to Production Workloads.”








Top comments (1)
A successful cloud project should demonstrate not only how infrastructure is deployed, but also how it is maintained, documented, and safely decommissioned. This final mission brings the full workflow together: preserving Kubernetes manifests in GitHub, verifying Azure resource cleanup, and removing obsolete local cluster configuration. The infrastructure may be deleted, but the repository remains as portfolio evidence of the implementation. A clean teardown is part of responsible cloud engineering.