├── .gitignore ├── 00-Pre-requisites └── README.md ├── 01-Create-AKS-Cluster ├── README.md └── kube-manifests │ ├── 01-Deployment.yml │ └── 02-LoadBalancer.yml ├── 02-Docker-Fundamentals └── README.md ├── 03-Kubernetes-Fundamentals-with-kubectl ├── 03-01-PODs-with-kubectl │ └── README.md ├── 03-02-ReplicaSets-with-kubectl │ ├── README.md │ └── replicaset-demo.yml ├── 03-03-Deployments-with-kubectl │ ├── 03-03-01-CreateDeployment-Scaling-and-Expose-as-Service │ │ └── README.md │ ├── 03-03-02-Update-Deployment │ │ └── README.md │ ├── 03-03-03-Rollback-Deployment │ │ └── README.md │ ├── 03-03-04-Pause-and-Resume-Deployment │ │ └── README.md │ └── README.md ├── 03-04-Services-with-kubectl │ └── README.md └── README.md ├── 04-Kubernetes-Fundamentals-with-YAML ├── 04-01-YAML-Basics │ ├── README.md │ └── sample-file.yml ├── 04-02-PODs-with-YAML │ ├── README.md │ └── kube-manifests │ │ ├── 01-kube-base-definition.yml │ │ ├── 02-pod-definition.yml │ │ └── 03-pod-LoadBalancer-service.yml ├── 04-03-ReplicaSets-with-YAML │ ├── README.md │ └── kube-manifests │ │ ├── 01-kube-base-definition.yml │ │ ├── 02-replicaset-definition.yml │ │ └── 03-replicaset-LoadBalancer-servie.yml ├── 04-04-Deployments-with-YAML │ ├── README.md │ └── kube-manifests │ │ ├── 01-kube-base-definition.yml │ │ ├── 02-deployment-definition.yml │ │ └── 03-deployment-LoadBalancer-servie.yml └── 04-05-Services-with-YAML │ ├── README.md │ └── kube-manifests │ ├── 00-kube-base-definition.yml │ ├── 01-backend-deployment.yml │ ├── 02-backend-clusterip-service.yml │ ├── 03-frontend-deployment.yml │ └── 04-frontend-LoadBalancer-service.yml ├── 05-Azure-Disks-for-AKS-Storage ├── 05-01-SC-PVC-ConfigMap-MySQL │ ├── README.md │ └── kube-manifests │ │ ├── 01-storage-class.yml │ │ ├── 02-persistent-volume-claim.yml │ │ ├── 03-UserManagement-ConfigMap.yml │ │ ├── 04-mysql-deployment.yml │ │ └── 05-mysql-clusterip-service.yml ├── 05-02-PVC-ConfigMap-MySQL │ ├── README.md │ └── kube-manifests │ │ ├── 01-persistent-volume-claim.yml │ │ ├── 02-UserManagement-ConfigMap.yml │ │ ├── 03-mysql-deployment.yml │ │ └── 04-mysql-clusterip-service.yml ├── 05-03-UserMgmt-WebApp-with-MySQLDB │ ├── README.md │ └── kube-manifests │ │ ├── 01-storage-class.yml │ │ ├── 02-persistent-volume-claim.yml │ │ ├── 03-UserManagement-ConfigMap.yml │ │ ├── 04-mysql-deployment.yml │ │ ├── 05-mysql-clusterip-service.yml │ │ ├── 06-UserMgmtWebApp-Deployment.yml │ │ └── 07-UserMgmtWebApp-Service.yml └── README.md ├── 06-Azure-MySQL-for-AKS-Storage ├── README.md └── kube-manifests │ ├── 01-MySQL-externalName-Service.yml │ ├── 02-UserMgmtWebApp-Deployment.yml │ └── 03-UserMgmtWebApp-Service.yml ├── 07-Kubernetes-Secrets ├── README.md └── kube-manifests │ ├── 01-storage-class.yml │ ├── 02-persistent-volume-claim.yml │ ├── 03-UserManagement-ConfigMap.yml │ ├── 04-mysql-deployment.yml │ ├── 05-mysql-clusterip-service.yml │ ├── 06-UserMgmtWebApp-Deployment.yml │ ├── 07-UserMgmtWebApp-Service.yml │ └── 08-Kubernetes-Secrets.yml ├── 08-Azure-Files-for-AKS-Storage ├── README.md ├── kube-manifests-v1 │ ├── 01-Storage-Class.yml │ ├── 02-Persistent-Volume-Claim.yml │ ├── 03-Nginx-Deployment.yml │ └── 04-Nginx-Service.yml ├── kube-manifests-v2 │ ├── 01-Persistent-Volume-Claim.yml │ ├── 02-Nginx-Deployment.yml │ └── 03-Nginx-Service.yml └── nginx-files │ ├── file1.html │ └── file2.html ├── 09-Ingress-Basic ├── FOR-Review-purpose-azure-nginx-ingress-controller-deploy.yml ├── FOR-Review-purpose-values.yml ├── README.md └── kube-manifests │ ├── 01-NginxApp1-Deployment.yml │ ├── 02-NginxApp1-ClusterIP-Service.yml │ └── 03-Ingress-Basic.yml ├── 10-Ingress-Context-Path-Based-Routing ├── README.md └── kube-manifests │ ├── 01-NginxApp1-Manifests │ ├── 01-NginxApp1-Deployment.yml │ └── 02-NginxApp1-ClusterIP-Service.yml │ ├── 02-NginxApp2-Manifets │ ├── 01-NginxApp2-Deployment.yml │ └── 02-NginxApp2-ClusterIP-Service.yml │ ├── 03-UserMgmtWebApp-Manifests │ ├── 01-persistent-volume-claim.yml │ ├── 02-UserManagement-ConfigMap.yml │ ├── 03-mysql-deployment.yml │ ├── 04-mysql-clusterip-service.yml │ ├── 05-UserMgmtWebApp-Deployment.yml │ ├── 06-UserMgmtWebApp-Service.yml │ └── 07-Kubernetes-Secrets.yml │ └── 04-IngressService-Manifests │ └── 01-Ingress-Context-Path-Based-Routing.yml ├── 11-Delegate-Domain-from-AWS-Route53-to-Azure-DNS └── README.md ├── 12-ExternalDNS-for-AzureDNS-on-AKS ├── README.md └── kube-manifests │ ├── 01-ExternalDNS │ ├── azure.json │ └── external-dns.yml │ └── 02-NginxApp1 │ ├── 01-NginxApp1-Deployment.yml │ ├── 02-NginxApp1-ClusterIP-Service.yml │ └── 03-Ingress-with-ExternalDNS.yml ├── 13-Ingress-ExternalDNS-Domain-Name-Based-Routing ├── README.md └── kube-manifests │ ├── 01-NginxApp1-Manifests │ ├── 01-NginxApp1-Deployment.yml │ └── 02-NginxApp1-ClusterIP-Service.yml │ ├── 02-NginxApp2-Manifets │ ├── 01-NginxApp2-Deployment.yml │ └── 02-NginxApp2-ClusterIP-Service.yml │ ├── 03-UserMgmtWebApp-Manifests │ ├── 01-persistent-volume-claim.yml │ ├── 02-UserManagement-ConfigMap.yml │ ├── 03-mysql-deployment.yml │ ├── 04-mysql-clusterip-service.yml │ ├── 05-UserMgmtWebApp-Deployment.yml │ ├── 06-UserMgmtWebApp-Service.yml │ └── 07-Kubernetes-Secrets.yml │ └── 04-IngressService-Manifests │ └── 01-Ingress-DomainName-Based-Routing-app1-2-3.yml ├── 14-Ingress-SSL-with-LetsEncrypt ├── README.md └── kube-manifests │ ├── 01-CertManager-ClusterIssuer │ └── cluster-issuer.yml │ ├── 02-Demo-Applications │ ├── 01-NginxApp1-Deployment.yml │ ├── 02-NginxApp1-ClusterIP-Service.yml │ ├── 03-NginxApp2-Deployment.yml │ └── 04-NginxApp2-ClusterIP-Service.yml │ └── 03-Ingress-SSL-Resource │ └── 01-Ingress-SSL.yml ├── 15-Kubernetes-Requests-Limits ├── README.md ├── kube-manifests-v1 │ ├── 01-NginxApp1-Deployment.yml │ └── 02-NginxApp1-LoadBalancer-Service.yml └── kube-manifests-v2 │ ├── 01-persistent-volume-claim.yml │ ├── 02-UserManagement-ConfigMap.yml │ ├── 03-mysql-deployment.yml │ ├── 04-mysql-clusterip-service.yml │ ├── 05-UserMgmtWebApp-Deployment.yml │ ├── 06-UserMgmtWebApp-Service.yml │ └── 07-Kubernetes-Secrets.yml ├── 16-Kubernetes-Namespaces ├── 16-01-Namespaces-Imperative │ ├── README.md │ └── kube-manifests │ │ ├── 01-NginxApp1-Deployment.yml │ │ └── 02-NginxApp1-LoadBalancer-Service.yml ├── 16-02-Namespaces-LimitRange-default │ ├── README.md │ └── kube-manifests │ │ ├── 00-namespace-LimitRange-default.yml │ │ ├── 01-NginxApp1-Deployment.yml │ │ └── 02-NginxApp1-LoadBalancer-Service.yml ├── 16-03-Namespaces-ResourceQuota │ ├── README.md │ └── kube-manifests │ │ ├── 00-namespace-LimitRange-ResourceQuota.yml │ │ ├── 01-NginxApp1-Deployment.yml │ │ └── 02-NginxApp1-LoadBalancer-Service.yml └── README.md ├── 17-Azure-VirtualNodes-for-AKS ├── 17-01-Azure-VirtualNodes-Basics │ ├── README.md │ └── kube-manifests │ │ ├── 01-NginxApp1-Deployment.yml │ │ └── 02-NginxApp1-LoadBalancer-Service.yml ├── 17-02-Azure-VirtualNodes-MixedMode-Deployments │ ├── README.md │ └── kube-manifests │ │ ├── 01-persistent-volume-claim.yml │ │ ├── 02-UserManagement-ConfigMap.yml │ │ ├── 03-Kubernetes-Secrets.yml │ │ ├── 04-mysql-deployment.yml │ │ ├── 05-mysql-clusterip-service.yml │ │ ├── 06-UserMgmtWebApp-Deployment.yml │ │ └── 07-UserMgmtWebApp-Service.yml └── README.md ├── 18-Azure-Container-Registry-ACR ├── 18-01-ACR-attach-to-AKS │ ├── README.md │ ├── docker-manifests │ │ ├── Dockerfile │ │ └── index.html │ └── kube-manifests │ │ ├── 01-acr-Deployment.yml │ │ └── 02-acr-LoadBalancer-Service.yml ├── 18-02-ACR-not-attached-to-AKS-Schedule-to-NodePools │ ├── README.md │ ├── docker-manifests │ │ ├── Dockerfile │ │ └── index.html │ ├── kube-manifests │ │ ├── 01-acr-Deployment.yml │ │ └── 02-acr-LoadBalancer-Service.yml │ └── shell-script │ │ └── generate-service-principal.sh ├── 18-03-ACR-not-attached-to-AKS-Schedule-to-VirtualNodes │ ├── README.md │ ├── docker-manifests │ │ ├── Dockerfile │ │ └── index.html │ └── kube-manifests │ │ ├── 01-acr-Deployment.yml │ │ └── 02-acr-LoadBalancer-Service.yml └── README.md ├── 19-Azure-DevOps-with-AKS ├── 19-01-Azure-DevOps-BuildandPush-to-ACR │ ├── 01-build-pipeline.yml │ ├── Git-Repository-files │ │ ├── Dockerfile │ │ ├── index.html │ │ └── kube-manifests │ │ │ └── 01-Deployment-and-LoadBalancer-Service.yml │ └── README.md ├── 19-02-Azure-DevOps-Deploy-to-AKS │ ├── 02-buildpush-to-acr-deploy-to-aks.yml │ └── README.md ├── 19-03-Azure-DevOps-Build-Pipeline-Publish-Artifacts │ ├── 03-custom1-pipeline-buildandpush-to-acr-and-publish-artifacts.yml │ ├── 04-custom2-pipeline-build-from-scratch.yml │ ├── README.md │ └── sample.yml └── 19-04-Azure-DevOps-Release-Pipelines │ └── README.md ├── 20-Azure-AKS-HTTP-Application-Routing ├── README.md └── kube-manifests │ ├── 01-NginxApp1-Deployment.yml │ ├── 02-NginxApp1-ClusterIP-Service.yml │ └── 03-Ingress-HTTPApplicationRouting-ExternalDNS.yml ├── 21-Azure-AKS-Authentication-and-RBAC ├── 21-01-AKS-Cluster-Access-Multiple-Clusters │ └── README.md ├── 21-02-AzureAD-Authentication-for-AKS-Admins │ └── README.md ├── 21-03-Kubernetes-RBAC-with-AzureAD-on-AzureAKS │ ├── README.md │ └── kube-manifests │ │ ├── 01-Sample-Application │ │ ├── 01-NginxApp1-Deployment.yml │ │ └── 02-NginxApp1-LoadBalancer-Service.yml │ │ └── 02-Roles-and-RoleBindings │ │ ├── role-dev-namespace.yaml │ │ └── rolebinding-dev-namespace.yaml └── 21-04-Kubernetes-RBAC-ClusterRole-ClusterRoleBinding │ ├── README.md │ └── kube-manifests │ ├── ClusterRole-ReadOnlyAccess.yaml │ └── ClusterRoleBinding-ReadOnlyAccess.yaml ├── 22-Azure-AKS-Autoscaling ├── 22-01-Azure-AKS-Cluster-Autoscaler │ ├── README.md │ └── kube-manifests │ │ └── 01-javaapp-Deployment-Service.yml └── 22-02-Azure-AKS-HPA-Horizontal-Pod-Autoscaler │ ├── README.md │ └── kube-manifests │ ├── apps │ └── 01-nginx-app.yml │ └── hpa-manifest │ └── hpa-manifest.yml ├── 23-AKS-Production-Grade-Cluster-Design-using-az-aks-cli ├── 23-01-Create-AKSCluster-with-az-aks-cli │ ├── README.md │ ├── az-aks-create-man-page.txt │ └── create-cluster-outout-for-reference.txt ├── 23-02-Create-Linux-Windows-Virtual-NodePools │ └── README.md └── 23-03-k8s-NodeSelectors-Deploy-Apps-Windows-Linux │ ├── README.md │ └── kube-manifests │ ├── 01-Webserver-Apps │ ├── 01-NginxApp1-Deployment.yml │ └── 02-NginxApp1-LoadBalancer-Service.yml │ ├── 02-Java-Apps │ ├── 00-storage-class.yml │ ├── 01-persistent-volume-claim.yml │ ├── 02-UserManagement-ConfigMap.yml │ ├── 03-mysql-deployment.yml │ ├── 04-mysql-clusterip-service.yml │ ├── 06-UserMgmtWebApp-Deployment.yml │ └── 07-UserMgmtWebApp-Service.yml │ ├── 03-Windows-DotNet-Apps │ ├── 01-windows-app-deployment.yml │ └── 02-windows-app-loadbalancer-service.yml │ └── 04-VirtualNode-Apps │ ├── 01-NginxVnode-Deployment.yml │ └── 02-NginxVnode-LoadBalancer-Service.yml ├── 24-Azure-AKS-Terraform ├── 24-01-Terraform-Commands-Basics │ ├── README.md │ ├── v1-terraform-azurerm-provider │ │ └── main.tf │ └── v2-terraform-azurerm-resource-group │ │ └── main.tf ├── 24-02-Terraform-Language-Basics │ ├── README.md │ └── terraform-manifests-aks │ │ ├── 01-main.tf │ │ ├── 02-variables.tf │ │ ├── 03-resource-group.tf │ │ └── 08-outputs.tf ├── 24-03-Create-AKS-Cluster │ ├── README.md │ └── terraform-manifests-aks │ │ ├── 01-main.tf │ │ ├── 02-variables.tf │ │ ├── 03-resource-group.tf │ │ ├── 04-aks-versions-datasource.tf │ │ ├── 05-log-analytics-workspace.tf │ │ ├── 06-aks-administrators-azure-ad.tf │ │ ├── 07-aks-cluster.tf │ │ └── 08-outputs.tf ├── 24-04-Create-AKS-NodePools-using-Terraform │ ├── README.md │ ├── kube-manifests │ │ ├── 01-Webserver-Apps │ │ │ ├── 01-NginxApp1-Deployment.yml │ │ │ └── 02-NginxApp1-LoadBalancer-Service.yml │ │ ├── 02-Java-Apps │ │ │ ├── 00-storage-class.yml │ │ │ ├── 01-persistent-volume-claim.yml │ │ │ ├── 02-UserManagement-ConfigMap.yml │ │ │ ├── 03-mysql-deployment.yml │ │ │ ├── 04-mysql-clusterip-service.yml │ │ │ ├── 06-UserMgmtWebApp-Deployment.yml │ │ │ └── 07-UserMgmtWebApp-Service.yml │ │ └── 03-Windows-DotNet-Apps │ │ │ ├── 01-windows-app-deployment.yml │ │ │ └── 02-windows-app-loadbalancer-service.yml │ └── terraform-manifests-aks │ │ ├── 01-main.tf │ │ ├── 02-variables.tf │ │ ├── 03-resource-group.tf │ │ ├── 04-aks-versions-datasource.tf │ │ ├── 05-log-analytics-workspace.tf │ │ ├── 06-aks-administrators-azure-ad.tf │ │ ├── 07-aks-cluster.tf │ │ ├── 08-outputs.tf │ │ ├── 09-aks-cluster-linux-user-nodepools.tf │ │ └── 10-aks-cluster-windows-user-nodepools.tf └── 24-05-Create-AKS-Cluster-Custom-VNET │ ├── README.md │ ├── kube-manifests │ ├── 01-Webserver-Apps │ │ ├── 01-NginxApp1-Deployment.yml │ │ └── 02-NginxApp1-LoadBalancer-Service.yml │ ├── 02-Java-Apps │ │ ├── 00-storage-class.yml │ │ ├── 01-persistent-volume-claim.yml │ │ ├── 02-UserManagement-ConfigMap.yml │ │ ├── 03-mysql-deployment.yml │ │ ├── 04-mysql-clusterip-service.yml │ │ ├── 06-UserMgmtWebApp-Deployment.yml │ │ └── 07-UserMgmtWebApp-Service.yml │ └── 03-Windows-DotNet-Apps │ │ ├── 01-windows-app-deployment.yml │ │ └── 02-windows-app-loadbalancer-service.yml │ └── terraform-manifests-aks-custom-vnet │ ├── 01-main.tf │ ├── 02-variables.tf │ ├── 03-resource-group.tf │ ├── 04-aks-versions-datasource.tf │ ├── 05-log-analytics-workspace.tf │ ├── 06-aks-administrators-azure-ad.tf │ ├── 07-aks-cluster.tf │ ├── 08-outputs.tf │ ├── 09-aks-cluster-linux-user-nodepools.tf │ ├── 10-aks-cluster-windows-user-nodepools.tf │ └── 11-virtual-network.tf ├── 25-Azure-DevOps-Terraform-Azure-AKS ├── Git-Repo-Files │ ├── README.md │ ├── kube-manifests │ │ ├── 01-Webserver-Apps │ │ │ ├── 01-NginxApp1-Deployment.yml │ │ │ └── 02-NginxApp1-LoadBalancer-Service.yml │ │ ├── 02-Java-Apps │ │ │ ├── 00-storage-class.yml │ │ │ ├── 01-persistent-volume-claim.yml │ │ │ ├── 02-UserManagement-ConfigMap.yml │ │ │ ├── 03-mysql-deployment.yml │ │ │ ├── 04-mysql-clusterip-service.yml │ │ │ ├── 06-UserMgmtWebApp-Deployment.yml │ │ │ └── 07-UserMgmtWebApp-Service.yml │ │ └── 03-Windows-DotNet-Apps │ │ │ ├── 01-windows-app-deployment.yml │ │ │ └── 02-windows-app-loadbalancer-service.yml │ ├── pipeline-backups │ │ ├── 01-terraform-provision-aks-cluster-pipeline.yml │ │ └── pipeline-inputs.txt │ └── terraform-manifests │ │ ├── 01-main.tf │ │ ├── 02-variables.tf │ │ ├── 03-resource-group.tf │ │ ├── 04-aks-versions-datasource.tf │ │ ├── 05-log-analytics-workspace.tf │ │ ├── 06-aks-administrators-azure-ad.tf │ │ ├── 07-aks-cluster.tf │ │ ├── 08-outputs.tf │ │ ├── 09-aks-cluster-linux-user-nodepools.tf │ │ ├── 10-aks-cluster-windows-user-nodepools.tf │ │ └── 11-aks-cluster-linux102-user-nodepools.tf └── README.md ├── README.md ├── git-deploy.sh └── ppt-presentation ├── Azure-AKS-Kubernetes-Masterclass-V16.pdf └── Azure-AKS-Kubernetes-Masterclass-V16.pptx /.gitignore: -------------------------------------------------------------------------------- 1 | /ADDITIONAL-TOPICS 2 | /FUTURE-TOPICS 3 | #.gitignore 4 | 5 | # macOS Files 6 | .DS_Store 7 | 8 | # Ignore .sh files 9 | #*.sh 10 | 11 | # Terraform Files and Folders 12 | .terraform 13 | *.tfstate 14 | *.tfstate.backup 15 | *.tfvars 16 | -------------------------------------------------------------------------------- /00-Pre-requisites/README.md: -------------------------------------------------------------------------------- 1 | # Pre-requisites 2 | 1. Azure Cloud Subscription 3 | 2. Course Github Repositories 4 | 5 | ## Step-01: Azure Cloud Subscription 6 | - [Azure Free Account](https://azure.microsoft.com/en-in/free/) 7 | - 200 dollar credit for first 30 days 8 | 9 | ## Step-02: Fork Course Github Repositories 10 | - [Azure Kubernetes Service with Azure DevOps and Terraform](https://github.com/stacksimplify/azure-aks-kubernetes-masterclass) 11 | - [Azure DevOps for Kubernetes Workloads running on Azure AKS Cluster](https://github.com/stacksimplify/azure-devops-github-acr-aks-app1) 12 | - [Provision Azure AKS Cluster using Terraform and Azure DevOps](https://github.com/stacksimplify/azure-devops-aks-kubernetes-terraform-pipeline) 13 | - [Docker Fundamentals](https://github.com/stacksimplify/docker-fundamentals) 14 | - [Presentation with 250 Slides outlining the various architectures and designs we are going to do in this course](https://github.com/stacksimplify/azure-aks-kubernetes-masterclass/tree/master/ppt-presentation) 15 | - **Important Note:** Please go to these repositories and FORK these repositories and make use of them during the course. 16 | -------------------------------------------------------------------------------- /01-Create-AKS-Cluster/kube-manifests/01-Deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: myapp1-deployment 5 | spec: 6 | replicas: 2 7 | selector: 8 | matchLabels: 9 | app: myapp1 10 | template: 11 | metadata: # Dictionary 12 | name: myapp1-pod 13 | labels: # Dictionary 14 | app: myapp1 15 | spec: 16 | containers: # List 17 | - name: myapp1-container 18 | image: stacksimplify/kubenginx:1.0.0 19 | ports: 20 | - containerPort: 80 21 | 22 | 23 | -------------------------------------------------------------------------------- /01-Create-AKS-Cluster/kube-manifests/02-LoadBalancer.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: myapp1-loadbalancer 5 | labels: 6 | app: myapp1 7 | spec: 8 | type: LoadBalancer 9 | selector: 10 | app: myapp1 11 | ports: 12 | - port: 80 13 | targetPort: 80 14 | -------------------------------------------------------------------------------- /02-Docker-Fundamentals/README.md: -------------------------------------------------------------------------------- 1 | # Docker Fundamentals 2 | - For Docker Fundamentals github repository, please click on below link 3 | - https://github.com/stacksimplify/docker-fundamentals -------------------------------------------------------------------------------- /03-Kubernetes-Fundamentals-with-kubectl/03-02-ReplicaSets-with-kubectl/replicaset-demo.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: ReplicaSet 3 | metadata: 4 | name: my-helloworld-rs 5 | labels: 6 | app: my-helloworld 7 | spec: 8 | replicas: 6 9 | selector: 10 | matchLabels: 11 | app: my-helloworld 12 | template: 13 | metadata: 14 | labels: 15 | app: my-helloworld 16 | spec: 17 | containers: 18 | - name: my-helloworld-app 19 | image: stacksimplify/kube-helloworld:1.0.0 20 | -------------------------------------------------------------------------------- /03-Kubernetes-Fundamentals-with-kubectl/03-03-Deployments-with-kubectl/03-03-01-CreateDeployment-Scaling-and-Expose-as-Service/README.md: -------------------------------------------------------------------------------- 1 | # Kubernetes - Deployment 2 | 3 | ## Step-01: Introduction to Deployments 4 | - What is a Deployment? 5 | - What all we can do using Deployment? 6 | - Create a Deployment 7 | - Scale the Deployment 8 | - Expose the Deployment as a Service 9 | 10 | ## Step-02: Create Deployment 11 | - Create Deployment to rollout a ReplicaSet 12 | - Verify Deployment, ReplicaSet & Pods 13 | - **Docker Image Location:** https://hub.docker.com/repository/docker/stacksimplify/kubenginx 14 | ``` 15 | # Create Deployment 16 | kubectl create deployment --image= 17 | kubectl create deployment my-first-deployment --image=stacksimplify/kubenginx:1.0.0 18 | 19 | # Verify Deployment 20 | kubectl get deployments 21 | kubectl get deploy 22 | 23 | # Describe Deployment 24 | kubectl describe deployment 25 | kubectl describe deployment my-first-deployment 26 | 27 | # Verify ReplicaSet 28 | kubectl get rs 29 | 30 | # Verify Pod 31 | kubectl get po 32 | ``` 33 | ## Step-03: Scaling a Deployment 34 | - Scale the deployment to increase the number of replicas (pods) 35 | ``` 36 | # Scale Up the Deployment 37 | kubectl scale --replicas=10 deployment/ 38 | kubectl scale --replicas=10 deployment/my-first-deployment 39 | 40 | # Verify Deployment 41 | kubectl get deploy 42 | 43 | # Verify ReplicaSet 44 | kubectl get rs 45 | 46 | # Verify Pods 47 | kubectl get po 48 | 49 | # Scale Down the Deployment 50 | kubectl scale --replicas=2 deployment/my-first-deployment 51 | kubectl get deploy 52 | ``` 53 | 54 | ## Step-04: Expose Deployment as a Service 55 | - Expose **Deployment** with a service (LoadBalancer Service) to access the application externally (from internet) 56 | ``` 57 | # Expose Deployment as a Service 58 | kubectl expose deployment --type=LoadBalancer --port=80 --target-port=80 --name= 59 | kubectl expose deployment my-first-deployment --type=LoadBalancer --port=80 --target-port=80 --name=my-first-deployment-service 60 | 61 | # Get Service Info 62 | kubectl get svc 63 | 64 | ``` 65 | - **Access the Application using Public IP** 66 | ``` 67 | http:// 68 | ``` -------------------------------------------------------------------------------- /03-Kubernetes-Fundamentals-with-kubectl/03-03-Deployments-with-kubectl/README.md: -------------------------------------------------------------------------------- 1 | # Kubernetes - Deployment 2 | 3 | ## Topics 4 | 1. Create Deployment 5 | 2. Scale the Deployment 6 | 3. Expose Deployment as a Service 7 | 4. Update Deployment 8 | 5. Rollback Deployment 9 | 6. Rolling Restarts 10 | 7. Pause & Resume Deployments 11 | 8. Canary Deployments (Will be covered at Declarative section of Deployments) 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /03-Kubernetes-Fundamentals-with-kubectl/README.md: -------------------------------------------------------------------------------- 1 | # Kubernetes Fundaments using Imperative Approach using kubectl 2 | 3 | 4 | | S.No | Topic Name | 5 | | ------| ------------- | 6 | | 01. | Pods | 7 | | 02. | ReplicaSets | 8 | | 03. | Deployments | 9 | | 04. | Services | -------------------------------------------------------------------------------- /04-Kubernetes-Fundamentals-with-YAML/04-01-YAML-Basics/README.md: -------------------------------------------------------------------------------- 1 | # YAML Basics 2 | 3 | ## Step-01: Comments & Key Value Pairs 4 | - Space after colon is mandatory to differentiate key and value 5 | ```yml 6 | # Defining simple key value pairs 7 | name: kalyan 8 | age: 23 9 | city: Hyderabad 10 | ``` 11 | 12 | ## Step-02: Dictionary / Map 13 | - Set of properties grouped together after an item 14 | - Equal amount of blank space required for all the items under a dictionary 15 | ```yml 16 | person: 17 | name: kalyan 18 | age: 23 19 | city: Hyderabad 20 | ``` 21 | 22 | ## Step-03: Array / Lists 23 | - Dash indicates an element of an array 24 | ```yml 25 | person: # Dictionary 26 | name: kalyan 27 | age: 23 28 | city: Hyderabad 29 | hobbies: # List 30 | - cycling 31 | - cookines 32 | hobbies: [cycling, cooking] # List with a differnt notation 33 | ``` 34 | 35 | ## Step-04: Multiple Lists 36 | - Dash indicates an element of an array 37 | ```yml 38 | person: # Dictionary 39 | name: kalyan 40 | age: 23 41 | city: Hyderabad 42 | hobbies: # List 43 | - cycling 44 | - cooking 45 | hobbies: [cycling, cooking] # List with a differnt notation 46 | friends: # 47 | - name: friend1 48 | age: 22 49 | - name: friend2 50 | age: 25 51 | ``` 52 | 53 | 54 | ## Step-05: Sample Pod Tempalte for Reference 55 | ```yml 56 | apiVersion: v1 # String 57 | kind: Pod # String 58 | metadata: # Dictionary 59 | name: myapp-pod 60 | labels: # Dictionary 61 | app: myapp 62 | spec: 63 | containers: # List 64 | - name: myapp 65 | image: stacksimplify/kubenginx:1.0.0 66 | ports: 67 | - containerPort: 80 68 | protocol: "TCP" 69 | - containerPort: 81 70 | protocol: "TCP" 71 | ``` 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /04-Kubernetes-Fundamentals-with-YAML/04-01-YAML-Basics/sample-file.yml: -------------------------------------------------------------------------------- 1 | # Simple Key value Pairs 2 | person: # Dictionary 3 | name: kalyan 4 | age: 23 5 | city: Hyderabd 6 | hobbies: # List 7 | - cooking 8 | - cycling 9 | friends: # Multiple lists 10 | - name: friend1 11 | age: 23 12 | - name: friend2 13 | age: 22 14 | --- # YAML Document Separator 15 | apiVersion: v1 # String 16 | kind: Pod # String 17 | metadata: # Dictionary 18 | name: myapp-pod 19 | labels: # Dictionary 20 | app: myapp 21 | tier: frontend 22 | spec: 23 | containers: # List 24 | - name: myapp 25 | image: stacksimplify/kubenginx:1.0.0 26 | ports: # List 27 | - containerPort: 80 28 | protocol: "TCP" 29 | - containerPort: 81 30 | protocol: "TCP" 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /04-Kubernetes-Fundamentals-with-YAML/04-02-PODs-with-YAML/README.md: -------------------------------------------------------------------------------- 1 | # PODs with YAML 2 | ## Step-01: Kubernetes YAML Top level Objects 3 | - Discuss about the k8s YAML top level objects 4 | - **01-kube-base-definition.yml** 5 | ```yml 6 | apiVersion: 7 | kind: 8 | metadata: 9 | 10 | spec: 11 | ``` 12 | - [Pod API Objects Reference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#pod-v1-core) 13 | 14 | ## Step-02: Create Simple Pod Definition using YAML 15 | - We are going to create a very basic pod definition 16 | - **02-pod-definition.yml** 17 | ```yml 18 | apiVersion: v1 # String 19 | kind: Pod # String 20 | metadata: # Dictionary 21 | name: myapp-pod 22 | labels: # Dictionary 23 | app: myapp 24 | spec: 25 | containers: # List 26 | - name: myapp 27 | image: stacksimplify/kubenginx:1.0.0 28 | ports: 29 | - containerPort: 80 30 | ``` 31 | - **Create Pod** 32 | ``` 33 | # Create Pod 34 | kubectl create -f 02-pod-definition.yml 35 | [or] 36 | kubectl apply -f 02-pod-definition.yml 37 | 38 | # List Pods 39 | kubectl get pods 40 | ``` 41 | 42 | ## Step-03: Create a LoadBalancer Service 43 | - **03-pod-LoadBalancer-service.yml** 44 | ```yml 45 | apiVersion: v1 46 | kind: Service 47 | metadata: 48 | name: myapp-pod-loadbalancer-service # Name of the Service 49 | spec: 50 | type: NodePort 51 | selector: 52 | # Loadbalance traffic across Pods matching this label selector 53 | app: myapp 54 | # Accept traffic sent to port 80 55 | ports: 56 | - name: http 57 | port: 80 # Service Port 58 | targetPort: 80 # Container Port 59 | ``` 60 | - **Create LoadBalancer Service for Pod** 61 | ``` 62 | # Create Service 63 | kubectl apply -f 03-pod-LoadBalancer-service.yml 64 | 65 | # List Service 66 | kubectl get svc 67 | 68 | # Access Application 69 | http:// 70 | 71 | ``` 72 | 73 | ## API Object References 74 | - [Kubernetes API Spec](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/) 75 | - [Pod Spec](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#pod-v1-core) 76 | - [Service Spec](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#service-v1-core) 77 | 78 | 79 | -------------------------------------------------------------------------------- /04-Kubernetes-Fundamentals-with-YAML/04-02-PODs-with-YAML/kube-manifests/01-kube-base-definition.yml: -------------------------------------------------------------------------------- 1 | apiVersion: 2 | kind: 3 | metadata: 4 | 5 | spec: 6 | 7 | # Types of Kubernetes Objects 8 | # Pod, ReplicaSet, Deployment, Service and many more 9 | 10 | # apiVersion: version of k8s objects 11 | # kind: k8s objects 12 | # metadata: define name and labels for k8s objects 13 | # spec: specification or real definition for k8s objects 14 | -------------------------------------------------------------------------------- /04-Kubernetes-Fundamentals-with-YAML/04-02-PODs-with-YAML/kube-manifests/02-pod-definition.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 # String 2 | kind: Pod # String 3 | metadata: # Dictionary 4 | name: myapp-pod 5 | labels: # Dictionary 6 | app: myapp # Key value paids 7 | spec: 8 | containers: # List 9 | - name: myapp 10 | image: stacksimplify/kubenginx:1.0.0 11 | ports: 12 | - containerPort: 80 13 | 14 | 15 | -------------------------------------------------------------------------------- /04-Kubernetes-Fundamentals-with-YAML/04-02-PODs-with-YAML/kube-manifests/03-pod-LoadBalancer-service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: myapp-pod-loadbalancer-service 5 | spec: 6 | type: LoadBalancer # ClusterIp, # NodePort 7 | selector: 8 | app: myapp 9 | ports: 10 | - name: http 11 | port: 80 # Service Port 12 | targetPort: 80 # Container Port -------------------------------------------------------------------------------- /04-Kubernetes-Fundamentals-with-YAML/04-03-ReplicaSets-with-YAML/README.md: -------------------------------------------------------------------------------- 1 | # ReplicaSets with YAML 2 | 3 | ## Step-01: Create ReplicaSet Definition 4 | - **replicaset-definition.yml** 5 | ```yml 6 | apiVersion: apps/v1 7 | kind: ReplicaSet 8 | metadata: 9 | name: myapp2-rs 10 | spec: 11 | replicas: 3 # 3 Pods should exist at all times. 12 | selector: # Pods label should be defined in ReplicaSet label selector 13 | matchLabels: 14 | app: myapp2 15 | template: 16 | metadata: 17 | name: myapp2-pod 18 | labels: 19 | app: myapp2 # Atleast 1 Pod label should match with ReplicaSet Label Selector 20 | spec: 21 | containers: 22 | - name: myapp2 23 | image: stacksimplify/kubenginx:2.0.0 24 | ports: 25 | - containerPort: 80 26 | ``` 27 | ## Step-02: Create ReplicaSet 28 | - Create ReplicaSet with 3 Replicas 29 | ``` 30 | # Create ReplicaSet 31 | kubectl apply -f 02-replicaset-definition.yml 32 | 33 | # List Replicasets 34 | kubectl get rs 35 | ``` 36 | - Delete a pod 37 | - ReplicaSet immediately creates the pod. 38 | ``` 39 | # List Pods 40 | kubectl get pods 41 | 42 | # Delete Pod 43 | kubectl delete pod 44 | ``` 45 | 46 | ## Step-03: Create LoadBalancer Service for ReplicaSet 47 | ```yml 48 | apiVersion: v1 49 | kind: Service 50 | metadata: 51 | name: replicaset-loadbalancer-service 52 | spec: 53 | type: LoadBalancer 54 | selector: 55 | app: myapp2 56 | ports: 57 | - name: http 58 | port: 80 59 | targetPort: 80 60 | 61 | ``` 62 | - **Create LoadBalancer Service for ReplicaSet & Test** 63 | ``` 64 | # Create LoadBalancer Service 65 | kubectl apply -f 03-replicaset-LoadBalancer-servie.yml 66 | 67 | # List LoadBalancer Service 68 | kubectl get svc 69 | 70 | # Access Application 71 | http:// 72 | 73 | ``` 74 | 75 | ## API References 76 | - [ReplicaSet](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#replicaset-v1-apps) -------------------------------------------------------------------------------- /04-Kubernetes-Fundamentals-with-YAML/04-03-ReplicaSets-with-YAML/kube-manifests/01-kube-base-definition.yml: -------------------------------------------------------------------------------- 1 | apiVersion: 2 | kind: 3 | metadata: 4 | 5 | spec: 6 | -------------------------------------------------------------------------------- /04-Kubernetes-Fundamentals-with-YAML/04-03-ReplicaSets-with-YAML/kube-manifests/02-replicaset-definition.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: ReplicaSet 3 | metadata: #Dictionary 4 | name: myapp2-rs 5 | spec: # Dictionary 6 | replicas: 3 7 | selector: 8 | matchLabels: 9 | app: myapp2 10 | template: 11 | metadata: # Dictionary 12 | name: myapp2-pod 13 | labels: # Dictionary 14 | app: myapp2 # Key value paids 15 | spec: 16 | containers: # List 17 | - name: myapp2-container 18 | image: stacksimplify/kubenginx:2.0.0 19 | ports: 20 | - containerPort: 80 21 | -------------------------------------------------------------------------------- /04-Kubernetes-Fundamentals-with-YAML/04-03-ReplicaSets-with-YAML/kube-manifests/03-replicaset-LoadBalancer-servie.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: replicaset-loadbalancer-service 5 | spec: 6 | type: LoadBalancer # ClusterIp, # NodePort 7 | selector: 8 | app: myapp2 9 | ports: 10 | - name: http 11 | port: 80 # Service Port 12 | targetPort: 80 # Container Port -------------------------------------------------------------------------------- /04-Kubernetes-Fundamentals-with-YAML/04-04-Deployments-with-YAML/README.md: -------------------------------------------------------------------------------- 1 | # Deployments with YAML 2 | 3 | ## Step-01: Copy templates from ReplicaSet 4 | - Copy templates from ReplicaSet and change the `kind: Deployment` 5 | - Update Container Image version to `3.0.0` 6 | - Change all names to Deployment 7 | - Change all labels and selectors to `myapp3` 8 | 9 | ``` 10 | # Create Deployment 11 | kubectl apply -f 02-deployment-definition.yml 12 | kubectl get deploy 13 | kubectl get rs 14 | kubectl get po 15 | 16 | # Create LoadBalancer Service 17 | kubectl apply -f 03-deployment-LoadBalancer-service.yml 18 | 19 | # List Service 20 | kubectl get svc 21 | 22 | # Get Public IP 23 | kubectl get nodes -o wide 24 | 25 | # Access Application 26 | http:// 27 | ``` 28 | ## API References 29 | - [Deployment](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#deployment-v1-apps) 30 | -------------------------------------------------------------------------------- /04-Kubernetes-Fundamentals-with-YAML/04-04-Deployments-with-YAML/kube-manifests/01-kube-base-definition.yml: -------------------------------------------------------------------------------- 1 | apiVersion: 2 | kind: 3 | metadata: 4 | 5 | spec: 6 | -------------------------------------------------------------------------------- /04-Kubernetes-Fundamentals-with-YAML/04-04-Deployments-with-YAML/kube-manifests/02-deployment-definition.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: #Dictionary 4 | name: myapp3-deployment 5 | spec: # Dictionary 6 | replicas: 3 7 | selector: 8 | matchLabels: 9 | app: myapp3 10 | template: 11 | metadata: # Dictionary 12 | name: myapp3-pod 13 | labels: # Dictionary 14 | app: myapp3 # Key value paids 15 | spec: 16 | containers: # List 17 | - name: myapp3-container 18 | image: stacksimplify/kubenginx:3.0.0 19 | ports: 20 | - containerPort: 80 21 | -------------------------------------------------------------------------------- /04-Kubernetes-Fundamentals-with-YAML/04-04-Deployments-with-YAML/kube-manifests/03-deployment-LoadBalancer-servie.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: deployment-loadbalancer-service 5 | spec: 6 | type: LoadBalancer # ClusterIp, # NodePort 7 | selector: 8 | app: myapp3 9 | ports: 10 | - name: http 11 | port: 80 # Service Port 12 | targetPort: 80 # Container Port -------------------------------------------------------------------------------- /04-Kubernetes-Fundamentals-with-YAML/04-05-Services-with-YAML/kube-manifests/00-kube-base-definition.yml: -------------------------------------------------------------------------------- 1 | apiVersion: 2 | kind: 3 | metadata: 4 | 5 | spec: 6 | -------------------------------------------------------------------------------- /04-Kubernetes-Fundamentals-with-YAML/04-05-Services-with-YAML/kube-manifests/01-backend-deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: backend-restapp 5 | labels: 6 | app: backend-restapp 7 | tier: backend 8 | spec: 9 | replicas: 3 10 | selector: 11 | matchLabels: 12 | app: backend-restapp 13 | template: 14 | metadata: 15 | labels: 16 | app: backend-restapp 17 | tier: backend 18 | spec: 19 | containers: 20 | - name: backend-restapp 21 | image: stacksimplify/kube-helloworld:1.0.0 22 | ports: 23 | - containerPort: 8080 -------------------------------------------------------------------------------- /04-Kubernetes-Fundamentals-with-YAML/04-05-Services-with-YAML/kube-manifests/02-backend-clusterip-service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: my-backend-service ## VERY VERY IMPORTANT - NGINX PROXYPASS needs this name 5 | labels: 6 | app: backend-restapp 7 | tier: backend 8 | spec: 9 | #type: ClusterIP is a default service in k8s 10 | selector: 11 | app: backend-restapp 12 | ports: 13 | - name: http 14 | port: 8080 # ClusterIP Service Port 15 | targetPort: 8080 # Container Port 16 | -------------------------------------------------------------------------------- /04-Kubernetes-Fundamentals-with-YAML/04-05-Services-with-YAML/kube-manifests/03-frontend-deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: frontend-nginxapp 5 | labels: 6 | app: frontend-nginxapp 7 | tier: frontend 8 | spec: 9 | replicas: 3 10 | selector: 11 | matchLabels: 12 | app: frontend-nginxapp 13 | template: 14 | metadata: 15 | labels: 16 | app: frontend-nginxapp 17 | tier: frontend 18 | spec: 19 | containers: 20 | - name: frontend-nginxapp 21 | image: stacksimplify/kube-frontend-nginx:1.0.0 22 | ports: 23 | - containerPort: 80 -------------------------------------------------------------------------------- /04-Kubernetes-Fundamentals-with-YAML/04-05-Services-with-YAML/kube-manifests/04-frontend-LoadBalancer-service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: frontend-nginxapp-loadbalancer-service 5 | labels: 6 | app: frontend-nginxapp 7 | tier: frontend 8 | spec: 9 | type: LoadBalancer # ClusterIp, # NodePort 10 | selector: 11 | app: frontend-nginxapp 12 | ports: 13 | - name: http 14 | port: 80 # Service Port 15 | targetPort: 80 # Container Port -------------------------------------------------------------------------------- /05-Azure-Disks-for-AKS-Storage/05-01-SC-PVC-ConfigMap-MySQL/kube-manifests/02-persistent-volume-claim.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: azure-managed-disk-pvc 5 | spec: 6 | accessModes: 7 | - ReadWriteOnce 8 | storageClassName: managed-premium-retain-sc 9 | resources: 10 | requests: 11 | storage: 5Gi -------------------------------------------------------------------------------- /05-Azure-Disks-for-AKS-Storage/05-01-SC-PVC-ConfigMap-MySQL/kube-manifests/03-UserManagement-ConfigMap.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: usermanagement-dbcreation-script 5 | data: 6 | mysql_usermgmt.sql: |- 7 | DROP DATABASE IF EXISTS webappdb; 8 | CREATE DATABASE webappdb; -------------------------------------------------------------------------------- /05-Azure-Disks-for-AKS-Storage/05-01-SC-PVC-ConfigMap-MySQL/kube-manifests/04-mysql-deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: mysql 5 | spec: 6 | replicas: 1 7 | selector: 8 | matchLabels: 9 | app: mysql 10 | strategy: 11 | type: Recreate 12 | template: 13 | metadata: 14 | labels: 15 | app: mysql 16 | spec: 17 | containers: 18 | - name: mysql 19 | image: mysql:5.6 20 | env: 21 | - name: MYSQL_ROOT_PASSWORD 22 | value: dbpassword11 23 | ports: 24 | - containerPort: 3306 25 | name: mysql 26 | volumeMounts: 27 | - name: mysql-persistent-storage 28 | mountPath: /var/lib/mysql 29 | - name: usermanagement-dbcreation-script 30 | mountPath: /docker-entrypoint-initdb.d #https://hub.docker.com/_/mysql Refer Initializing a fresh instance 31 | volumes: 32 | - name: mysql-persistent-storage 33 | persistentVolumeClaim: 34 | claimName: azure-managed-disk-pvc 35 | - name: usermanagement-dbcreation-script 36 | configMap: 37 | name: usermanagement-dbcreation-script -------------------------------------------------------------------------------- /05-Azure-Disks-for-AKS-Storage/05-01-SC-PVC-ConfigMap-MySQL/kube-manifests/05-mysql-clusterip-service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: mysql 5 | spec: 6 | selector: 7 | app: mysql 8 | ports: 9 | - port: 3306 10 | clusterIP: None # This means we are going to use Pod IP -------------------------------------------------------------------------------- /05-Azure-Disks-for-AKS-Storage/05-02-PVC-ConfigMap-MySQL/README.md: -------------------------------------------------------------------------------- 1 | # AKS Storage - Azure Disks 2 | 3 | ## Step-01: Introduction 4 | - We are going to use Azure AKS provisioned storage class as part of this section 5 | 6 | ## Step-02: Use AKS Provisioned Azure Disks 7 | - Copy all templates from previous section 8 | - Remove Storage Class Manifest 9 | - **Question-1:** Why do we need to remove storage class Manifests? 10 | - Azure AKS provisions two types of storage classes well in advance during the cluster creation process 11 | - managed-premium 12 | - default- 13 | - We can leverage Azure AKS provisioned disk storage classes instead of what we created manually. 14 | - **Question-2:** If that is the case why did we use custom storate class in previous section? 15 | - That is for us to learn the `kind: StorageClass` concept. 16 | 17 | ## Step-03: Review PVC Manifest 01-persistent-volume-claim.yml 18 | - Primarily we are going to focus on `storageClassName: managed-premium` which tells us that we are going to use Azure AKS provisioned Azure Disks storage class. 19 | ```yml 20 | apiVersion: v1 21 | kind: PersistentVolumeClaim 22 | metadata: 23 | name: azure-managed-disk-pvc 24 | spec: 25 | accessModes: 26 | - ReadWriteOnce 27 | storageClassName: managed-premium 28 | resources: 29 | requests: 30 | storage: 5Gi 31 | ``` 32 | 33 | ## Step-04: Deploy and Test 34 | ``` 35 | # Create MySQL Database 36 | kubectl apply -f kube-manifests/ 37 | 38 | # List Storage Classes 39 | kubectl get sc 40 | 41 | # List PVC 42 | kubectl get pvc 43 | 44 | # List PV 45 | kubectl get pv 46 | 47 | # List pods 48 | kubectl get pods 49 | ``` 50 | 51 | ## Step-05: Connect to MySQL Database 52 | ``` 53 | # Connect to MYSQL Database 54 | kubectl run -it --rm --image=mysql:5.6 --restart=Never mysql-client -- mysql -h mysql -pdbpassword11 55 | 56 | # Verify usermgmt schema got created which we provided in ConfigMap 57 | mysql> show schemas; 58 | ``` 59 | 60 | ## Step-06: Clean-Up 61 | ``` 62 | # Delete all manifests 63 | kubectl delete -f kube-manifests/ 64 | ``` -------------------------------------------------------------------------------- /05-Azure-Disks-for-AKS-Storage/05-02-PVC-ConfigMap-MySQL/kube-manifests/01-persistent-volume-claim.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: azure-managed-disk-pvc 5 | spec: 6 | accessModes: 7 | - ReadWriteOnce 8 | storageClassName: managed-premium 9 | resources: 10 | requests: 11 | storage: 5Gi -------------------------------------------------------------------------------- /05-Azure-Disks-for-AKS-Storage/05-02-PVC-ConfigMap-MySQL/kube-manifests/02-UserManagement-ConfigMap.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: usermanagement-dbcreation-script 5 | data: 6 | mysql_usermgmt.sql: |- 7 | DROP DATABASE IF EXISTS webappdb; 8 | CREATE DATABASE webappdb; -------------------------------------------------------------------------------- /05-Azure-Disks-for-AKS-Storage/05-02-PVC-ConfigMap-MySQL/kube-manifests/03-mysql-deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: mysql 5 | spec: 6 | replicas: 1 7 | selector: 8 | matchLabels: 9 | app: mysql 10 | strategy: 11 | type: Recreate 12 | template: 13 | metadata: 14 | labels: 15 | app: mysql 16 | spec: 17 | containers: 18 | - name: mysql 19 | image: mysql:5.6 20 | env: 21 | - name: MYSQL_ROOT_PASSWORD 22 | value: dbpassword11 23 | ports: 24 | - containerPort: 3306 25 | name: mysql 26 | volumeMounts: 27 | - name: mysql-persistent-storage 28 | mountPath: /var/lib/mysql 29 | - name: usermanagement-dbcreation-script 30 | mountPath: /docker-entrypoint-initdb.d #https://hub.docker.com/_/mysql Refer Initializing a fresh instance 31 | volumes: 32 | - name: mysql-persistent-storage 33 | persistentVolumeClaim: 34 | claimName: azure-managed-disk-pvc 35 | - name: usermanagement-dbcreation-script 36 | configMap: 37 | name: usermanagement-dbcreation-script -------------------------------------------------------------------------------- /05-Azure-Disks-for-AKS-Storage/05-02-PVC-ConfigMap-MySQL/kube-manifests/04-mysql-clusterip-service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: mysql 5 | spec: 6 | selector: 7 | app: mysql 8 | ports: 9 | - port: 3306 10 | clusterIP: None # This means we are going to use Pod IP -------------------------------------------------------------------------------- /05-Azure-Disks-for-AKS-Storage/05-03-UserMgmt-WebApp-with-MySQLDB/kube-manifests/01-storage-class.yml: -------------------------------------------------------------------------------- 1 | apiVersion: storage.k8s.io/v1 2 | kind: StorageClass 3 | metadata: 4 | name: managed-premium-retain-sc 5 | provisioner: kubernetes.io/azure-disk 6 | reclaimPolicy: Retain # Default is Delete, recommended is retain 7 | volumeBindingMode: WaitForFirstConsumer # Default is Immediate, recommended is WaitForFirstConsumer 8 | allowVolumeExpansion: true 9 | parameters: 10 | storageaccounttype: Premium_LRS # or we can use Standard_LRS 11 | kind: Managed # Default is shared, recommended is Managed 12 | 13 | # Additional Reference 14 | # https://kubernetes.io/docs/concepts/storage/storage-classes/#azure-disk 15 | 16 | ############################################################################## 17 | # Note - 1: 18 | #volumeBindingMode: Immediate - This setting implies that the PersistentVolumecreation, 19 | #followed with the storage medium (Azure Disk in this case) provisioning is triggered as 20 | #soon as the PersistentVolumeClaim is created. 21 | 22 | # Note - 2: 23 | # volumeBindingMode: WaitForFirstConsumer 24 | #By default, the Immediate mode indicates that volume binding and dynamic provisioning 25 | #occurs once the PersistentVolumeClaim is created. For storage backends that are 26 | #topology-constrained and not globally accessible from all Nodes in the cluster, 27 | #PersistentVolumes will be bound or provisioned without knowledge of the Pod's scheduling 28 | #requirements. This may result in unschedulable Pods. 29 | #A cluster administrator can address this issue by specifying the WaitForFirstConsumer 30 | #mode which will delay the binding and provisioning of a PersistentVolume until a 31 | #Pod using the PersistentVolumeClaim is created. PersistentVolumes will be selected or 32 | #provisioned conforming to the topology that is specified by the Pod's scheduling 33 | #constraints. 34 | ############################################################################## 35 | # Note - 3: 36 | #reclaimPolicy: Delete - With this setting, as soon as a PersistentVolumeClaim is deleted, 37 | #it also triggers the removal of the corresponding PersistentVolume along with the 38 | #Azure Disk. 39 | #We will be surprised provided if we intended to retain that data as backup. 40 | # reclaimPolicy: retain - Disk is retained even when PVC is deleted - Recommended Option 41 | 42 | # Note - 4: 43 | # Both reclaimPolicy: Delete and volumeBindingMode: Immediate are default settings 44 | ############################################################################## -------------------------------------------------------------------------------- /05-Azure-Disks-for-AKS-Storage/05-03-UserMgmt-WebApp-with-MySQLDB/kube-manifests/02-persistent-volume-claim.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: azure-managed-disk-pvc 5 | spec: 6 | accessModes: 7 | - ReadWriteOnce 8 | storageClassName: managed-premium-retain-sc 9 | resources: 10 | requests: 11 | storage: 5Gi 12 | 13 | # AKS already provisioned Storage classes managed-premium and default as part of 14 | # default cluster setup -------------------------------------------------------------------------------- /05-Azure-Disks-for-AKS-Storage/05-03-UserMgmt-WebApp-with-MySQLDB/kube-manifests/03-UserManagement-ConfigMap.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: usermanagement-dbcreation-script 5 | data: 6 | mysql_usermgmt.sql: |- 7 | DROP DATABASE IF EXISTS webappdb; 8 | CREATE DATABASE webappdb; -------------------------------------------------------------------------------- /05-Azure-Disks-for-AKS-Storage/05-03-UserMgmt-WebApp-with-MySQLDB/kube-manifests/04-mysql-deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: mysql 5 | spec: 6 | replicas: 1 7 | selector: 8 | matchLabels: 9 | app: mysql 10 | strategy: 11 | type: Recreate 12 | template: 13 | metadata: 14 | labels: 15 | app: mysql 16 | spec: 17 | containers: 18 | - name: mysql 19 | image: mysql:5.6 20 | env: 21 | - name: MYSQL_ROOT_PASSWORD 22 | value: dbpassword11 23 | ports: 24 | - containerPort: 3306 25 | name: mysql 26 | volumeMounts: 27 | - name: mysql-persistent-storage 28 | mountPath: /var/lib/mysql 29 | - name: usermanagement-dbcreation-script 30 | mountPath: /docker-entrypoint-initdb.d #https://hub.docker.com/_/mysql Refer Initializing a fresh instance 31 | volumes: 32 | - name: mysql-persistent-storage 33 | persistentVolumeClaim: 34 | claimName: azure-managed-disk-pvc 35 | - name: usermanagement-dbcreation-script 36 | configMap: 37 | name: usermanagement-dbcreation-script -------------------------------------------------------------------------------- /05-Azure-Disks-for-AKS-Storage/05-03-UserMgmt-WebApp-with-MySQLDB/kube-manifests/05-mysql-clusterip-service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: mysql 5 | spec: 6 | selector: 7 | app: mysql 8 | ports: 9 | - port: 3306 10 | clusterIP: None # This means we are going to use Pod IP -------------------------------------------------------------------------------- /05-Azure-Disks-for-AKS-Storage/05-03-UserMgmt-WebApp-with-MySQLDB/kube-manifests/06-UserMgmtWebApp-Deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: usermgmt-webapp 5 | labels: 6 | app: usermgmt-webapp 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: usermgmt-webapp 12 | template: 13 | metadata: 14 | labels: 15 | app: usermgmt-webapp 16 | spec: 17 | initContainers: 18 | - name: init-db 19 | image: busybox:1.31 20 | command: ['sh', '-c', 'echo -e "Checking for the availability of MySQL Server deployment"; while ! nc -z mysql 3306; do sleep 1; printf "-"; done; echo -e " >> MySQL DB Server has started";'] 21 | containers: 22 | - name: usermgmt-webapp 23 | image: stacksimplify/kube-usermgmt-webapp:1.0.0-MySQLDB 24 | imagePullPolicy: Always 25 | ports: 26 | - containerPort: 8080 27 | env: 28 | - name: DB_HOSTNAME 29 | value: "mysql" 30 | - name: DB_PORT 31 | value: "3306" 32 | - name: DB_NAME 33 | value: "webappdb" 34 | - name: DB_USERNAME 35 | value: "root" 36 | - name: DB_PASSWORD 37 | value: "dbpassword11" 38 | -------------------------------------------------------------------------------- /05-Azure-Disks-for-AKS-Storage/05-03-UserMgmt-WebApp-with-MySQLDB/kube-manifests/07-UserMgmtWebApp-Service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: usermgmt-webapp-service 5 | labels: 6 | app: usermgmt-webapp 7 | spec: 8 | type: LoadBalancer 9 | selector: 10 | app: usermgmt-webapp 11 | ports: 12 | - port: 80 13 | targetPort: 8080 -------------------------------------------------------------------------------- /05-Azure-Disks-for-AKS-Storage/README.md: -------------------------------------------------------------------------------- 1 | # Azure AKS Storage - Azure Disks 2 | 3 | ## Topics 4 | 1. Understand about Azure Disks 5 | 2. How we are going to use Azure Disks for Applications deployed on AKS for persistent Storage? 6 | 3. Understand best possible options available that we can configure in Storage Classess to persist our data, save cost and performance etc. 7 | 8 | ## Concepts 9 | | Kubernetes Object | YAML File | 10 | | ------------- | ------------- | 11 | | Storage Class | 01-storage-class.yml | 12 | | Persistent Volume Claim | 02-persistent-volume-claim.yml | 13 | | Config Map | 03-UserManagement-ConfigMap.yml | 14 | | Deployment | 04-mysql-deployment.yml | 15 | | Environment Variables | 04-mysql-deployment.yml | 16 | | Volumes | 04-mysql-deployment.yml | 17 | | VolumeMounts | 04-mysql-deployment.yml | 18 | | ClusterIP Service | 05-mysql-clusterip-service.yml | 19 | | Deployment | 06-UserMgmtWebApp-Deployment.yml | 20 | | Environment Variables| 06-UserMgmtWebApp-Deployment.yml | 21 | | Init Containers | 06-UserMgmtWebApp-Deployment.yml | 22 | | Load Balancer Service | 07-UserMgmtWebApp-Service.yml | 23 | 24 | 25 | -------------------------------------------------------------------------------- /06-Azure-MySQL-for-AKS-Storage/kube-manifests/01-MySQL-externalName-Service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: mysql 5 | spec: 6 | type: ExternalName 7 | externalName: akswebappdb.mysql.database.azure.com -------------------------------------------------------------------------------- /06-Azure-MySQL-for-AKS-Storage/kube-manifests/02-UserMgmtWebApp-Deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: usermgmt-webapp 5 | labels: 6 | app: usermgmt-webapp 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: usermgmt-webapp 12 | template: 13 | metadata: 14 | labels: 15 | app: usermgmt-webapp 16 | spec: 17 | initContainers: 18 | - name: init-db 19 | image: busybox:1.31 20 | command: ['sh', '-c', 'echo -e "Checking for the availability of MySQL Server deployment"; while ! nc -z mysql 3306; do sleep 1; printf "-"; done; echo -e " >> MySQL DB Server has started";'] 21 | containers: 22 | - name: usermgmt-webapp 23 | image: stacksimplify/kube-usermgmt-webapp:1.0.0-MySQLDB 24 | imagePullPolicy: Always 25 | ports: 26 | - containerPort: 8080 27 | env: 28 | - name: DB_HOSTNAME 29 | value: "mysql" 30 | - name: DB_PORT 31 | value: "3306" 32 | - name: DB_NAME 33 | value: "webappdb" 34 | - name: DB_USERNAME 35 | value: "dbadmin@akswebappdb" 36 | - name: DB_PASSWORD 37 | value: "Redhat1449" 38 | -------------------------------------------------------------------------------- /06-Azure-MySQL-for-AKS-Storage/kube-manifests/03-UserMgmtWebApp-Service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: usermgmt-webapp-service 5 | labels: 6 | app: usermgmt-webapp 7 | spec: 8 | type: LoadBalancer 9 | selector: 10 | app: usermgmt-webapp 11 | ports: 12 | - port: 80 13 | targetPort: 8080 14 | 15 | -------------------------------------------------------------------------------- /07-Kubernetes-Secrets/README.md: -------------------------------------------------------------------------------- 1 | # Kubernetes - Secrets 2 | 3 | ## Step-01: Introduction 4 | - Kubernetes Secrets let you store and manage sensitive information, such as passwords, OAuth tokens, and ssh keys. 5 | - Storing confidential information in a Secret is safer and more flexible than putting it directly in a Pod definition or in a container image. 6 | 7 | ## Step-02: Create Secret for MySQL DB Password 8 | ### 9 | ``` 10 | # Mac 11 | echo -n 'dbpassword11' | base64 12 | 13 | # URL: https://www.base64encode.org 14 | ``` 15 | ### Create Kubernetes Secrets manifest 16 | ```yml 17 | apiVersion: v1 18 | kind: Secret 19 | metadata: 20 | name: mysql-db-password 21 | #type: Opaque means that from kubernetes's point of view the contents of this Secret is unstructured. 22 | #It can contain arbitrary key-value pairs. 23 | type: Opaque 24 | data: 25 | # Output of echo -n 'Redhat1449' | base64 26 | db-password: ZGJwYXNzd29yZDEx 27 | ``` 28 | ## Step-03: Update secret in MySQL Deployment for DB Password 29 | ```yml 30 | env: 31 | - name: MYSQL_ROOT_PASSWORD 32 | valueFrom: 33 | secretKeyRef: 34 | name: mysql-db-password 35 | key: db-password 36 | ``` 37 | 38 | ## Step-04: Update secret in UWA Deployment 39 | - UMS means User Management Microservice 40 | ```yml 41 | - name: DB_PASSWORD 42 | valueFrom: 43 | secretKeyRef: 44 | name: mysql-db-password 45 | key: db-password 46 | ``` 47 | 48 | ## Step-05: Create & Test 49 | ``` 50 | # Create All Objects 51 | kubectl apply -f kube-manifests/ 52 | 53 | # List Pods 54 | kubectl get pods 55 | 56 | # Get Public IP of Application 57 | kubectl get svc 58 | 59 | # Access Application 60 | http:// 61 | Username: admin101 62 | Password: password101 63 | ``` 64 | 65 | ## Step-06: Clean-Up 66 | - Delete all k8s objects created as part of this section 67 | ``` 68 | # Delete All 69 | kubectl delete -f kube-manifests/ 70 | 71 | # List Pods 72 | kubectl get pods 73 | 74 | # Verify sc, pvc, pv 75 | kubectl get sc,pvc,pv 76 | ``` -------------------------------------------------------------------------------- /07-Kubernetes-Secrets/kube-manifests/01-storage-class.yml: -------------------------------------------------------------------------------- 1 | apiVersion: storage.k8s.io/v1 2 | kind: StorageClass 3 | metadata: 4 | name: managed-premium-retain-sc 5 | provisioner: kubernetes.io/azure-disk 6 | reclaimPolicy: Retain # Default is Delete, recommended is retain 7 | volumeBindingMode: WaitForFirstConsumer # Default is Immediate, recommended is WaitForFirstConsumer 8 | allowVolumeExpansion: true 9 | parameters: 10 | storageaccounttype: Premium_LRS # or we can use Standard_LRS 11 | kind: Managed # Default is shared, recommended is Managed 12 | 13 | # Additional Reference 14 | # https://kubernetes.io/docs/concepts/storage/storage-classes/#azure-disk 15 | 16 | ############################################################################## 17 | # Note - 1: 18 | #volumeBindingMode: Immediate - This setting implies that the PersistentVolumecreation, 19 | #followed with the storage medium (Azure Disk in this case) provisioning is triggered as 20 | #soon as the PersistentVolumeClaim is created. 21 | 22 | # Note - 2: 23 | # volumeBindingMode: WaitForFirstConsumer 24 | #By default, the Immediate mode indicates that volume binding and dynamic provisioning 25 | #occurs once the PersistentVolumeClaim is created. For storage backends that are 26 | #topology-constrained and not globally accessible from all Nodes in the cluster, 27 | #PersistentVolumes will be bound or provisioned without knowledge of the Pod's scheduling 28 | #requirements. This may result in unschedulable Pods. 29 | #A cluster administrator can address this issue by specifying the WaitForFirstConsumer 30 | #mode which will delay the binding and provisioning of a PersistentVolume until a 31 | #Pod using the PersistentVolumeClaim is created. PersistentVolumes will be selected or 32 | #provisioned conforming to the topology that is specified by the Pod's scheduling 33 | #constraints. 34 | ############################################################################## 35 | # Note - 3: 36 | #reclaimPolicy: Delete - With this setting, as soon as a PersistentVolumeClaim is deleted, 37 | #it also triggers the removal of the corresponding PersistentVolume along with the 38 | #Azure Disk. 39 | #We will be surprised provided if we intended to retain that data as backup. 40 | # reclaimPolicy: retain - Disk is retained even when PVC is deleted - Recommended Option 41 | 42 | # Note - 4: 43 | # Both reclaimPolicy: Delete and volumeBindingMode: Immediate are default settings 44 | ############################################################################## -------------------------------------------------------------------------------- /07-Kubernetes-Secrets/kube-manifests/02-persistent-volume-claim.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: azure-managed-disk-pvc 5 | spec: 6 | accessModes: 7 | - ReadWriteOnce 8 | storageClassName: managed-premium-retain-sc 9 | resources: 10 | requests: 11 | storage: 5Gi 12 | 13 | # AKS already provisioned Storage classes managed-premium and default as part of 14 | # default cluster setup -------------------------------------------------------------------------------- /07-Kubernetes-Secrets/kube-manifests/03-UserManagement-ConfigMap.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: usermanagement-dbcreation-script 5 | data: 6 | mysql_usermgmt.sql: |- 7 | DROP DATABASE IF EXISTS webappdb; 8 | CREATE DATABASE webappdb; -------------------------------------------------------------------------------- /07-Kubernetes-Secrets/kube-manifests/04-mysql-deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: mysql 5 | spec: 6 | replicas: 1 7 | selector: 8 | matchLabels: 9 | app: mysql 10 | strategy: 11 | type: Recreate 12 | template: 13 | metadata: 14 | labels: 15 | app: mysql 16 | spec: 17 | containers: 18 | - name: mysql 19 | image: mysql:5.6 20 | env: 21 | - name: MYSQL_ROOT_PASSWORD 22 | valueFrom: 23 | secretKeyRef: 24 | name: mysql-db-password 25 | key: db-password 26 | ports: 27 | - containerPort: 3306 28 | name: mysql 29 | volumeMounts: 30 | - name: mysql-persistent-storage 31 | mountPath: /var/lib/mysql 32 | - name: usermanagement-dbcreation-script 33 | mountPath: /docker-entrypoint-initdb.d #https://hub.docker.com/_/mysql Refer Initializing a fresh instance 34 | volumes: 35 | - name: mysql-persistent-storage 36 | persistentVolumeClaim: 37 | claimName: azure-managed-disk-pvc 38 | - name: usermanagement-dbcreation-script 39 | configMap: 40 | name: usermanagement-dbcreation-script -------------------------------------------------------------------------------- /07-Kubernetes-Secrets/kube-manifests/05-mysql-clusterip-service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: mysql 5 | spec: 6 | selector: 7 | app: mysql 8 | ports: 9 | - port: 3306 10 | clusterIP: None # This means we are going to use Pod IP -------------------------------------------------------------------------------- /07-Kubernetes-Secrets/kube-manifests/06-UserMgmtWebApp-Deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: usermgmt-webapp 5 | labels: 6 | app: usermgmt-webapp 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: usermgmt-webapp 12 | template: 13 | metadata: 14 | labels: 15 | app: usermgmt-webapp 16 | spec: 17 | initContainers: 18 | - name: init-db 19 | image: busybox:1.31 20 | command: ['sh', '-c', 'echo -e "Checking for the availability of MySQL Server deployment"; while ! nc -z mysql 3306; do sleep 1; printf "-"; done; echo -e " >> MySQL DB Server has started";'] 21 | containers: 22 | - name: usermgmt-webapp 23 | image: stacksimplify/kube-usermgmt-webapp:1.0.0-MySQLDB 24 | imagePullPolicy: Always 25 | ports: 26 | - containerPort: 8080 27 | env: 28 | - name: DB_HOSTNAME 29 | value: "mysql" 30 | - name: DB_PORT 31 | value: "3306" 32 | - name: DB_NAME 33 | value: "webappdb" 34 | - name: DB_USERNAME 35 | value: "root" 36 | - name: DB_PASSWORD 37 | valueFrom: 38 | secretKeyRef: 39 | name: mysql-db-password 40 | key: db-password 41 | -------------------------------------------------------------------------------- /07-Kubernetes-Secrets/kube-manifests/07-UserMgmtWebApp-Service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: usermgmt-webapp-service 5 | labels: 6 | app: usermgmt-webapp 7 | spec: 8 | type: LoadBalancer 9 | selector: 10 | app: usermgmt-webapp 11 | ports: 12 | - port: 80 13 | targetPort: 8080 -------------------------------------------------------------------------------- /07-Kubernetes-Secrets/kube-manifests/08-Kubernetes-Secrets.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: mysql-db-password 5 | type: Opaque 6 | data: 7 | db-password: ZGJwYXNzd29yZDEx 8 | 9 | 10 | -------------------------------------------------------------------------------- /08-Azure-Files-for-AKS-Storage/kube-manifests-v1/01-Storage-Class.yml: -------------------------------------------------------------------------------- 1 | kind: StorageClass 2 | apiVersion: storage.k8s.io/v1 3 | metadata: 4 | name: my-azurefile-sc 5 | provisioner: kubernetes.io/azure-file 6 | mountOptions: 7 | - dir_mode=0777 8 | - file_mode=0777 9 | - uid=0 10 | - gid=0 11 | - mfsymlinks 12 | - cache=strict 13 | parameters: 14 | skuName: Standard_LRS -------------------------------------------------------------------------------- /08-Azure-Files-for-AKS-Storage/kube-manifests-v1/02-Persistent-Volume-Claim.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: my-azurefile-pvc 5 | spec: 6 | accessModes: 7 | - ReadWriteMany 8 | storageClassName: my-azurefile-sc 9 | resources: 10 | requests: 11 | storage: 5Gi -------------------------------------------------------------------------------- /08-Azure-Files-for-AKS-Storage/kube-manifests-v1/03-Nginx-Deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: azure-files-nginx-deployment 5 | labels: 6 | app: azure-files-nginx-app 7 | spec: 8 | replicas: 4 9 | selector: 10 | matchLabels: 11 | app: azure-files-nginx-app 12 | template: 13 | metadata: 14 | labels: 15 | app: azure-files-nginx-app 16 | spec: 17 | containers: 18 | - name: azure-files-nginx-app 19 | image: stacksimplify/kube-nginxapp1:1.0.0 20 | imagePullPolicy: Always 21 | ports: 22 | - containerPort: 80 23 | volumeMounts: 24 | - name: my-azurefile-volume 25 | mountPath: "/usr/share/nginx/html/app1" 26 | volumes: 27 | - name: my-azurefile-volume 28 | persistentVolumeClaim: 29 | claimName: my-azurefile-pvc 30 | 31 | -------------------------------------------------------------------------------- /08-Azure-Files-for-AKS-Storage/kube-manifests-v1/04-Nginx-Service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: azure-files-nginx-service 5 | labels: 6 | app: azure-files-nginx-app 7 | spec: 8 | type: LoadBalancer 9 | selector: 10 | app: azure-files-nginx-app 11 | ports: 12 | - port: 80 13 | targetPort: 80 14 | 15 | -------------------------------------------------------------------------------- /08-Azure-Files-for-AKS-Storage/kube-manifests-v2/01-Persistent-Volume-Claim.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: my-azurefile-pvc 5 | spec: 6 | accessModes: 7 | - ReadWriteMany 8 | storageClassName: azurefile # default AKS provisioned storage class in my AKS Cluster 9 | resources: 10 | requests: 11 | storage: 5Gi -------------------------------------------------------------------------------- /08-Azure-Files-for-AKS-Storage/kube-manifests-v2/02-Nginx-Deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: azure-files-nginx-deployment 5 | labels: 6 | app: azure-files-nginx-app 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: azure-files-nginx-app 12 | template: 13 | metadata: 14 | labels: 15 | app: azure-files-nginx-app 16 | spec: 17 | containers: 18 | - name: azure-files-nginx-app 19 | image: stacksimplify/kube-nginxapp1:1.0.0 20 | imagePullPolicy: Always 21 | ports: 22 | - containerPort: 80 23 | volumeMounts: 24 | - name: my-azurefile-volume 25 | mountPath: "/usr/share/nginx/html/app1" 26 | volumes: 27 | - name: my-azurefile-volume 28 | persistentVolumeClaim: 29 | claimName: my-azurefile-pvc 30 | 31 | -------------------------------------------------------------------------------- /08-Azure-Files-for-AKS-Storage/kube-manifests-v2/03-Nginx-Service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: azure-files-nginx-service 5 | labels: 6 | app: azure-files-nginx-app 7 | spec: 8 | type: LoadBalancer 9 | selector: 10 | app: azure-files-nginx-app 11 | ports: 12 | - port: 80 13 | targetPort: 80 14 | 15 | -------------------------------------------------------------------------------- /08-Azure-Files-for-AKS-Storage/nginx-files/file1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |

Welcome to Stack Simplify - File 1

5 |

Azure Files Demo

6 |

Application Version: V1

7 | 8 | -------------------------------------------------------------------------------- /08-Azure-Files-for-AKS-Storage/nginx-files/file2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |

Welcome to Stack Simplify - File 2

5 |

Azure Files Demo

6 |

Application Version: V1

7 | 8 | -------------------------------------------------------------------------------- /09-Ingress-Basic/kube-manifests/01-NginxApp1-Deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: app1-nginx-deployment 5 | labels: 6 | app: app1-nginx 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: app1-nginx 12 | template: 13 | metadata: 14 | labels: 15 | app: app1-nginx 16 | spec: 17 | containers: 18 | - name: app1-nginx 19 | image: stacksimplify/kube-nginxapp1:1.0.0 20 | ports: 21 | - containerPort: 80 22 | 23 | -------------------------------------------------------------------------------- /09-Ingress-Basic/kube-manifests/02-NginxApp1-ClusterIP-Service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: app1-nginx-clusterip-service 5 | labels: 6 | app: app1-nginx 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | app: app1-nginx 11 | ports: 12 | - port: 80 13 | targetPort: 80 14 | -------------------------------------------------------------------------------- /09-Ingress-Basic/kube-manifests/03-Ingress-Basic.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1beta1 2 | kind: Ingress 3 | metadata: 4 | name: nginxapp1-ingress-service 5 | spec: 6 | rules: 7 | - http: 8 | paths: 9 | - path: / 10 | backend: 11 | serviceName: app1-nginx-clusterip-service 12 | servicePort: 80 13 | 14 | -------------------------------------------------------------------------------- /10-Ingress-Context-Path-Based-Routing/README.md: -------------------------------------------------------------------------------- 1 | # Ingress - Context Path Based Routing 2 | 3 | ## Step-01: Introduction 4 | - We are going to implement context path based routing using Ingress 5 | 6 | [![Image](https://www.stacksimplify.com/course-images/azure-aks-ingress-path-based-routing.png "Azure AKS Kubernetes - Masterclass")](https://www.udemy.com/course/aws-eks-kubernetes-masterclass-devops-microservices/?referralCode=257C9AD5B5AF8D12D1E1) 7 | 8 | ## Step-02: Review k8s Application Manifests 9 | - 01-NginxApp1-Manifests 10 | - 02-NginxApp2-Manifests 11 | - 03-UserMgmtmWebApp-Manifests 12 | 13 | ## Step-03: Review Ingress Service Manifests 14 | - 04-IngressService-Manifests 15 | 16 | ## Step-04: Deploy and Verify 17 | ``` 18 | # Deploy Apps 19 | kubectl apply -R -f kube-manifests/ 20 | 21 | # List Pods 22 | kubectl get pods 23 | 24 | # List Services 25 | kubectl get svc 26 | 27 | # List Ingress 28 | kubectl get ingress 29 | 30 | # Verify Ingress Controller Logs 31 | kubectl get pods -n ingress-basic 32 | kubectl logs -f -n ingress-basic 33 | ``` 34 | 35 | ## Step-05: Access Applications 36 | ``` 37 | # Access App1 38 | http:///app1/index.html 39 | 40 | # Access App2 41 | http:///app2/index.html 42 | 43 | # Access Usermgmt Web App 44 | http:// 45 | Username: admin101 46 | Password: password101 47 | 48 | ``` 49 | 50 | ## Step-06: Clean-Up Applications 51 | ``` 52 | # Delete Apps 53 | kubectl delete -f kube-manifests/ 54 | 55 | # Delete Azure Disk created for Usermgmt Web App 56 | Go to All Services -> Azure Disks -> Delete disk 57 | ``` 58 | 59 | ## Ingress Annotation Reference 60 | - https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/ 61 | 62 | -------------------------------------------------------------------------------- /10-Ingress-Context-Path-Based-Routing/kube-manifests/01-NginxApp1-Manifests/01-NginxApp1-Deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: app1-nginx-deployment 5 | labels: 6 | app: app1-nginx 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: app1-nginx 12 | template: 13 | metadata: 14 | labels: 15 | app: app1-nginx 16 | spec: 17 | containers: 18 | - name: app1-nginx 19 | image: stacksimplify/kube-nginxapp1:1.0.0 20 | ports: 21 | - containerPort: 80 22 | 23 | -------------------------------------------------------------------------------- /10-Ingress-Context-Path-Based-Routing/kube-manifests/01-NginxApp1-Manifests/02-NginxApp1-ClusterIP-Service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: app1-nginx-clusterip-service 5 | labels: 6 | app: app1-nginx 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | app: app1-nginx 11 | ports: 12 | - port: 80 13 | targetPort: 80 14 | -------------------------------------------------------------------------------- /10-Ingress-Context-Path-Based-Routing/kube-manifests/02-NginxApp2-Manifets/01-NginxApp2-Deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: app2-nginx-deployment 5 | labels: 6 | app: app2-nginx 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: app2-nginx 12 | template: 13 | metadata: 14 | labels: 15 | app: app2-nginx 16 | spec: 17 | containers: 18 | - name: app2-nginx 19 | image: stacksimplify/kube-nginxapp2:1.0.0 20 | ports: 21 | - containerPort: 80 22 | -------------------------------------------------------------------------------- /10-Ingress-Context-Path-Based-Routing/kube-manifests/02-NginxApp2-Manifets/02-NginxApp2-ClusterIP-Service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: app2-nginx-clusterip-service 5 | labels: 6 | app: app2-nginx 7 | annotations: 8 | spec: 9 | type: ClusterIP 10 | selector: 11 | app: app2-nginx 12 | ports: 13 | - port: 80 14 | targetPort: 80 15 | 16 | -------------------------------------------------------------------------------- /10-Ingress-Context-Path-Based-Routing/kube-manifests/03-UserMgmtWebApp-Manifests/01-persistent-volume-claim.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: azure-managed-disk-pvc 5 | spec: 6 | accessModes: 7 | - ReadWriteOnce 8 | storageClassName: managed-premium 9 | resources: 10 | requests: 11 | storage: 5Gi 12 | 13 | # AKS already provisioned Storage classes managed-premium and default as part of 14 | # default cluster setup -------------------------------------------------------------------------------- /10-Ingress-Context-Path-Based-Routing/kube-manifests/03-UserMgmtWebApp-Manifests/02-UserManagement-ConfigMap.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: usermanagement-dbcreation-script 5 | data: 6 | mysql_usermgmt.sql: |- 7 | DROP DATABASE IF EXISTS webappdb; 8 | CREATE DATABASE webappdb; -------------------------------------------------------------------------------- /10-Ingress-Context-Path-Based-Routing/kube-manifests/03-UserMgmtWebApp-Manifests/03-mysql-deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: mysql 5 | spec: 6 | replicas: 1 7 | selector: 8 | matchLabels: 9 | app: mysql 10 | strategy: 11 | type: Recreate 12 | template: 13 | metadata: 14 | labels: 15 | app: mysql 16 | spec: 17 | containers: 18 | - name: mysql 19 | image: mysql:5.6 20 | env: 21 | - name: MYSQL_ROOT_PASSWORD 22 | valueFrom: 23 | secretKeyRef: 24 | name: mysql-db-password 25 | key: db-password 26 | ports: 27 | - containerPort: 3306 28 | name: mysql 29 | volumeMounts: 30 | - name: mysql-persistent-storage 31 | mountPath: /var/lib/mysql 32 | - name: usermanagement-dbcreation-script 33 | mountPath: /docker-entrypoint-initdb.d #https://hub.docker.com/_/mysql Refer Initializing a fresh instance 34 | volumes: 35 | - name: mysql-persistent-storage 36 | persistentVolumeClaim: 37 | claimName: azure-managed-disk-pvc 38 | - name: usermanagement-dbcreation-script 39 | configMap: 40 | name: usermanagement-dbcreation-script -------------------------------------------------------------------------------- /10-Ingress-Context-Path-Based-Routing/kube-manifests/03-UserMgmtWebApp-Manifests/04-mysql-clusterip-service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: mysql 5 | spec: 6 | selector: 7 | app: mysql 8 | ports: 9 | - port: 3306 10 | clusterIP: None # This means we are going to use Pod IP -------------------------------------------------------------------------------- /10-Ingress-Context-Path-Based-Routing/kube-manifests/03-UserMgmtWebApp-Manifests/05-UserMgmtWebApp-Deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: usermgmt-webapp 5 | labels: 6 | app: usermgmt-webapp 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: usermgmt-webapp 12 | template: 13 | metadata: 14 | labels: 15 | app: usermgmt-webapp 16 | spec: 17 | initContainers: 18 | - name: init-db 19 | image: busybox:1.31 20 | command: ['sh', '-c', 'echo -e "Checking for the availability of MySQL Server deployment"; while ! nc -z mysql 3306; do sleep 1; printf "-"; done; echo -e " >> MySQL DB Server has started";'] 21 | containers: 22 | - name: usermgmt-webapp 23 | image: stacksimplify/kube-usermgmt-webapp:1.0.0-MySQLDB 24 | imagePullPolicy: Always 25 | ports: 26 | - containerPort: 8080 27 | env: 28 | - name: DB_HOSTNAME 29 | value: "mysql" 30 | - name: DB_PORT 31 | value: "3306" 32 | - name: DB_NAME 33 | value: "webappdb" 34 | - name: DB_USERNAME 35 | value: "root" 36 | - name: DB_PASSWORD 37 | valueFrom: 38 | secretKeyRef: 39 | name: mysql-db-password 40 | key: db-password 41 | -------------------------------------------------------------------------------- /10-Ingress-Context-Path-Based-Routing/kube-manifests/03-UserMgmtWebApp-Manifests/06-UserMgmtWebApp-Service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: usermgmt-webapp-clusterip-service 5 | labels: 6 | app: usermgmt-webapp 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | app: usermgmt-webapp 11 | ports: 12 | - port: 80 13 | targetPort: 8080 14 | 15 | -------------------------------------------------------------------------------- /10-Ingress-Context-Path-Based-Routing/kube-manifests/03-UserMgmtWebApp-Manifests/07-Kubernetes-Secrets.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: mysql-db-password 5 | type: Opaque 6 | data: 7 | db-password: ZGJwYXNzd29yZDEx 8 | 9 | 10 | -------------------------------------------------------------------------------- /10-Ingress-Context-Path-Based-Routing/kube-manifests/04-IngressService-Manifests/01-Ingress-Context-Path-Based-Routing.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1beta1 2 | kind: Ingress 3 | metadata: 4 | name: ingress-cpr 5 | spec: 6 | rules: 7 | - http: 8 | paths: 9 | - path: /app1/ 10 | backend: 11 | serviceName: app1-nginx-clusterip-service 12 | servicePort: 80 13 | - path: /app2/ 14 | backend: 15 | serviceName: app2-nginx-clusterip-service 16 | servicePort: 80 17 | - path: / 18 | backend: 19 | serviceName: usermgmt-webapp-clusterip-service 20 | servicePort: 80 21 | 22 | -------------------------------------------------------------------------------- /11-Delegate-Domain-from-AWS-Route53-to-Azure-DNS/README.md: -------------------------------------------------------------------------------- 1 | # Delegate Domain to Azure DNS 2 | 3 | ## Step-01: Introduction 4 | - Understand about 5 | - Domain Registrar 6 | - DNS Zones 7 | - Learn to delegate a domain from AWS Route53 to Azure DNS by creating DNS Zones in Azure Cloud 8 | 9 | [![Image](https://www.stacksimplify.com/course-images/azure-aks-delegate-domain-to-azure-dns.png "Azure AKS Kubernetes - Masterclass")](https://www.udemy.com/course/aws-eks-kubernetes-masterclass-devops-microservices/?referralCode=257C9AD5B5AF8D12D1E1) 10 | 11 | 12 | ## Step-02: DNS Zones - Create DNS Zone 13 | - Go to Service -> **DNS Zones** 14 | - **Subscription:** StackSimplify-Paid-Subscription (You need to have a paid subscription for this) 15 | - **Resource Group:** dns-zones 16 | - **Name:** kubeoncloud.com 17 | - **Resource Group Location:** East US 18 | - Click on **Review + Create** 19 | 20 | ## Step-03: Make a note of Azure Nameservers 21 | - Go to Services -> **DNS Zones** -> **kubeoncloud.com** 22 | - Make a note of Nameservers 23 | ``` 24 | ns1-04.azure-dns.com. 25 | ns2-04.azure-dns.net. 26 | ns3-04.azure-dns.org. 27 | ns4-04.azure-dns.info. 28 | ``` 29 | 30 | ## Step-04: Update Nameservers at your Domain provider (Mine is AWS) 31 | - **Verify before updation** 32 | ``` 33 | nslookup -type=SOA kubeoncloud.com 34 | nslookup -type=NS kubeoncloud.com 35 | ``` 36 | - Go to AWS Route53 (This is my Domain Provider) 37 | - Go to Services -> Route53 -> Registered Domains -> kubeoncloud.com 38 | - Click on **Add or edit name servers** 39 | - Update Azure Name servers here and click on **Update** 40 | - Click on **Hosted Zones** 41 | - Delete the hosted zone with name **kubeoncloud.com** 42 | - **Verify after updation** 43 | ``` 44 | nslookup -type=SOA kubeoncloud.com 8.8.8.8 45 | nslookup -type=NS kubeoncloud.com 8.8.8.8 46 | ``` 47 | -------------------------------------------------------------------------------- /12-ExternalDNS-for-AzureDNS-on-AKS/kube-manifests/01-ExternalDNS/azure.json: -------------------------------------------------------------------------------- 1 | { 2 | "tenantId": "c81f465b-99f9-42d3-a169-8082d61c677a", 3 | "subscriptionId": "82808767-144c-4c66-a320-b30791668b0a", 4 | "resourceGroup": "dns-zones", 5 | "useManagedIdentityExtension": true, 6 | "userAssignedIdentityID": "97e867dc-ee8c-4f89-bb81-db7c36dca3dc" 7 | } 8 | -------------------------------------------------------------------------------- /12-ExternalDNS-for-AzureDNS-on-AKS/kube-manifests/01-ExternalDNS/external-dns.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: external-dns 5 | --- 6 | apiVersion: rbac.authorization.k8s.io/v1beta1 7 | kind: ClusterRole 8 | metadata: 9 | name: external-dns 10 | rules: 11 | - apiGroups: [""] 12 | resources: ["services","endpoints","pods"] 13 | verbs: ["get","watch","list"] 14 | - apiGroups: ["extensions","networking.k8s.io"] 15 | resources: ["ingresses"] 16 | verbs: ["get","watch","list"] 17 | - apiGroups: [""] 18 | resources: ["nodes"] 19 | verbs: ["list"] 20 | --- 21 | apiVersion: rbac.authorization.k8s.io/v1beta1 22 | kind: ClusterRoleBinding 23 | metadata: 24 | name: external-dns-viewer 25 | roleRef: 26 | apiGroup: rbac.authorization.k8s.io 27 | kind: ClusterRole 28 | name: external-dns 29 | subjects: 30 | - kind: ServiceAccount 31 | name: external-dns 32 | namespace: default 33 | --- 34 | apiVersion: apps/v1 35 | kind: Deployment 36 | metadata: 37 | name: external-dns 38 | spec: 39 | strategy: 40 | type: Recreate 41 | selector: 42 | matchLabels: 43 | app: external-dns 44 | template: 45 | metadata: 46 | labels: 47 | app: external-dns 48 | spec: 49 | serviceAccountName: external-dns 50 | containers: 51 | - name: external-dns 52 | image: registry.opensource.zalan.do/teapot/external-dns:latest 53 | args: 54 | - --source=service 55 | - --source=ingress 56 | #- --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. 57 | - --provider=azure 58 | #- --azure-resource-group=externaldns # (optional) use the DNS zones from the specific resource group 59 | volumeMounts: 60 | - name: azure-config-file 61 | mountPath: /etc/kubernetes 62 | readOnly: true 63 | volumes: 64 | - name: azure-config-file 65 | secret: 66 | secretName: azure-config-file -------------------------------------------------------------------------------- /12-ExternalDNS-for-AzureDNS-on-AKS/kube-manifests/02-NginxApp1/01-NginxApp1-Deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: app1-nginx-deployment 5 | labels: 6 | app: app1-nginx 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: app1-nginx 12 | template: 13 | metadata: 14 | labels: 15 | app: app1-nginx 16 | spec: 17 | containers: 18 | - name: app1-nginx 19 | image: stacksimplify/kube-nginxapp1:1.0.0 20 | ports: 21 | - containerPort: 80 22 | 23 | -------------------------------------------------------------------------------- /12-ExternalDNS-for-AzureDNS-on-AKS/kube-manifests/02-NginxApp1/02-NginxApp1-ClusterIP-Service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: app1-nginx-clusterip-service 5 | labels: 6 | app: app1-nginx 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | app: app1-nginx 11 | ports: 12 | - port: 80 13 | targetPort: 80 14 | -------------------------------------------------------------------------------- /12-ExternalDNS-for-AzureDNS-on-AKS/kube-manifests/02-NginxApp1/03-Ingress-with-ExternalDNS.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1beta1 2 | kind: Ingress 3 | metadata: 4 | name: nginxapp1-ingress-service 5 | annotations: 6 | kubernetes.io/ingress.class: "nginx" 7 | spec: 8 | rules: 9 | - host: eapp1.kubeoncloud.com 10 | http: 11 | paths: 12 | - path: / 13 | backend: 14 | serviceName: app1-nginx-clusterip-service 15 | servicePort: 80 16 | -------------------------------------------------------------------------------- /13-Ingress-ExternalDNS-Domain-Name-Based-Routing/README.md: -------------------------------------------------------------------------------- 1 | # Ingress - Domain Name Based Routing 2 | 3 | ## Step-01: Introduction 4 | - We are going to implement Domain Name based routing using Ingress 5 | - We are going to use 3 applications for this. 6 | 7 | [![Image](https://www.stacksimplify.com/course-images/azure-aks-ingress-domain-name-based-routing.png "Azure AKS Kubernetes - Masterclass")](https://www.udemy.com/course/aws-eks-kubernetes-masterclass-devops-microservices/?referralCode=257C9AD5B5AF8D12D1E1) 8 | 9 | ## Step-02: Review k8s Application Manifests 10 | - App1 Manifests 11 | - App2 Manifests 12 | - App3 Manifests 13 | 14 | ## Step-03: Review Ingress Service Manifests 15 | - 01-Ingress-DomainName-Based-Routing-app1-2-3.yml 16 | 17 | 18 | ## Step-04: Deploy and Verify 19 | ``` 20 | # Deploy Apps 21 | kubectl apply -R -f kube-manifests/ 22 | 23 | # List Pods 24 | kubectl get pods 25 | 26 | # List Services 27 | kubectl get svc 28 | 29 | # List Ingress 30 | kubectl get ingress 31 | 32 | # Verify Ingress Controller Logs 33 | kubectl get pods -n ingress-basic 34 | kubectl logs -f -n ingress-basic 35 | 36 | # Verify External DNS pod to ensure record set got deleted 37 | kubectl logs -f $(kubectl get po | egrep -o 'external-dns[A-Za-z0-9-]+') 38 | 39 | 40 | # Verify Record set got automatically deleted in DNS Zones 41 | # Template Command 42 | az network dns record-set a list -g -z 43 | 44 | # Replace DNS Zones Resource Group and yourdomain 45 | az network dns record-set a list -g dns-zones -z kubeoncloud.com 46 | ``` 47 | 48 | ## Step-05: Access Applications 49 | ``` 50 | # Access App1 51 | http://eapp1.kubeoncloud.com/app1/index.html 52 | 53 | # Access App2 54 | http://eapp2.kubeoncloud.com/app2/index.html 55 | 56 | # Access Usermgmt Web App 57 | http://eapp3.kubeoncloud.com 58 | Username: admin101 59 | Password: password101 60 | 61 | ``` 62 | 63 | ## Step-06: Clean-Up Applications 64 | ``` 65 | # Delete Apps 66 | kubectl delete -R -f kube-manifests/ 67 | 68 | # Verify Record set got automatically deleted in DNS Zones 69 | # Template Command 70 | az network dns record-set a list -g -z 71 | 72 | # Replace DNS Zones Resource Group and yourdomain 73 | az network dns record-set a list -g dns-zones -z kubeoncloud.com 74 | ``` 75 | 76 | ## Ingress Annotation Reference 77 | - https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/ 78 | 79 | ## Other References 80 | - https://docs.nginx.com/nginx-ingress-controller/ 81 | 82 | -------------------------------------------------------------------------------- /13-Ingress-ExternalDNS-Domain-Name-Based-Routing/kube-manifests/01-NginxApp1-Manifests/01-NginxApp1-Deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: app1-nginx-deployment 5 | labels: 6 | app: app1-nginx 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: app1-nginx 12 | template: 13 | metadata: 14 | labels: 15 | app: app1-nginx 16 | spec: 17 | containers: 18 | - name: app1-nginx 19 | image: stacksimplify/kube-nginxapp1:1.0.0 20 | ports: 21 | - containerPort: 80 22 | 23 | -------------------------------------------------------------------------------- /13-Ingress-ExternalDNS-Domain-Name-Based-Routing/kube-manifests/01-NginxApp1-Manifests/02-NginxApp1-ClusterIP-Service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: app1-nginx-clusterip-service 5 | labels: 6 | app: app1-nginx 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | app: app1-nginx 11 | ports: 12 | - port: 80 13 | targetPort: 80 14 | -------------------------------------------------------------------------------- /13-Ingress-ExternalDNS-Domain-Name-Based-Routing/kube-manifests/02-NginxApp2-Manifets/01-NginxApp2-Deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: app2-nginx-deployment 5 | labels: 6 | app: app2-nginx 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: app2-nginx 12 | template: 13 | metadata: 14 | labels: 15 | app: app2-nginx 16 | spec: 17 | containers: 18 | - name: app2-nginx 19 | image: stacksimplify/kube-nginxapp2:1.0.0 20 | ports: 21 | - containerPort: 80 22 | -------------------------------------------------------------------------------- /13-Ingress-ExternalDNS-Domain-Name-Based-Routing/kube-manifests/02-NginxApp2-Manifets/02-NginxApp2-ClusterIP-Service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: app2-nginx-clusterip-service 5 | labels: 6 | app: app2-nginx 7 | annotations: 8 | spec: 9 | type: ClusterIP 10 | selector: 11 | app: app2-nginx 12 | ports: 13 | - port: 80 14 | targetPort: 80 15 | 16 | -------------------------------------------------------------------------------- /13-Ingress-ExternalDNS-Domain-Name-Based-Routing/kube-manifests/03-UserMgmtWebApp-Manifests/01-persistent-volume-claim.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: azure-managed-disk-pvc 5 | spec: 6 | accessModes: 7 | - ReadWriteOnce 8 | storageClassName: managed-premium 9 | resources: 10 | requests: 11 | storage: 5Gi 12 | 13 | # AKS already provisioned Storage classes managed-premium and default as part of 14 | # default cluster setup -------------------------------------------------------------------------------- /13-Ingress-ExternalDNS-Domain-Name-Based-Routing/kube-manifests/03-UserMgmtWebApp-Manifests/02-UserManagement-ConfigMap.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: usermanagement-dbcreation-script 5 | data: 6 | mysql_usermgmt.sql: |- 7 | DROP DATABASE IF EXISTS webappdb; 8 | CREATE DATABASE webappdb; -------------------------------------------------------------------------------- /13-Ingress-ExternalDNS-Domain-Name-Based-Routing/kube-manifests/03-UserMgmtWebApp-Manifests/03-mysql-deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: mysql 5 | spec: 6 | replicas: 1 7 | selector: 8 | matchLabels: 9 | app: mysql 10 | strategy: 11 | type: Recreate 12 | template: 13 | metadata: 14 | labels: 15 | app: mysql 16 | spec: 17 | containers: 18 | - name: mysql 19 | image: mysql:5.6 20 | env: 21 | - name: MYSQL_ROOT_PASSWORD 22 | valueFrom: 23 | secretKeyRef: 24 | name: mysql-db-password 25 | key: db-password 26 | ports: 27 | - containerPort: 3306 28 | name: mysql 29 | volumeMounts: 30 | - name: mysql-persistent-storage 31 | mountPath: /var/lib/mysql 32 | - name: usermanagement-dbcreation-script 33 | mountPath: /docker-entrypoint-initdb.d #https://hub.docker.com/_/mysql Refer Initializing a fresh instance 34 | volumes: 35 | - name: mysql-persistent-storage 36 | persistentVolumeClaim: 37 | claimName: azure-managed-disk-pvc 38 | - name: usermanagement-dbcreation-script 39 | configMap: 40 | name: usermanagement-dbcreation-script -------------------------------------------------------------------------------- /13-Ingress-ExternalDNS-Domain-Name-Based-Routing/kube-manifests/03-UserMgmtWebApp-Manifests/04-mysql-clusterip-service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: mysql 5 | spec: 6 | selector: 7 | app: mysql 8 | ports: 9 | - port: 3306 10 | clusterIP: None # This means we are going to use Pod IP -------------------------------------------------------------------------------- /13-Ingress-ExternalDNS-Domain-Name-Based-Routing/kube-manifests/03-UserMgmtWebApp-Manifests/05-UserMgmtWebApp-Deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: usermgmt-webapp 5 | labels: 6 | app: usermgmt-webapp 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: usermgmt-webapp 12 | template: 13 | metadata: 14 | labels: 15 | app: usermgmt-webapp 16 | spec: 17 | initContainers: 18 | - name: init-db 19 | image: busybox:1.31 20 | command: ['sh', '-c', 'echo -e "Checking for the availability of MySQL Server deployment"; while ! nc -z mysql 3306; do sleep 1; printf "-"; done; echo -e " >> MySQL DB Server has started";'] 21 | containers: 22 | - name: usermgmt-webapp 23 | image: stacksimplify/kube-usermgmt-webapp:1.0.0-MySQLDB 24 | imagePullPolicy: Always 25 | ports: 26 | - containerPort: 8080 27 | env: 28 | - name: DB_HOSTNAME 29 | value: "mysql" 30 | - name: DB_PORT 31 | value: "3306" 32 | - name: DB_NAME 33 | value: "webappdb" 34 | - name: DB_USERNAME 35 | value: "root" 36 | - name: DB_PASSWORD 37 | valueFrom: 38 | secretKeyRef: 39 | name: mysql-db-password 40 | key: db-password 41 | -------------------------------------------------------------------------------- /13-Ingress-ExternalDNS-Domain-Name-Based-Routing/kube-manifests/03-UserMgmtWebApp-Manifests/06-UserMgmtWebApp-Service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: usermgmt-webapp-clusterip-service 5 | labels: 6 | app: usermgmt-webapp 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | app: usermgmt-webapp 11 | ports: 12 | - port: 80 13 | targetPort: 8080 14 | 15 | -------------------------------------------------------------------------------- /13-Ingress-ExternalDNS-Domain-Name-Based-Routing/kube-manifests/03-UserMgmtWebApp-Manifests/07-Kubernetes-Secrets.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: mysql-db-password 5 | type: Opaque 6 | data: 7 | db-password: ZGJwYXNzd29yZDEx 8 | 9 | 10 | -------------------------------------------------------------------------------- /13-Ingress-ExternalDNS-Domain-Name-Based-Routing/kube-manifests/04-IngressService-Manifests/01-Ingress-DomainName-Based-Routing-app1-2-3.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1beta1 2 | kind: Ingress 3 | metadata: 4 | name: ingress-app1-app2-app3 5 | annotations: 6 | kubernetes.io/ingress.class: "nginx" 7 | spec: 8 | rules: 9 | - host: eapp1.kubeoncloud.com 10 | http: 11 | paths: 12 | - path: / 13 | backend: 14 | serviceName: app1-nginx-clusterip-service 15 | servicePort: 80 16 | - host: eapp2.kubeoncloud.com 17 | http: 18 | paths: 19 | - path: / 20 | backend: 21 | serviceName: app2-nginx-clusterip-service 22 | servicePort: 80 23 | - host: eapp3.kubeoncloud.com 24 | http: 25 | paths: 26 | - path: / 27 | backend: 28 | serviceName: usermgmt-webapp-clusterip-service 29 | servicePort: 80 30 | -------------------------------------------------------------------------------- /14-Ingress-SSL-with-LetsEncrypt/kube-manifests/01-CertManager-ClusterIssuer/cluster-issuer.yml: -------------------------------------------------------------------------------- 1 | apiVersion: cert-manager.io/v1alpha2 2 | kind: ClusterIssuer 3 | metadata: 4 | name: letsencrypt 5 | spec: 6 | acme: 7 | server: https://acme-v02.api.letsencrypt.org/directory 8 | email: dkalyanreddy@gmail.com 9 | privateKeySecretRef: 10 | name: letsencrypt 11 | solvers: 12 | - http01: 13 | ingress: 14 | class: nginx 15 | 16 | -------------------------------------------------------------------------------- /14-Ingress-SSL-with-LetsEncrypt/kube-manifests/02-Demo-Applications/01-NginxApp1-Deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: app1-nginx-deployment 5 | labels: 6 | app: app1-nginx 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: app1-nginx 12 | template: 13 | metadata: 14 | labels: 15 | app: app1-nginx 16 | spec: 17 | containers: 18 | - name: app1-nginx 19 | image: stacksimplify/kube-nginxapp1:1.0.0 20 | ports: 21 | - containerPort: 80 22 | 23 | -------------------------------------------------------------------------------- /14-Ingress-SSL-with-LetsEncrypt/kube-manifests/02-Demo-Applications/02-NginxApp1-ClusterIP-Service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: app1-nginx-clusterip-service 5 | labels: 6 | app: app1-nginx 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | app: app1-nginx 11 | ports: 12 | - port: 80 13 | targetPort: 80 14 | -------------------------------------------------------------------------------- /14-Ingress-SSL-with-LetsEncrypt/kube-manifests/02-Demo-Applications/03-NginxApp2-Deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: app2-nginx-deployment 5 | labels: 6 | app: app2-nginx 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: app2-nginx 12 | template: 13 | metadata: 14 | labels: 15 | app: app2-nginx 16 | spec: 17 | containers: 18 | - name: app2-nginx 19 | image: stacksimplify/kube-nginxapp2:1.0.0 20 | ports: 21 | - containerPort: 80 22 | -------------------------------------------------------------------------------- /14-Ingress-SSL-with-LetsEncrypt/kube-manifests/02-Demo-Applications/04-NginxApp2-ClusterIP-Service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: app2-nginx-clusterip-service 5 | labels: 6 | app: app2-nginx 7 | annotations: 8 | spec: 9 | type: ClusterIP 10 | selector: 11 | app: app2-nginx 12 | ports: 13 | - port: 80 14 | targetPort: 80 15 | 16 | -------------------------------------------------------------------------------- /14-Ingress-SSL-with-LetsEncrypt/kube-manifests/03-Ingress-SSL-Resource/01-Ingress-SSL.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1beta1 2 | kind: Ingress 3 | metadata: 4 | name: ingress-ssl 5 | annotations: 6 | kubernetes.io/ingress.class: "nginx" 7 | cert-manager.io/cluster-issuer: letsencrypt 8 | spec: 9 | rules: 10 | - host: sapp1.kubeoncloud.com 11 | http: 12 | paths: 13 | - path: / 14 | backend: 15 | serviceName: app1-nginx-clusterip-service 16 | servicePort: 80 17 | - host: sapp2.kubeoncloud.com 18 | http: 19 | paths: 20 | - path: / 21 | backend: 22 | serviceName: app2-nginx-clusterip-service 23 | servicePort: 80 24 | tls: 25 | - hosts: 26 | - sapp1.kubeoncloud.com 27 | secretName: sapp1-kubeoncloud-secret 28 | - hosts: 29 | - sapp2.kubeoncloud.com 30 | secretName: sapp2-kubeoncloud-secret 31 | 32 | 33 | -------------------------------------------------------------------------------- /15-Kubernetes-Requests-Limits/kube-manifests-v1/01-NginxApp1-Deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: app1-nginx-deployment 5 | labels: 6 | app: app1-nginx 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: app1-nginx 12 | template: 13 | metadata: 14 | labels: 15 | app: app1-nginx 16 | spec: 17 | containers: 18 | - name: app1-nginx 19 | image: stacksimplify/kube-nginxapp1:1.0.0 20 | imagePullPolicy: Always 21 | ports: 22 | - containerPort: 80 23 | # Requests & Limits 24 | resources: 25 | requests: 26 | cpu: "100m" 27 | memory: "128Mi" 28 | limits: 29 | cpu: "200m" 30 | memory: "256Mi" 31 | -------------------------------------------------------------------------------- /15-Kubernetes-Requests-Limits/kube-manifests-v1/02-NginxApp1-LoadBalancer-Service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: app1-nginx-clusterip-service 5 | labels: 6 | app: app1-nginx 7 | spec: 8 | type: LoadBalancer 9 | selector: 10 | app: app1-nginx 11 | ports: 12 | - port: 80 13 | targetPort: 80 14 | -------------------------------------------------------------------------------- /15-Kubernetes-Requests-Limits/kube-manifests-v2/01-persistent-volume-claim.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: azure-managed-disk-pvc 5 | spec: 6 | accessModes: 7 | - ReadWriteOnce 8 | storageClassName: managed-premium 9 | resources: 10 | requests: 11 | storage: 5Gi 12 | 13 | # AKS already provisioned Storage classes managed-premium and default as part of 14 | # default cluster setup -------------------------------------------------------------------------------- /15-Kubernetes-Requests-Limits/kube-manifests-v2/02-UserManagement-ConfigMap.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: usermanagement-dbcreation-script 5 | data: 6 | mysql_usermgmt.sql: |- 7 | DROP DATABASE IF EXISTS webappdb; 8 | CREATE DATABASE webappdb; -------------------------------------------------------------------------------- /15-Kubernetes-Requests-Limits/kube-manifests-v2/03-mysql-deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: mysql 5 | spec: 6 | replicas: 1 7 | selector: 8 | matchLabels: 9 | app: mysql 10 | strategy: 11 | type: Recreate 12 | template: 13 | metadata: 14 | labels: 15 | app: mysql 16 | spec: 17 | containers: 18 | - name: mysql 19 | image: mysql:5.6 20 | env: 21 | - name: MYSQL_ROOT_PASSWORD 22 | valueFrom: 23 | secretKeyRef: 24 | name: mysql-db-password 25 | key: db-password 26 | ports: 27 | - containerPort: 3306 28 | name: mysql 29 | volumeMounts: 30 | - name: mysql-persistent-storage 31 | mountPath: /var/lib/mysql 32 | - name: usermanagement-dbcreation-script 33 | mountPath: /docker-entrypoint-initdb.d #https://hub.docker.com/_/mysql Refer Initializing a fresh instance 34 | volumes: 35 | - name: mysql-persistent-storage 36 | persistentVolumeClaim: 37 | claimName: azure-managed-disk-pvc 38 | - name: usermanagement-dbcreation-script 39 | configMap: 40 | name: usermanagement-dbcreation-script -------------------------------------------------------------------------------- /15-Kubernetes-Requests-Limits/kube-manifests-v2/04-mysql-clusterip-service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: mysql 5 | spec: 6 | selector: 7 | app: mysql 8 | ports: 9 | - port: 3306 10 | clusterIP: None # This means we are going to use Pod IP -------------------------------------------------------------------------------- /15-Kubernetes-Requests-Limits/kube-manifests-v2/05-UserMgmtWebApp-Deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: usermgmt-webapp 5 | labels: 6 | app: usermgmt-webapp 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: usermgmt-webapp 12 | template: 13 | metadata: 14 | labels: 15 | app: usermgmt-webapp 16 | spec: 17 | initContainers: 18 | - name: init-db 19 | image: busybox:1.31 20 | command: ['sh', '-c', 'echo -e "Checking for the availability of MySQL Server deployment"; while ! nc -z mysql 3306; do sleep 1; printf "-"; done; echo -e " >> MySQL DB Server has started";'] 21 | containers: 22 | - name: usermgmt-webapp 23 | image: stacksimplify/kube-usermgmt-webapp:1.0.0-MySQLDB 24 | imagePullPolicy: Always 25 | # Requests & Limits for usermgmt-webapp Container 26 | resources: 27 | requests: 28 | cpu: "500m" 29 | memory: "128Mi" 30 | limits: 31 | cpu: "1000m" 32 | memory: "500Mi" 33 | ports: 34 | - containerPort: 8080 35 | env: 36 | - name: DB_HOSTNAME 37 | value: "mysql" 38 | - name: DB_PORT 39 | value: "3306" 40 | - name: DB_NAME 41 | value: "webappdb" 42 | - name: DB_USERNAME 43 | value: "root" 44 | - name: DB_PASSWORD 45 | valueFrom: 46 | secretKeyRef: 47 | name: mysql-db-password 48 | key: db-password 49 | -------------------------------------------------------------------------------- /15-Kubernetes-Requests-Limits/kube-manifests-v2/06-UserMgmtWebApp-Service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: usermgmt-webapp-clusterip-service 5 | labels: 6 | app: usermgmt-webapp 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | app: usermgmt-webapp 11 | ports: 12 | - port: 80 13 | targetPort: 8080 14 | 15 | -------------------------------------------------------------------------------- /15-Kubernetes-Requests-Limits/kube-manifests-v2/07-Kubernetes-Secrets.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: mysql-db-password 5 | type: Opaque 6 | data: 7 | db-password: ZGJwYXNzd29yZDEx 8 | 9 | 10 | -------------------------------------------------------------------------------- /16-Kubernetes-Namespaces/16-01-Namespaces-Imperative/kube-manifests/01-NginxApp1-Deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: app1-nginx-deployment 5 | labels: 6 | app: app1-nginx 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: app1-nginx 12 | template: 13 | metadata: 14 | labels: 15 | app: app1-nginx 16 | spec: 17 | containers: 18 | - name: app1-nginx 19 | image: stacksimplify/kube-nginxapp1:1.0.0 20 | imagePullPolicy: Always 21 | ports: 22 | - containerPort: 80 23 | # Requests & Limits 24 | resources: 25 | requests: 26 | cpu: "100m" 27 | memory: "128Mi" 28 | limits: 29 | cpu: "200m" 30 | memory: "256Mi" 31 | -------------------------------------------------------------------------------- /16-Kubernetes-Namespaces/16-01-Namespaces-Imperative/kube-manifests/02-NginxApp1-LoadBalancer-Service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: app1-nginx-service 5 | labels: 6 | app: app1-nginx 7 | spec: 8 | type: LoadBalancer 9 | selector: 10 | app: app1-nginx 11 | ports: 12 | - port: 80 13 | targetPort: 80 14 | -------------------------------------------------------------------------------- /16-Kubernetes-Namespaces/16-02-Namespaces-LimitRange-default/kube-manifests/00-namespace-LimitRange-default.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: dev3 5 | --- 6 | apiVersion: v1 7 | kind: LimitRange 8 | metadata: 9 | name: default-cpu-mem-limit-range 10 | namespace: dev3 11 | spec: 12 | limits: 13 | - default: 14 | cpu: "500m" # If not specified default limit is 1 vCPU per container 15 | memory: "512Mi" # If not specified the Container's memory limit is set to 512Mi, which is the default memory limit for the namespace. 16 | defaultRequest: 17 | cpu: "300m" # If not specified default it will take from whatever specified in limits.default.cpu 18 | memory: "256Mi" # If not specified default it will take from whatever specified in limits.default.memory 19 | type: Container -------------------------------------------------------------------------------- /16-Kubernetes-Namespaces/16-02-Namespaces-LimitRange-default/kube-manifests/01-NginxApp1-Deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: app1-nginx-deployment 5 | labels: 6 | app: app1-nginx 7 | namespace: dev3 8 | spec: 9 | replicas: 1 10 | selector: 11 | matchLabels: 12 | app: app1-nginx 13 | template: 14 | metadata: 15 | labels: 16 | app: app1-nginx 17 | spec: 18 | containers: 19 | - name: app1-nginx 20 | image: stacksimplify/kube-nginxapp1:1.0.0 21 | imagePullPolicy: Always 22 | ports: 23 | - containerPort: 80 24 | -------------------------------------------------------------------------------- /16-Kubernetes-Namespaces/16-02-Namespaces-LimitRange-default/kube-manifests/02-NginxApp1-LoadBalancer-Service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: app1-nginx-service 5 | labels: 6 | app: app1-nginx 7 | namespace: dev3 8 | spec: 9 | type: LoadBalancer 10 | selector: 11 | app: app1-nginx 12 | ports: 13 | - port: 80 14 | targetPort: 80 15 | -------------------------------------------------------------------------------- /16-Kubernetes-Namespaces/16-03-Namespaces-ResourceQuota/kube-manifests/00-namespace-LimitRange-ResourceQuota.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: dev3 5 | --- 6 | apiVersion: v1 7 | kind: LimitRange 8 | metadata: 9 | name: default-cpu-mem-limit-range 10 | namespace: dev3 11 | spec: 12 | limits: 13 | - default: 14 | memory: "512Mi" # If not specified the Container's memory limit is set to 512Mi, which is the default memory limit for the namespace. 15 | cpu: "500m" # If not specified default limit is 1 vCPU per container 16 | defaultRequest: 17 | memory: "256Mi" # If not specified default it will take from whatever specified in limits.default.memory 18 | cpu: "300m" # If not specified default it will take from whatever specified in limits.default.cpu 19 | type: Container 20 | --- 21 | apiVersion: v1 22 | kind: ResourceQuota 23 | metadata: 24 | name: ns-resource-quota 25 | namespace: dev3 26 | spec: 27 | hard: 28 | requests.cpu: "1" 29 | requests.memory: 1Gi 30 | limits.cpu: "2" 31 | limits.memory: 2Gi 32 | pods: "5" 33 | configmaps: "5" 34 | persistentvolumeclaims: "5" 35 | secrets: "5" 36 | services: "5" -------------------------------------------------------------------------------- /16-Kubernetes-Namespaces/16-03-Namespaces-ResourceQuota/kube-manifests/01-NginxApp1-Deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: app1-nginx-deployment 5 | labels: 6 | app: app1-nginx 7 | namespace: dev3 8 | spec: 9 | replicas: 1 10 | selector: 11 | matchLabels: 12 | app: app1-nginx 13 | template: 14 | metadata: 15 | labels: 16 | app: app1-nginx 17 | spec: 18 | containers: 19 | - name: app1-nginx 20 | image: stacksimplify/kube-nginxapp1:1.0.0 21 | imagePullPolicy: Always 22 | ports: 23 | - containerPort: 80 -------------------------------------------------------------------------------- /16-Kubernetes-Namespaces/16-03-Namespaces-ResourceQuota/kube-manifests/02-NginxApp1-LoadBalancer-Service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: app1-nginx-service 5 | labels: 6 | app: app1-nginx 7 | namespace: dev3 8 | spec: 9 | type: LoadBalancer 10 | selector: 11 | app: app1-nginx 12 | ports: 13 | - port: 80 14 | targetPort: 80 15 | -------------------------------------------------------------------------------- /16-Kubernetes-Namespaces/README.md: -------------------------------------------------------------------------------- 1 | # Namespaces 2 | 3 | 1. Namespaces - Imperative using kubectl 4 | 2. Namespaces - Declarative using YAML & LimitRange 5 | 3. Namespaces - Declarative using YAML & ResourceQuota 6 | -------------------------------------------------------------------------------- /17-Azure-VirtualNodes-for-AKS/17-01-Azure-VirtualNodes-Basics/kube-manifests/01-NginxApp1-Deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: app1-nginx-deployment 5 | labels: 6 | app: app1-nginx 7 | spec: 8 | replicas: 2 9 | selector: 10 | matchLabels: 11 | app: app1-nginx 12 | template: 13 | metadata: 14 | labels: 15 | app: app1-nginx 16 | spec: 17 | containers: 18 | - name: app1-nginx 19 | image: stacksimplify/kube-nginxapp1:1.0.0 20 | ports: 21 | - containerPort: 80 22 | # To schedule pods on Azure Virtual Nodes 23 | nodeSelector: 24 | kubernetes.io/role: agent 25 | beta.kubernetes.io/os: linux 26 | type: virtual-kubelet 27 | tolerations: 28 | - key: virtual-kubelet.io/provider 29 | operator: Exists 30 | - key: azure.com/aci 31 | effect: NoSchedule 32 | 33 | -------------------------------------------------------------------------------- /17-Azure-VirtualNodes-for-AKS/17-01-Azure-VirtualNodes-Basics/kube-manifests/02-NginxApp1-LoadBalancer-Service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: app1-nginx-loadbalancer-service 5 | labels: 6 | app: app1-nginx 7 | spec: 8 | type: LoadBalancer 9 | selector: 10 | app: app1-nginx 11 | ports: 12 | - port: 80 13 | targetPort: 80 14 | -------------------------------------------------------------------------------- /17-Azure-VirtualNodes-for-AKS/17-02-Azure-VirtualNodes-MixedMode-Deployments/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Azure AKS Virtual Nodes Mixed Mode Deployments 3 | description: Deploy Applications in mixed mode to Virtual Nodes and AKS Nodepools 4 | --- 5 | 6 | # Azure AKS Virtual Nodes Mixed Mode Deployments 7 | 8 | ## Step-01: Introduction 9 | - We are going to deploy MySQL on regular AKS nodepools (default system nodepool) 10 | - We are going to deploy **User Management Web Application** on Azure Virtual Nodes 11 | - All this we are going to do using NodeSelectors concept in Kubernetes 12 | 13 | [![Image](https://stacksimplify.com/course-images/azure-kubernetes-service-virtual-nodes-mixed-mode-deployments.png "Azure AKS Kubernetes - Masterclass")](https://stacksimplify.com/course-images/azure-kubernetes-service-virtual-nodes-mixed-mode-deployments.png) 14 | 15 | ## Step-02: Review Kubernetes Manifests 16 | ### MySQL Deployment 17 | - **File Name:** 04-mysql-deployment.yml 18 | - No changes in it, MySQL pod will get scheduled on default AKS nodepool 19 | 20 | ### User Management Web Application Deployment 21 | - **File Name:** 06-UserMgmtWebApp-Deployment.yml 22 | - User Management web app pod will schedule on Azure Virtual Node 23 | ```yaml 24 | # To schedule pods on Azure Virtual Nodes 25 | nodeSelector: 26 | kubernetes.io/role: agent 27 | beta.kubernetes.io/os: linux 28 | type: virtual-kubelet 29 | tolerations: 30 | - key: virtual-kubelet.io/provider 31 | operator: Exists 32 | - key: azure.com/aci 33 | effect: NoSchedule 34 | ``` 35 | 36 | ## Step-03: Deploy App & Test 37 | ``` 38 | # Deploy 39 | kubectl apply -f kube-manifests/ 40 | 41 | # Verify Pods 42 | kubectl get pods 43 | 44 | # Verify Pods scheduled on which Nodes 45 | kubectl get pods -o wide 46 | 47 | # List Kubernetes Nodes 48 | kubectl get nodes 49 | kubectl get nodes -o wide 50 | 51 | # List Node Pools 52 | az aks nodepool list --cluster-name aksdemo2 --resource-group aks-rg2 --output table 53 | 54 | # Access Application 55 | kubectl get svc 56 | http:// 57 | Username: admin101 58 | Password: password101 59 | ``` 60 | 61 | 62 | ## Step-04: Clean-Up Apps 63 | ``` 64 | # Delete App 65 | kubectl delete -f kube-manifests/ 66 | 67 | # Delete this new cluster created for Virtual Nodes (if you want to) 68 | az aks delete --name aksdemo2 --resource-group aks-rg2 69 | ``` 70 | 71 | -------------------------------------------------------------------------------- /17-Azure-VirtualNodes-for-AKS/17-02-Azure-VirtualNodes-MixedMode-Deployments/kube-manifests/01-persistent-volume-claim.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: azure-managed-disk-pvc 5 | spec: 6 | accessModes: 7 | - ReadWriteOnce 8 | storageClassName: managed-premium 9 | resources: 10 | requests: 11 | storage: 5Gi 12 | 13 | # AKS already provisioned Storage classes managed-premium and default as part of 14 | # default cluster setup -------------------------------------------------------------------------------- /17-Azure-VirtualNodes-for-AKS/17-02-Azure-VirtualNodes-MixedMode-Deployments/kube-manifests/02-UserManagement-ConfigMap.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: usermanagement-dbcreation-script 5 | data: 6 | mysql_usermgmt.sql: |- 7 | DROP DATABASE IF EXISTS webappdb; 8 | CREATE DATABASE webappdb; -------------------------------------------------------------------------------- /17-Azure-VirtualNodes-for-AKS/17-02-Azure-VirtualNodes-MixedMode-Deployments/kube-manifests/03-Kubernetes-Secrets.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: mysql-db-password 5 | type: Opaque 6 | data: 7 | db-password: ZGJwYXNzd29yZDEx 8 | 9 | 10 | -------------------------------------------------------------------------------- /17-Azure-VirtualNodes-for-AKS/17-02-Azure-VirtualNodes-MixedMode-Deployments/kube-manifests/04-mysql-deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: mysql 5 | spec: 6 | replicas: 1 7 | selector: 8 | matchLabels: 9 | app: mysql 10 | strategy: 11 | type: Recreate 12 | template: 13 | metadata: 14 | labels: 15 | app: mysql 16 | spec: 17 | containers: 18 | - name: mysql 19 | image: mysql:5.6 20 | env: 21 | - name: MYSQL_ROOT_PASSWORD 22 | valueFrom: 23 | secretKeyRef: 24 | name: mysql-db-password 25 | key: db-password 26 | ports: 27 | - containerPort: 3306 28 | name: mysql 29 | volumeMounts: 30 | - name: mysql-persistent-storage 31 | mountPath: /var/lib/mysql 32 | - name: usermanagement-dbcreation-script 33 | mountPath: /docker-entrypoint-initdb.d #https://hub.docker.com/_/mysql Refer Initializing a fresh instance 34 | volumes: 35 | - name: mysql-persistent-storage 36 | persistentVolumeClaim: 37 | claimName: azure-managed-disk-pvc 38 | - name: usermanagement-dbcreation-script 39 | configMap: 40 | name: usermanagement-dbcreation-script -------------------------------------------------------------------------------- /17-Azure-VirtualNodes-for-AKS/17-02-Azure-VirtualNodes-MixedMode-Deployments/kube-manifests/05-mysql-clusterip-service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: mysql 5 | spec: 6 | selector: 7 | app: mysql 8 | ports: 9 | - port: 3306 10 | clusterIP: None # This means we are going to use Pod IP -------------------------------------------------------------------------------- /17-Azure-VirtualNodes-for-AKS/17-02-Azure-VirtualNodes-MixedMode-Deployments/kube-manifests/06-UserMgmtWebApp-Deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: usermgmt-webapp 5 | labels: 6 | app: usermgmt-webapp 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: usermgmt-webapp 12 | template: 13 | metadata: 14 | labels: 15 | app: usermgmt-webapp 16 | spec: 17 | # Init Containers is a limitation currently in Azure Virtual Nodes 18 | #initContainers: 19 | # - name: init-db 20 | # image: busybox:1.31 21 | # command: ['sh', '-c', 'echo -e "Checking for the availability of MySQL Server deployment"; while ! nc -z mysql 3306; do sleep 1; printf "-"; done; echo -e " >> MySQL DB Server has started";'] 22 | containers: 23 | - name: usermgmt-webapp 24 | image: stacksimplify/kube-usermgmt-webapp:1.0.0-MySQLDB 25 | imagePullPolicy: Always 26 | ports: 27 | - containerPort: 8080 28 | env: 29 | - name: DB_HOSTNAME 30 | # Virtual nodes expect a full DNS name of a service 31 | value: "mysql.default.svc.cluster.local" 32 | - name: DB_PORT 33 | value: "3306" 34 | - name: DB_NAME 35 | value: "webappdb" 36 | - name: DB_USERNAME 37 | value: "root" 38 | - name: DB_PASSWORD 39 | valueFrom: 40 | secretKeyRef: 41 | name: mysql-db-password 42 | key: db-password 43 | # To schedule pods on Azure Virtual Nodes 44 | nodeSelector: 45 | kubernetes.io/role: agent 46 | beta.kubernetes.io/os: linux 47 | type: virtual-kubelet 48 | tolerations: 49 | - key: virtual-kubelet.io/provider 50 | operator: Exists 51 | - key: azure.com/aci 52 | effect: NoSchedule 53 | -------------------------------------------------------------------------------- /17-Azure-VirtualNodes-for-AKS/17-02-Azure-VirtualNodes-MixedMode-Deployments/kube-manifests/07-UserMgmtWebApp-Service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: usermgmt-webapp-loadbalancer-service 5 | labels: 6 | app: usermgmt-webapp 7 | spec: 8 | type: LoadBalancer 9 | selector: 10 | app: usermgmt-webapp 11 | ports: 12 | - port: 80 13 | targetPort: 8080 14 | 15 | -------------------------------------------------------------------------------- /17-Azure-VirtualNodes-for-AKS/README.md: -------------------------------------------------------------------------------- 1 | # Azure Virtual Nodes for Azure Kubernetes Service 2 | 3 | 1. What is [Virtual Kubelet](https://github.com/virtual-kubelet/virtual-kubelet)? 4 | 2. What is [Azure Container Instances - ACI](https://docs.microsoft.com/en-us/azure/container-instances/)? 5 | 3. What are [AKS Virtual Nodes](https://docs.microsoft.com/en-us/azure/aks/virtual-nodes-portal)? 6 | - **Important Note:** Virtual nodes require AKS clusters with [Azure CNI networking](https://docs.microsoft.com/en-us/azure/aks/configure-azure-cni) 7 | 4. Understand and implement basic usecase using Azure Virtual Nodes 8 | 5. **Advanced Implementation:** Implement Mixed Mode Deployments with Azure Virtual Nodes and Azure AKS Nodepools 9 | -------------------------------------------------------------------------------- /18-Azure-Container-Registry-ACR/18-01-ACR-attach-to-AKS/docker-manifests/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nginx 2 | COPY index.html /usr/share/nginx/html -------------------------------------------------------------------------------- /18-Azure-Container-Registry-ACR/18-01-ACR-attach-to-AKS/docker-manifests/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |

Welcome to Stack Simplify - Azure Container Registry (ACR)

5 |

Build and Push Image from Local Docker Desktop to ACR

6 |

Application Version: V1

7 | 8 | 9 | -------------------------------------------------------------------------------- /18-Azure-Container-Registry-ACR/18-01-ACR-attach-to-AKS/kube-manifests/01-acr-Deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: acrdemo-localdocker-deployment 5 | labels: 6 | app: acrdemo-localdocker 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: acrdemo-localdocker 12 | template: 13 | metadata: 14 | labels: 15 | app: acrdemo-localdocker 16 | spec: 17 | containers: 18 | - name: acrdemo-localdocker 19 | image: acrforaksdemo2.azurecr.io/app1/kube-nginx-acr:v1 20 | imagePullPolicy: Always 21 | ports: 22 | - containerPort: 80 23 | 24 | -------------------------------------------------------------------------------- /18-Azure-Container-Registry-ACR/18-01-ACR-attach-to-AKS/kube-manifests/02-acr-LoadBalancer-Service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: acrdemo-localdocker-service 5 | labels: 6 | app: acrdemo-localdocker 7 | spec: 8 | type: LoadBalancer 9 | selector: 10 | app: acrdemo-localdocker 11 | ports: 12 | - port: 80 13 | targetPort: 80 14 | -------------------------------------------------------------------------------- /18-Azure-Container-Registry-ACR/18-02-ACR-not-attached-to-AKS-Schedule-to-NodePools/docker-manifests/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nginx 2 | COPY index.html /usr/share/nginx/html -------------------------------------------------------------------------------- /18-Azure-Container-Registry-ACR/18-02-ACR-not-attached-to-AKS-Schedule-to-NodePools/docker-manifests/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |

Welcome to Stack Simplify - Azure Container Registry (ACR)

5 |

ACR not attached to AKS

6 |

Access ACR from Kubernetes using k8s Secrets & Azure Service Principal

7 |

Application Version: V1

8 | 9 | 10 | -------------------------------------------------------------------------------- /18-Azure-Container-Registry-ACR/18-02-ACR-not-attached-to-AKS-Schedule-to-NodePools/kube-manifests/01-acr-Deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: acrdemo2ss-deployment 5 | labels: 6 | app: acrdemo2ss 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: acrdemo2ss 12 | template: 13 | metadata: 14 | labels: 15 | app: acrdemo2ss 16 | spec: 17 | containers: 18 | - name: acrdemo2ss 19 | image: acrdemo2ss.azurecr.io/app2/acr-app2:v1 # Update Image Name 20 | imagePullPolicy: Always 21 | ports: 22 | - containerPort: 80 23 | imagePullSecrets: # Update Image Pull Secret Name we creted 24 | - name: acrdemo2ss-secret 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /18-Azure-Container-Registry-ACR/18-02-ACR-not-attached-to-AKS-Schedule-to-NodePools/kube-manifests/02-acr-LoadBalancer-Service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: acrdemo2ss-loadbalancer-service 5 | labels: 6 | app: acrdemo2ss 7 | spec: 8 | type: LoadBalancer 9 | selector: 10 | app: acrdemo2ss 11 | ports: 12 | - port: 80 13 | targetPort: 80 14 | -------------------------------------------------------------------------------- /18-Azure-Container-Registry-ACR/18-02-ACR-not-attached-to-AKS-Schedule-to-NodePools/shell-script/generate-service-principal.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Modify for your environment. 4 | # ACR_NAME: The name of your Azure Container Registry 5 | # SERVICE_PRINCIPAL_NAME: Must be unique within your AD tenant 6 | #ACR_NAME= 7 | ACR_NAME=acrdemo2ss 8 | SERVICE_PRINCIPAL_NAME=acr-sp-demo 9 | 10 | # Obtain the full registry ID for subsequent command args 11 | ACR_REGISTRY_ID=$(az acr show --name $ACR_NAME --query id --output tsv) 12 | 13 | # Create the service principal with rights scoped to the registry. 14 | # Default permissions are for docker pull access. Modify the '--role' 15 | # argument value as desired: 16 | # acrpull: pull only 17 | # acrpush: push and pull 18 | # owner: push, pull, and assign roles 19 | SP_PASSWD=$(az ad sp create-for-rbac --name http://$SERVICE_PRINCIPAL_NAME --scopes $ACR_REGISTRY_ID --role acrpull --query password --output tsv) 20 | SP_APP_ID=$(az ad sp show --id http://$SERVICE_PRINCIPAL_NAME --query appId --output tsv) 21 | 22 | # Output the service principal's credentials; use these in your services and 23 | # applications to authenticate to the container registry. 24 | echo "Service principal ID: $SP_APP_ID" 25 | echo "Service principal password: $SP_PASSWD" -------------------------------------------------------------------------------- /18-Azure-Container-Registry-ACR/18-03-ACR-not-attached-to-AKS-Schedule-to-VirtualNodes/docker-manifests/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nginx 2 | COPY index.html /usr/share/nginx/html -------------------------------------------------------------------------------- /18-Azure-Container-Registry-ACR/18-03-ACR-not-attached-to-AKS-Schedule-to-VirtualNodes/docker-manifests/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |

Welcome to Stack Simplify - Azure Container Registry (ACR)

5 |

ACR not attached to AKS

6 |

Access ACR from Kubernetes using k8s Secrets & Azure Service Principal

7 |

Schedule on Azure Virtual Nodes

8 |

Application Version: V1

9 | 10 | 11 | -------------------------------------------------------------------------------- /18-Azure-Container-Registry-ACR/18-03-ACR-not-attached-to-AKS-Schedule-to-VirtualNodes/kube-manifests/01-acr-Deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: acrdemo2ss-deployment 5 | labels: 6 | app: acrdemo2ss 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: acrdemo2ss 12 | template: 13 | metadata: 14 | labels: 15 | app: acrdemo2ss 16 | spec: 17 | containers: 18 | - name: acrdemo2ss-vn 19 | image: acrdemo2ss.azurecr.io/app3/acr-app3:v1 # Update Image Name 20 | imagePullPolicy: Always 21 | ports: 22 | - containerPort: 80 23 | imagePullSecrets: # Update Image Pull Secret Name we creted 24 | - name: acrdemo2ss-secret 25 | # To schedule pods on Azure Virtual Nodes 26 | nodeSelector: 27 | kubernetes.io/role: agent 28 | beta.kubernetes.io/os: linux 29 | type: virtual-kubelet 30 | tolerations: 31 | - key: virtual-kubelet.io/provider 32 | operator: Exists 33 | - key: azure.com/aci 34 | effect: NoSchedule 35 | 36 | 37 | -------------------------------------------------------------------------------- /18-Azure-Container-Registry-ACR/18-03-ACR-not-attached-to-AKS-Schedule-to-VirtualNodes/kube-manifests/02-acr-LoadBalancer-Service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: acrdemo2ss-loadbalancer-service 5 | labels: 6 | app: acrdemo2ss 7 | spec: 8 | type: LoadBalancer 9 | selector: 10 | app: acrdemo2ss 11 | ports: 12 | - port: 80 13 | targetPort: 80 14 | -------------------------------------------------------------------------------- /18-Azure-Container-Registry-ACR/README.md: -------------------------------------------------------------------------------- 1 | # Azure Container Registry Integrate wtih AKS 2 | 3 | 1. Attach Azure Container Registry to AKS 4 | 2. Use Service Principal to access ACR and Schedule workload on AKS Nodepools 5 | 3. Use Service Principal to access ACR and Schedule workload on AKS Virtual Nodes -------------------------------------------------------------------------------- /19-Azure-DevOps-with-AKS/19-01-Azure-DevOps-BuildandPush-to-ACR/01-build-pipeline.yml: -------------------------------------------------------------------------------- 1 | # Docker 2 | # Build and push an image to Azure Container Registry 3 | # https://docs.microsoft.com/azure/devops/pipelines/languages/docker 4 | 5 | trigger: 6 | - master 7 | 8 | resources: 9 | - repo: self 10 | 11 | variables: 12 | # Container registry service connection established during pipeline creation 13 | dockerRegistryServiceConnection: '6a8843fd-7313-48e2-9381-3f9ef59ce82d' 14 | imageRepository: 'app1/app1nginx' 15 | containerRegistry: 'aksdevopsacr.azurecr.io' 16 | dockerfilePath: '$(Build.SourcesDirectory)/Dockerfile' 17 | tag: '$(Build.BuildId)' 18 | 19 | # Agent VM image name 20 | vmImageName: 'ubuntu-latest' 21 | 22 | stages: 23 | - stage: Build 24 | displayName: Build and push stage 25 | jobs: 26 | - job: Build 27 | displayName: Build 28 | pool: 29 | vmImage: $(vmImageName) 30 | steps: 31 | - task: Docker@2 32 | displayName: Build and push an image to container registry 33 | inputs: 34 | command: buildAndPush 35 | repository: $(imageRepository) 36 | dockerfile: $(dockerfilePath) 37 | containerRegistry: $(dockerRegistryServiceConnection) 38 | tags: | 39 | $(tag) 40 | -------------------------------------------------------------------------------- /19-Azure-DevOps-with-AKS/19-01-Azure-DevOps-BuildandPush-to-ACR/Git-Repository-files/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nginx 2 | COPY index.html /usr/share/nginx/html -------------------------------------------------------------------------------- /19-Azure-DevOps-with-AKS/19-01-Azure-DevOps-BuildandPush-to-ACR/Git-Repository-files/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |

Welcome to Stack Simplify - Azure DevOps App1 - V1

5 |

Azure DevOps Demo App1

6 |

Application Version: V1

7 | 8 | 9 | -------------------------------------------------------------------------------- /19-Azure-DevOps-with-AKS/19-01-Azure-DevOps-BuildandPush-to-ACR/Git-Repository-files/kube-manifests/01-Deployment-and-LoadBalancer-Service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: app1-nginx-deployment 5 | labels: 6 | app: app1-nginx 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: app1-nginx 12 | template: 13 | metadata: 14 | labels: 15 | app: app1-nginx 16 | spec: 17 | containers: 18 | - name: app1-nginx 19 | image: aksdevopsacr.azurecr.io/custom2aksnginxapp1 20 | ports: 21 | - containerPort: 80 22 | --- 23 | apiVersion: v1 24 | kind: Service 25 | metadata: 26 | name: app1-nginx-loadbalancer-service 27 | labels: 28 | app: app1-nginx 29 | spec: 30 | type: LoadBalancer 31 | selector: 32 | app: app1-nginx 33 | ports: 34 | - port: 80 35 | targetPort: 80 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /19-Azure-DevOps-with-AKS/19-03-Azure-DevOps-Build-Pipeline-Publish-Artifacts/03-custom1-pipeline-buildandpush-to-acr-and-publish-artifacts.yml: -------------------------------------------------------------------------------- 1 | # Docker 2 | # Build and push an image to Azure Container Registry 3 | # https://docs.microsoft.com/azure/devops/pipelines/languages/docker 4 | 5 | trigger: 6 | - master 7 | 8 | resources: 9 | - repo: self 10 | 11 | variables: 12 | # Container registry service connection established during pipeline creation 13 | dockerRegistryServiceConnection: '3f60d734-2d68-41cf-ae78-e22d45f01a8e' 14 | imageRepository: 'customaksnginxapp1' 15 | containerRegistry: 'aksdevopsacr.azurecr.io' 16 | dockerfilePath: '$(Build.SourcesDirectory)/Dockerfile' 17 | tag: '$(Build.BuildId)' 18 | 19 | # Agent VM image name 20 | vmImageName: 'ubuntu-latest' 21 | 22 | stages: 23 | - stage: Build 24 | displayName: Build and push stage 25 | jobs: 26 | - job: Build 27 | displayName: Build 28 | pool: 29 | vmImage: $(vmImageName) 30 | steps: 31 | - task: Docker@2 32 | displayName: Build and push an image to container registry 33 | inputs: 34 | command: buildAndPush 35 | repository: $(imageRepository) 36 | dockerfile: $(dockerfilePath) 37 | containerRegistry: $(dockerRegistryServiceConnection) 38 | tags: | 39 | $(tag) 40 | ## Publish Artifacts pipeline code in addition to Build and Push 41 | - bash: echo Contents in System Default Working Directory; ls -R $(System.DefaultWorkingDirectory) 42 | - bash: echo Before copying Contents in Build Artifact Directory; ls -R $(Build.ArtifactStagingDirectory) 43 | # Task-2: Copy files (Copy files from a source folder to target folder) 44 | # Source Directory: $(System.DefaultWorkingDirectory)/kube-manifests 45 | # Target Directory: $(Build.ArtifactStagingDirectory) 46 | - task: CopyFiles@2 47 | inputs: 48 | SourceFolder: '$(System.DefaultWorkingDirectory)/kube-manifests' 49 | Contents: '**' 50 | TargetFolder: '$(Build.ArtifactStagingDirectory)' 51 | OverWrite: true 52 | # List files from Build Artifact Staging Directory - After Copy 53 | - bash: echo After copying to Build Artifact Directory; ls -R $(Build.ArtifactStagingDirectory) 54 | # Task-3: Publish build artifacts (Publish build to Azure Pipelines) 55 | - task: PublishBuildArtifacts@1 56 | inputs: 57 | PathtoPublish: '$(Build.ArtifactStagingDirectory)' 58 | ArtifactName: 'kube-manifests' 59 | publishLocation: 'Container' 60 | 61 | -------------------------------------------------------------------------------- /19-Azure-DevOps-with-AKS/19-03-Azure-DevOps-Build-Pipeline-Publish-Artifacts/04-custom2-pipeline-build-from-scratch.yml: -------------------------------------------------------------------------------- 1 | # Stages 2 | # Stage-1: 3 | # Task-1: Build Docker Image and push to Azure Container Registry ACR 4 | # Task-2: Copy kube-manifest files to Build Artifact Directory 5 | # Task-3: Publish build articats to Azure Pipelines 6 | # Pipeline Hierarchial Flow: Stages -> Stage -> Jobs -> Job -> Steps -> Task1, Task2, Task3 7 | 8 | trigger: 9 | - master 10 | 11 | # Variables 12 | variables: 13 | tag: '$(Build.BuildId)' 14 | 15 | stages: 16 | # Build Stage 17 | - stage: Build 18 | displayName: Build Stage 19 | jobs: 20 | - job: Build 21 | displayName: Build Job 22 | pool: 23 | vmImage: 'ubuntu-latest' 24 | steps: 25 | 26 | # Task-1: Build Docker Image and push to Azure Container Registry ACR 27 | - task: Docker@2 28 | inputs: 29 | containerRegistry: 'manual-aksdevopsacr-svc' 30 | repository: 'custom2aksnginxapp1' 31 | command: 'buildAndPush' 32 | Dockerfile: '**/Dockerfile' 33 | tags: | 34 | $(tag) 35 | $(Build.SourceVersion) 36 | ## Publish Artifacts pipeline code in addition to Build and Push 37 | - bash: echo Contents in System Default Working Directory; ls -R $(System.DefaultWorkingDirectory) 38 | - bash: echo Before copying Contents in Build Artifact Directory; ls -R $(Build.ArtifactStagingDirectory) 39 | # Task-2: Copy files (Copy files from a source folder to target folder) 40 | # Source Directory: $(System.DefaultWorkingDirectory)/kube-manifests 41 | # Target Directory: $(Build.ArtifactStagingDirectory) 42 | - task: CopyFiles@2 43 | inputs: 44 | SourceFolder: '$(System.DefaultWorkingDirectory)/kube-manifests' 45 | Contents: '**' 46 | TargetFolder: '$(Build.ArtifactStagingDirectory)' 47 | OverWrite: true 48 | # List files from Build Artifact Staging Directory - After Copy 49 | - bash: echo After copying to Build Artifact Directory; ls -R $(Build.ArtifactStagingDirectory) 50 | # Task-3: Publish build artifacts (Publish build to Azure Pipelines) 51 | - task: PublishBuildArtifacts@1 52 | inputs: 53 | PathtoPublish: '$(Build.ArtifactStagingDirectory)' 54 | ArtifactName: 'kube-manifests' 55 | publishLocation: 'Container' 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /19-Azure-DevOps-with-AKS/19-03-Azure-DevOps-Build-Pipeline-Publish-Artifacts/sample.yml: -------------------------------------------------------------------------------- 1 | 2 | stages: 3 | - stage: Stage-1 4 | jobs: 5 | - job: Job-1 6 | steps: 7 | - script: echo Step-1 8 | - script: echo Step-2 9 | - job: Job-2 10 | steps: 11 | - task: some task step-1 12 | - task: some task step-2 13 | - stage: Stage-2 14 | jobs: 15 | - job: Job-1 16 | steps: 17 | - task: some task step-1 18 | - task: some task step-2 19 | - job: Job-2 20 | steps: 21 | - script: echo Step-1 22 | - script: echo Step-2 23 | -------------------------------------------------------------------------------- /20-Azure-AKS-HTTP-Application-Routing/kube-manifests/01-NginxApp1-Deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: app1-nginx-deployment 5 | labels: 6 | app: app1-nginx 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: app1-nginx 12 | template: 13 | metadata: 14 | labels: 15 | app: app1-nginx 16 | spec: 17 | containers: 18 | - name: app1-nginx 19 | image: stacksimplify/kube-nginxapp1:1.0.0 20 | ports: 21 | - containerPort: 80 22 | 23 | -------------------------------------------------------------------------------- /20-Azure-AKS-HTTP-Application-Routing/kube-manifests/02-NginxApp1-ClusterIP-Service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: app1-nginx-clusterip-service 5 | labels: 6 | app: app1-nginx 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | app: app1-nginx 11 | ports: 12 | - port: 80 13 | targetPort: 80 14 | -------------------------------------------------------------------------------- /20-Azure-AKS-HTTP-Application-Routing/kube-manifests/03-Ingress-HTTPApplicationRouting-ExternalDNS.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1beta1 2 | kind: Ingress 3 | metadata: 4 | name: ingress-demo 5 | annotations: 6 | # Add ingress.class as addon-http-application-routing 7 | kubernetes.io/ingress.class: addon-http-application-routing 8 | spec: 9 | rules: 10 | - host: app1.c8bb03906cd34011a281.centralus.aksapp.io # Add Application DNS name to be registered in DNS 11 | http: 12 | paths: 13 | - path: / 14 | backend: 15 | serviceName: app1-nginx-clusterip-service 16 | servicePort: 80 17 | -------------------------------------------------------------------------------- /21-Azure-AKS-Authentication-and-RBAC/21-03-Kubernetes-RBAC-with-AzureAD-on-AzureAKS/kube-manifests/01-Sample-Application/01-NginxApp1-Deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: app1-nginx-deployment 5 | labels: 6 | app: app1-nginx 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: app1-nginx 12 | template: 13 | metadata: 14 | labels: 15 | app: app1-nginx 16 | spec: 17 | containers: 18 | - name: app1-nginx 19 | image: stacksimplify/kube-nginxapp1:1.0.0 20 | imagePullPolicy: Always 21 | ports: 22 | - containerPort: 80 23 | 24 | -------------------------------------------------------------------------------- /21-Azure-AKS-Authentication-and-RBAC/21-03-Kubernetes-RBAC-with-AzureAD-on-AzureAKS/kube-manifests/01-Sample-Application/02-NginxApp1-LoadBalancer-Service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: app1-nginx-service 5 | labels: 6 | app: app1-nginx 7 | spec: 8 | type: LoadBalancer 9 | selector: 10 | app: app1-nginx 11 | ports: 12 | - port: 80 13 | targetPort: 80 14 | -------------------------------------------------------------------------------- /21-Azure-AKS-Authentication-and-RBAC/21-03-Kubernetes-RBAC-with-AzureAD-on-AzureAKS/kube-manifests/02-Roles-and-RoleBindings/role-dev-namespace.yaml: -------------------------------------------------------------------------------- 1 | kind: Role 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | metadata: 4 | name: dev-user-full-access-role 5 | namespace: dev 6 | rules: 7 | - apiGroups: ["", "extensions", "apps"] 8 | resources: ["*"] 9 | verbs: ["*"] 10 | - apiGroups: ["batch"] 11 | resources: 12 | - jobs 13 | - cronjobs 14 | verbs: ["*"] -------------------------------------------------------------------------------- /21-Azure-AKS-Authentication-and-RBAC/21-03-Kubernetes-RBAC-with-AzureAD-on-AzureAKS/kube-manifests/02-Roles-and-RoleBindings/rolebinding-dev-namespace.yaml: -------------------------------------------------------------------------------- 1 | kind: RoleBinding 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | metadata: 4 | name: dev-user-access-rolebinding 5 | namespace: dev 6 | roleRef: 7 | apiGroup: rbac.authorization.k8s.io 8 | kind: Role 9 | name: dev-user-full-access-role 10 | subjects: 11 | - kind: Group 12 | namespace: dev 13 | #name: groupObjectId # Your Azure AD Group Object ID: devaksteam 14 | name: "4123d819-9ed6-460b-8321-39f02157536b" -------------------------------------------------------------------------------- /21-Azure-AKS-Authentication-and-RBAC/21-04-Kubernetes-RBAC-ClusterRole-ClusterRoleBinding/kube-manifests/ClusterRole-ReadOnlyAccess.yaml: -------------------------------------------------------------------------------- 1 | kind: ClusterRole 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | metadata: 4 | name: aks-cluster-readonly-role 5 | rules: 6 | - apiGroups: ["", "extensions", "apps"] 7 | resources: ["*"] 8 | verbs: ["get", "list", "watch"] 9 | - apiGroups: ["batch"] 10 | resources: 11 | - jobs 12 | - cronjobs 13 | verbs: ["get", "list", "watch"] -------------------------------------------------------------------------------- /21-Azure-AKS-Authentication-and-RBAC/21-04-Kubernetes-RBAC-ClusterRole-ClusterRoleBinding/kube-manifests/ClusterRoleBinding-ReadOnlyAccess.yaml: -------------------------------------------------------------------------------- 1 | kind: ClusterRoleBinding 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | metadata: 4 | name: aks-cluster-readonly-rolebinding 5 | roleRef: 6 | apiGroup: rbac.authorization.k8s.io 7 | kind: ClusterRole 8 | name: aks-cluster-readonly-role 9 | subjects: 10 | - kind: Group 11 | #name: groupObjectId # Your Azure AD Group Object ID: aksreadonly 12 | name: "e8f709f7-4029-4fdb-b786-d0af29445fc9" -------------------------------------------------------------------------------- /22-Azure-AKS-Autoscaling/22-01-Azure-AKS-Cluster-Autoscaler/kube-manifests/01-javaapp-Deployment-Service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: cluster-autoscaler-demoapp-deployment 5 | labels: 6 | app: ca-java-app 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: ca-java-app 12 | template: 13 | metadata: 14 | labels: 15 | app: ca-java-app 16 | spec: 17 | containers: 18 | - name: ca-java-app 19 | #image: stacksimplify/kubenginx:1.0.0 20 | image: stacksimplify/kube-helloworld:1.0.0 21 | ports: 22 | - containerPort: 8080 23 | resources: 24 | requests: 25 | memory: "200Mi" 26 | cpu: "250m" 27 | limits: 28 | memory: "500Mi" 29 | cpu: "500m" 30 | --- 31 | apiVersion: v1 32 | kind: Service 33 | metadata: 34 | name: cluster-autoscaler-demoservice-java-app 35 | labels: 36 | app: ca-java-app 37 | spec: 38 | type: LoadBalancer 39 | selector: 40 | app: ca-java-app 41 | ports: 42 | - port: 80 43 | targetPort: 8080 -------------------------------------------------------------------------------- /22-Azure-AKS-Autoscaling/22-02-Azure-AKS-HPA-Horizontal-Pod-Autoscaler/kube-manifests/apps/01-nginx-app.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: hpa-demo-deployment 5 | labels: 6 | app: hpa-nginx 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: hpa-nginx 12 | template: 13 | metadata: 14 | labels: 15 | app: hpa-nginx 16 | spec: 17 | containers: 18 | - name: hpa-nginx 19 | image: stacksimplify/kubenginx:1.0.0 20 | ports: 21 | - containerPort: 80 22 | resources: 23 | requests: 24 | memory: "128Mi" 25 | cpu: "100m" 26 | limits: 27 | memory: "500Mi" 28 | cpu: "200m" 29 | --- 30 | apiVersion: v1 31 | kind: Service 32 | metadata: 33 | name: hpa-demo-service-nginx 34 | labels: 35 | app: hpa-nginx 36 | spec: 37 | type: LoadBalancer 38 | selector: 39 | app: hpa-nginx 40 | ports: 41 | - port: 80 42 | targetPort: 80 43 | -------------------------------------------------------------------------------- /22-Azure-AKS-Autoscaling/22-02-Azure-AKS-HPA-Horizontal-Pod-Autoscaler/kube-manifests/hpa-manifest/hpa-manifest.yml: -------------------------------------------------------------------------------- 1 | apiVersion: autoscaling/v1 2 | kind: HorizontalPodAutoscaler 3 | metadata: 4 | name: hpa-demo-declarative 5 | spec: 6 | maxReplicas: 10 # define max replica count 7 | minReplicas: 1 # define min replica count 8 | scaleTargetRef: 9 | apiVersion: apps/v1 10 | kind: Deployment 11 | name: hpa-demo-deployment 12 | targetCPUUtilizationPercentage: 20 # target CPU utilization -------------------------------------------------------------------------------- /23-AKS-Production-Grade-Cluster-Design-using-az-aks-cli/23-03-k8s-NodeSelectors-Deploy-Apps-Windows-Linux/kube-manifests/01-Webserver-Apps/01-NginxApp1-Deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: app1-nginx-deployment 5 | labels: 6 | app: app1-nginx 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: app1-nginx 12 | template: 13 | metadata: 14 | labels: 15 | app: app1-nginx 16 | spec: 17 | containers: 18 | - name: app1-nginx 19 | image: stacksimplify/kube-nginxapp1:1.0.0 20 | ports: 21 | - containerPort: 80 22 | # To schedule pods on based on NodeSelectors 23 | nodeSelector: 24 | app: system-apps 25 | 26 | 27 | -------------------------------------------------------------------------------- /23-AKS-Production-Grade-Cluster-Design-using-az-aks-cli/23-03-k8s-NodeSelectors-Deploy-Apps-Windows-Linux/kube-manifests/01-Webserver-Apps/02-NginxApp1-LoadBalancer-Service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: app1-nginx-clusterip-service 5 | labels: 6 | app: app1-nginx 7 | spec: 8 | type: LoadBalancer 9 | selector: 10 | app: app1-nginx 11 | ports: 12 | - port: 80 13 | targetPort: 80 14 | -------------------------------------------------------------------------------- /23-AKS-Production-Grade-Cluster-Design-using-az-aks-cli/23-03-k8s-NodeSelectors-Deploy-Apps-Windows-Linux/kube-manifests/02-Java-Apps/01-persistent-volume-claim.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: azure-managed-disk-pvc 5 | spec: 6 | accessModes: 7 | - ReadWriteOnce 8 | storageClassName: managed-premium-retain-sc 9 | resources: 10 | requests: 11 | storage: 5Gi -------------------------------------------------------------------------------- /23-AKS-Production-Grade-Cluster-Design-using-az-aks-cli/23-03-k8s-NodeSelectors-Deploy-Apps-Windows-Linux/kube-manifests/02-Java-Apps/02-UserManagement-ConfigMap.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: usermanagement-dbcreation-script 5 | data: 6 | mysql_usermgmt.sql: |- 7 | DROP DATABASE IF EXISTS webappdb; 8 | CREATE DATABASE webappdb; -------------------------------------------------------------------------------- /23-AKS-Production-Grade-Cluster-Design-using-az-aks-cli/23-03-k8s-NodeSelectors-Deploy-Apps-Windows-Linux/kube-manifests/02-Java-Apps/03-mysql-deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: mysql 5 | spec: 6 | replicas: 1 7 | selector: 8 | matchLabels: 9 | app: mysql 10 | strategy: 11 | type: Recreate 12 | template: 13 | metadata: 14 | labels: 15 | app: mysql 16 | spec: 17 | containers: 18 | - name: mysql 19 | image: mysql:5.6 20 | env: 21 | - name: MYSQL_ROOT_PASSWORD 22 | value: dbpassword11 23 | ports: 24 | - containerPort: 3306 25 | name: mysql 26 | volumeMounts: 27 | - name: mysql-persistent-storage 28 | mountPath: /var/lib/mysql 29 | - name: usermanagement-dbcreation-script 30 | mountPath: /docker-entrypoint-initdb.d #https://hub.docker.com/_/mysql Refer Initializing a fresh instance 31 | volumes: 32 | - name: mysql-persistent-storage 33 | persistentVolumeClaim: 34 | claimName: azure-managed-disk-pvc 35 | - name: usermanagement-dbcreation-script 36 | configMap: 37 | name: usermanagement-dbcreation-script 38 | # To schedule pods on based on NodeSelectors 39 | nodeSelector: 40 | app: java-apps -------------------------------------------------------------------------------- /23-AKS-Production-Grade-Cluster-Design-using-az-aks-cli/23-03-k8s-NodeSelectors-Deploy-Apps-Windows-Linux/kube-manifests/02-Java-Apps/04-mysql-clusterip-service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: mysql 5 | spec: 6 | selector: 7 | app: mysql 8 | ports: 9 | - port: 3306 10 | clusterIP: None # This means we are going to use Pod IP -------------------------------------------------------------------------------- /23-AKS-Production-Grade-Cluster-Design-using-az-aks-cli/23-03-k8s-NodeSelectors-Deploy-Apps-Windows-Linux/kube-manifests/02-Java-Apps/06-UserMgmtWebApp-Deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: usermgmt-webapp 5 | labels: 6 | app: usermgmt-webapp 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: usermgmt-webapp 12 | template: 13 | metadata: 14 | labels: 15 | app: usermgmt-webapp 16 | spec: 17 | initContainers: 18 | - name: init-db 19 | image: busybox:1.31 20 | command: ['sh', '-c', 'echo -e "Checking for the availability of MySQL Server deployment"; while ! nc -z mysql 3306; do sleep 1; printf "-"; done; echo -e " >> MySQL DB Server has started";'] 21 | containers: 22 | - name: usermgmt-webapp 23 | image: stacksimplify/kube-usermgmt-webapp:1.0.0-MySQLDB 24 | imagePullPolicy: Always 25 | ports: 26 | - containerPort: 8080 27 | env: 28 | - name: DB_HOSTNAME 29 | value: "mysql" 30 | - name: DB_PORT 31 | value: "3306" 32 | - name: DB_NAME 33 | value: "webappdb" 34 | - name: DB_USERNAME 35 | value: "root" 36 | - name: DB_PASSWORD 37 | value: "dbpassword11" 38 | # To schedule pods on based on NodeSelectors 39 | nodeSelector: 40 | app: java-apps 41 | 42 | -------------------------------------------------------------------------------- /23-AKS-Production-Grade-Cluster-Design-using-az-aks-cli/23-03-k8s-NodeSelectors-Deploy-Apps-Windows-Linux/kube-manifests/02-Java-Apps/07-UserMgmtWebApp-Service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: usermgmt-webapp-service 5 | labels: 6 | app: usermgmt-webapp 7 | spec: 8 | type: LoadBalancer 9 | selector: 10 | app: usermgmt-webapp 11 | ports: 12 | - port: 80 13 | targetPort: 8080 -------------------------------------------------------------------------------- /23-AKS-Production-Grade-Cluster-Design-using-az-aks-cli/23-03-k8s-NodeSelectors-Deploy-Apps-Windows-Linux/kube-manifests/03-Windows-DotNet-Apps/01-windows-app-deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: windows-app1-deployment 5 | labels: 6 | app: windows-app1 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: windows-app1 12 | template: 13 | metadata: 14 | name: windows-app1 15 | labels: 16 | app: windows-app1 17 | spec: 18 | # To schedule pods on based on NodeSelectors 19 | nodeSelector: 20 | #"beta.kubernetes.io/os": windows 21 | app: dotnet-apps 22 | containers: 23 | - name: windows-app1 24 | image: mcr.microsoft.com/dotnet/framework/samples:aspnetapp 25 | resources: 26 | limits: 27 | cpu: 1 28 | memory: 800M 29 | requests: 30 | cpu: .1 31 | memory: 300M 32 | ports: 33 | - containerPort: 80 34 | 35 | -------------------------------------------------------------------------------- /23-AKS-Production-Grade-Cluster-Design-using-az-aks-cli/23-03-k8s-NodeSelectors-Deploy-Apps-Windows-Linux/kube-manifests/03-Windows-DotNet-Apps/02-windows-app-loadbalancer-service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: windows-app1-loadbalancer-service 5 | spec: 6 | type: LoadBalancer 7 | selector: 8 | app: windows-app1 9 | ports: 10 | - protocol: TCP 11 | port: 80 -------------------------------------------------------------------------------- /23-AKS-Production-Grade-Cluster-Design-using-az-aks-cli/23-03-k8s-NodeSelectors-Deploy-Apps-Windows-Linux/kube-manifests/04-VirtualNode-Apps/01-NginxVnode-Deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: vnode-app-deployment 5 | labels: 6 | app: vnode-nginx 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: vnode-nginx 12 | template: 13 | metadata: 14 | labels: 15 | app: vnode-nginx 16 | spec: 17 | containers: 18 | - name: vnode-nginx 19 | image: stacksimplify/kubenginx:1.0.0 20 | ports: 21 | - containerPort: 80 22 | # To schedule pods on Azure Virtual Nodes 23 | nodeSelector: 24 | kubernetes.io/role: agent 25 | beta.kubernetes.io/os: linux 26 | type: virtual-kubelet 27 | tolerations: 28 | - key: virtual-kubelet.io/provider 29 | operator: Exists 30 | - key: azure.com/aci 31 | effect: NoSchedule 32 | 33 | -------------------------------------------------------------------------------- /23-AKS-Production-Grade-Cluster-Design-using-az-aks-cli/23-03-k8s-NodeSelectors-Deploy-Apps-Windows-Linux/kube-manifests/04-VirtualNode-Apps/02-NginxVnode-LoadBalancer-Service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: vnode-loadbalancer-service 5 | labels: 6 | app: vnode-nginx 7 | spec: 8 | type: LoadBalancer 9 | selector: 10 | app: vnode-nginx 11 | ports: 12 | - port: 80 13 | targetPort: 80 14 | -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-01-Terraform-Commands-Basics/v1-terraform-azurerm-provider/main.tf: -------------------------------------------------------------------------------- 1 | # Configure Azure Provider 2 | provider "azurerm" { 3 | # Version is optional 4 | # Terraform recommends to pin to a specific version of provider 5 | #version = "=2.35.0" 6 | #version = "~>2.35.0" 7 | #version = "~> 2.37.0" 8 | features {} 9 | } 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-01-Terraform-Commands-Basics/v2-terraform-azurerm-resource-group/main.tf: -------------------------------------------------------------------------------- 1 | # Configure Azure Provider 2 | provider "azurerm" { 3 | # Version is optional 4 | # Terraform recommends to pin to a specific version of provide 5 | #version = "=2.35.0" 6 | #version = "~>2.35.0" 7 | features {} 8 | } 9 | 10 | 11 | # Create a Azure Resource Group 12 | resource "azurerm_resource_group" "aks-rg2" { 13 | name = "aks-rg2-tf" 14 | location = "Central US" 15 | 16 | # Add Tags 17 | # tags = { 18 | # "environment" = "k8sdev" 19 | # "demotag" = "refreshtest" 20 | # } 21 | 22 | } 23 | 24 | -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-02-Terraform-Language-Basics/terraform-manifests-aks/01-main.tf: -------------------------------------------------------------------------------- 1 | # We will define 2 | # 1. Terraform Settings Block 3 | # 1. Required Version Terraform 4 | # 2. Required Terraform Providers 5 | # 3. Terraform Remote State Storage with Azure Storage Account (last step of this section) 6 | # 2. Terraform Provider Block for AzureRM 7 | # 3. Terraform Resource Block: Define a Random Pet Resource 8 | 9 | # 1. Terraform Settings Block 10 | terraform { 11 | # 1. Required Version Terraform 12 | required_version = ">= 0.13" 13 | # 2. Required Terraform Providers 14 | required_providers { 15 | azurerm = { 16 | source = "hashicorp/azurerm" 17 | version = "~> 2.0" 18 | } 19 | azuread = { 20 | source = "hashicorp/azuread" 21 | version = "~> 1.0" 22 | } 23 | random = { 24 | source = "hashicorp/random" 25 | version = "~> 3.0" 26 | } 27 | } 28 | 29 | # Terraform State Storage to Azure Storage Container 30 | backend "azurerm" { 31 | resource_group_name = "terraform-storage-rg" 32 | storage_account_name = "terraformstatexlrwdrzs" 33 | container_name = "tfstatefiles" 34 | key = "terraform.tfstate" 35 | } 36 | } 37 | 38 | 39 | # 2. Terraform Provider Block for AzureRM 40 | provider "azurerm" { 41 | features { 42 | 43 | } 44 | } 45 | 46 | # 3. Terraform Resource Block: Define a Random Pet Resource 47 | resource "random_pet" "aksrandom" { 48 | 49 | } -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-02-Terraform-Language-Basics/terraform-manifests-aks/02-variables.tf: -------------------------------------------------------------------------------- 1 | # https://www.terraform.io/docs/configuration/variables.html 2 | # Input Variables 3 | # Output Values 4 | # Local Values (Optional) 5 | 6 | # Define Input Variables 7 | # 1. Azure Location (CentralUS) 8 | # 2. Azure Resource Group Name 9 | # 3. Azure AKS Environment Name (Dev, QA, Prod) 10 | 11 | # Azure Location 12 | variable "location" { 13 | type = string 14 | description = "Azure Region where all these resources will be provisioned" 15 | default = "Central US" 16 | } 17 | 18 | # Azure Resource Group Name 19 | variable "resource_group_name" { 20 | type = string 21 | description = "This variable defines the Resource Group" 22 | default = "terraform-aks" 23 | } 24 | 25 | # Azure AKS Environment Name 26 | variable "environment" { 27 | type = string 28 | description = "This variable defines the Environment" 29 | default = "dev" 30 | } -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-02-Terraform-Language-Basics/terraform-manifests-aks/03-resource-group.tf: -------------------------------------------------------------------------------- 1 | # Terraform Resource to Create Azure Resource Group with Input Variables defined in variables.tf 2 | 3 | resource "azurerm_resource_group" "aks_rg" { 4 | name = "${var.resource_group_name}-${var.environment}" 5 | location = var.location 6 | 7 | } 8 | 9 | 10 | -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-02-Terraform-Language-Basics/terraform-manifests-aks/08-outputs.tf: -------------------------------------------------------------------------------- 1 | # Create Outputs 2 | # 1. Resource Group Location 3 | # 2. Resource Group Id 4 | # 3. Resource Group Name 5 | 6 | output "location" { 7 | value = azurerm_resource_group.aks_rg.location 8 | } 9 | 10 | output "resource_group_id" { 11 | value = azurerm_resource_group.aks_rg.id 12 | } 13 | 14 | output "resource_group_name" { 15 | value = azurerm_resource_group.aks_rg.name 16 | } -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-03-Create-AKS-Cluster/terraform-manifests-aks/01-main.tf: -------------------------------------------------------------------------------- 1 | # We will define 2 | # 1. Terraform Settings Block 3 | # 1. Required Version Terraform 4 | # 2. Required Terraform Providers 5 | # 3. Terraform Remote State Storage with Azure Storage Account (last step of this section) 6 | # 2. Terraform Provider Block for AzureRM 7 | # 3. Terraform Resource Block: Define a Random Pet Resource 8 | 9 | # 1. Terraform Settings Block 10 | terraform { 11 | # 1. Required Version Terraform 12 | required_version = ">= 0.13" 13 | # 2. Required Terraform Providers 14 | required_providers { 15 | azurerm = { 16 | source = "hashicorp/azurerm" 17 | version = "~> 2.0" 18 | } 19 | azuread = { 20 | source = "hashicorp/azuread" 21 | version = "~> 1.0" 22 | } 23 | random = { 24 | source = "hashicorp/random" 25 | version = "~> 3.0" 26 | } 27 | } 28 | 29 | # Terraform State Storage to Azure Storage Container 30 | backend "azurerm" { 31 | resource_group_name = "terraform-storage-rg" 32 | storage_account_name = "terraformstatexlrwdrzs" 33 | container_name = "tfstatefiles" 34 | key = "dev.terraform.tfstate" 35 | } 36 | } 37 | 38 | 39 | 40 | # 2. Terraform Provider Block for AzureRM 41 | provider "azurerm" { 42 | features { 43 | 44 | } 45 | } 46 | 47 | # 3. Terraform Resource Block: Define a Random Pet Resource 48 | resource "random_pet" "aksrandom" { 49 | 50 | } 51 | 52 | -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-03-Create-AKS-Cluster/terraform-manifests-aks/02-variables.tf: -------------------------------------------------------------------------------- 1 | # Define Input Variables 2 | # 1. Azure Location (CentralUS) 3 | # 2. Azure Resource Group Name 4 | # 3. Azure AKS Environment Name (Dev, QA, Prod) 5 | 6 | # Azure Location 7 | variable "location" { 8 | type = string 9 | description = "Azure Region where all these resources will be provisioned" 10 | default = "Central US" 11 | } 12 | 13 | # Azure Resource Group Name 14 | variable "resource_group_name" { 15 | type = string 16 | description = "This variable defines the Resource Group" 17 | default = "terraform-aks" 18 | } 19 | 20 | # Azure AKS Environment Name 21 | variable "environment" { 22 | type = string 23 | description = "This variable defines the Environment" 24 | default = "dev" 25 | } 26 | 27 | 28 | # AKS Input Variables 29 | 30 | # SSH Public Key for Linux VMs 31 | variable "ssh_public_key" { 32 | default = "~/.ssh/aks-prod-sshkeys-terraform/aksprodsshkey.pub" 33 | description = "This variable defines the SSH Public Key for Linux k8s Worker nodes" 34 | } 35 | 36 | # Windows Admin Username for k8s worker nodes 37 | variable "windows_admin_username" { 38 | type = string 39 | default = "azureuser" 40 | description = "This variable defines the Windows admin username k8s Worker nodes" 41 | } 42 | 43 | # Windows Admin Password for k8s worker nodes 44 | variable "windows_admin_password" { 45 | type = string 46 | default = "P@ssw0rd1234" 47 | description = "This variable defines the Windows admin password k8s Worker nodes" 48 | } 49 | 50 | -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-03-Create-AKS-Cluster/terraform-manifests-aks/03-resource-group.tf: -------------------------------------------------------------------------------- 1 | # Terraform Resource to Create Azure Resource Group with Input Variables defined in variables.tf 2 | resource "azurerm_resource_group" "aks_rg" { 3 | name = "${var.resource_group_name}-${var.environment}" 4 | location = var.location 5 | } 6 | 7 | 8 | -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-03-Create-AKS-Cluster/terraform-manifests-aks/04-aks-versions-datasource.tf: -------------------------------------------------------------------------------- 1 | # Documentation Reference: https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/kubernetes_service_versions 2 | # Datasource to get Latest Azure AKS latest Version 3 | data "azurerm_kubernetes_service_versions" "current" { 4 | location = azurerm_resource_group.aks_rg.location 5 | include_preview = false 6 | } 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-03-Create-AKS-Cluster/terraform-manifests-aks/05-log-analytics-workspace.tf: -------------------------------------------------------------------------------- 1 | # Create Log Analytics Workspace 2 | resource "azurerm_log_analytics_workspace" "insights" { 3 | name = "logs-${random_pet.aksrandom.id}" 4 | location = azurerm_resource_group.aks_rg.location 5 | resource_group_name = azurerm_resource_group.aks_rg.name 6 | retention_in_days = 30 7 | } -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-03-Create-AKS-Cluster/terraform-manifests-aks/06-aks-administrators-azure-ad.tf: -------------------------------------------------------------------------------- 1 | # Create Azure AD Group in Active Directory for AKS Admins 2 | resource "azuread_group" "aks_administrators" { 3 | name = "${azurerm_resource_group.aks_rg.name}-cluster-administrators" 4 | description = "Azure AKS Kubernetes administrators for the ${azurerm_resource_group.aks_rg.name}-cluster." 5 | } 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-03-Create-AKS-Cluster/terraform-manifests-aks/08-outputs.tf: -------------------------------------------------------------------------------- 1 | # Create Outputs 2 | # 1. Resource Group Location 3 | # 2. Resource Group Id 4 | # 3. Resource Group Name 5 | 6 | # Resource Group Outputs 7 | output "location" { 8 | value = azurerm_resource_group.aks_rg.location 9 | } 10 | 11 | output "resource_group_id" { 12 | value = azurerm_resource_group.aks_rg.id 13 | } 14 | 15 | output "resource_group_name" { 16 | value = azurerm_resource_group.aks_rg.name 17 | } 18 | 19 | # Azure AKS Versions Datasource 20 | output "versions" { 21 | value = data.azurerm_kubernetes_service_versions.current.versions 22 | } 23 | 24 | output "latest_version" { 25 | value = data.azurerm_kubernetes_service_versions.current.latest_version 26 | } 27 | 28 | # Azure AD Group Object Id 29 | output "azure_ad_group_id" { 30 | value = azuread_group.aks_administrators.id 31 | } 32 | output "azure_ad_group_objectid" { 33 | value = azuread_group.aks_administrators.object_id 34 | } 35 | 36 | 37 | # Azure AKS Outputs 38 | 39 | output "aks_cluster_id" { 40 | value = azurerm_kubernetes_cluster.aks_cluster.id 41 | } 42 | 43 | output "aks_cluster_name" { 44 | value = azurerm_kubernetes_cluster.aks_cluster.name 45 | } 46 | 47 | output "aks_cluster_kubernetes_version" { 48 | value = azurerm_kubernetes_cluster.aks_cluster.kubernetes_version 49 | } 50 | -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-04-Create-AKS-NodePools-using-Terraform/kube-manifests/01-Webserver-Apps/01-NginxApp1-Deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: app1-nginx-deployment 5 | labels: 6 | app: app1-nginx 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: app1-nginx 12 | template: 13 | metadata: 14 | labels: 15 | app: app1-nginx 16 | spec: 17 | containers: 18 | - name: app1-nginx 19 | image: stacksimplify/kube-nginxapp1:1.0.0 20 | ports: 21 | - containerPort: 80 22 | # To schedule pods on based on NodeSelectors 23 | nodeSelector: 24 | app: system-apps 25 | 26 | 27 | -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-04-Create-AKS-NodePools-using-Terraform/kube-manifests/01-Webserver-Apps/02-NginxApp1-LoadBalancer-Service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: app1-nginx-clusterip-service 5 | labels: 6 | app: app1-nginx 7 | spec: 8 | type: LoadBalancer 9 | selector: 10 | app: app1-nginx 11 | ports: 12 | - port: 80 13 | targetPort: 80 14 | -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-04-Create-AKS-NodePools-using-Terraform/kube-manifests/02-Java-Apps/01-persistent-volume-claim.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: azure-managed-disk-pvc 5 | spec: 6 | accessModes: 7 | - ReadWriteOnce 8 | storageClassName: managed-premium-retain-sc 9 | resources: 10 | requests: 11 | storage: 5Gi -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-04-Create-AKS-NodePools-using-Terraform/kube-manifests/02-Java-Apps/02-UserManagement-ConfigMap.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: usermanagement-dbcreation-script 5 | data: 6 | mysql_usermgmt.sql: |- 7 | DROP DATABASE IF EXISTS webappdb; 8 | CREATE DATABASE webappdb; -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-04-Create-AKS-NodePools-using-Terraform/kube-manifests/02-Java-Apps/03-mysql-deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: mysql 5 | spec: 6 | replicas: 1 7 | selector: 8 | matchLabels: 9 | app: mysql 10 | strategy: 11 | type: Recreate 12 | template: 13 | metadata: 14 | labels: 15 | app: mysql 16 | spec: 17 | containers: 18 | - name: mysql 19 | image: mysql:5.6 20 | env: 21 | - name: MYSQL_ROOT_PASSWORD 22 | value: dbpassword11 23 | ports: 24 | - containerPort: 3306 25 | name: mysql 26 | volumeMounts: 27 | - name: mysql-persistent-storage 28 | mountPath: /var/lib/mysql 29 | - name: usermanagement-dbcreation-script 30 | mountPath: /docker-entrypoint-initdb.d #https://hub.docker.com/_/mysql Refer Initializing a fresh instance 31 | volumes: 32 | - name: mysql-persistent-storage 33 | persistentVolumeClaim: 34 | claimName: azure-managed-disk-pvc 35 | - name: usermanagement-dbcreation-script 36 | configMap: 37 | name: usermanagement-dbcreation-script 38 | # To schedule pods on based on NodeSelectors 39 | nodeSelector: 40 | app: java-apps -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-04-Create-AKS-NodePools-using-Terraform/kube-manifests/02-Java-Apps/04-mysql-clusterip-service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: mysql 5 | spec: 6 | selector: 7 | app: mysql 8 | ports: 9 | - port: 3306 10 | clusterIP: None # This means we are going to use Pod IP -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-04-Create-AKS-NodePools-using-Terraform/kube-manifests/02-Java-Apps/06-UserMgmtWebApp-Deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: usermgmt-webapp 5 | labels: 6 | app: usermgmt-webapp 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: usermgmt-webapp 12 | template: 13 | metadata: 14 | labels: 15 | app: usermgmt-webapp 16 | spec: 17 | initContainers: 18 | - name: init-db 19 | image: busybox:1.31 20 | command: ['sh', '-c', 'echo -e "Checking for the availability of MySQL Server deployment"; while ! nc -z mysql 3306; do sleep 1; printf "-"; done; echo -e " >> MySQL DB Server has started";'] 21 | containers: 22 | - name: usermgmt-webapp 23 | image: stacksimplify/kube-usermgmt-webapp:1.0.0-MySQLDB 24 | imagePullPolicy: Always 25 | ports: 26 | - containerPort: 8080 27 | env: 28 | - name: DB_HOSTNAME 29 | value: "mysql" 30 | - name: DB_PORT 31 | value: "3306" 32 | - name: DB_NAME 33 | value: "webappdb" 34 | - name: DB_USERNAME 35 | value: "root" 36 | - name: DB_PASSWORD 37 | value: "dbpassword11" 38 | # To schedule pods on based on NodeSelectors 39 | nodeSelector: 40 | app: java-apps 41 | 42 | -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-04-Create-AKS-NodePools-using-Terraform/kube-manifests/02-Java-Apps/07-UserMgmtWebApp-Service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: usermgmt-webapp-service 5 | labels: 6 | app: usermgmt-webapp 7 | spec: 8 | type: LoadBalancer 9 | selector: 10 | app: usermgmt-webapp 11 | ports: 12 | - port: 80 13 | targetPort: 8080 -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-04-Create-AKS-NodePools-using-Terraform/kube-manifests/03-Windows-DotNet-Apps/01-windows-app-deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: windows-app1-deployment 5 | labels: 6 | app: windows-app1 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: windows-app1 12 | template: 13 | metadata: 14 | name: windows-app1 15 | labels: 16 | app: windows-app1 17 | spec: 18 | # To schedule pods on based on NodeSelectors 19 | nodeSelector: 20 | #"beta.kubernetes.io/os": windows 21 | app: dotnet-apps 22 | containers: 23 | - name: windows-app1 24 | image: mcr.microsoft.com/dotnet/framework/samples:aspnetapp 25 | resources: 26 | limits: 27 | cpu: 1 28 | memory: 800M 29 | requests: 30 | cpu: .1 31 | memory: 300M 32 | ports: 33 | - containerPort: 80 34 | 35 | -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-04-Create-AKS-NodePools-using-Terraform/kube-manifests/03-Windows-DotNet-Apps/02-windows-app-loadbalancer-service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: windows-app1-loadbalancer-service 5 | spec: 6 | type: LoadBalancer 7 | selector: 8 | app: windows-app1 9 | ports: 10 | - protocol: TCP 11 | port: 80 -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-04-Create-AKS-NodePools-using-Terraform/terraform-manifests-aks/01-main.tf: -------------------------------------------------------------------------------- 1 | # We will define 2 | # 1. Terraform Settings Block 3 | # 1. Required Version Terraform 4 | # 2. Required Terraform Providers 5 | # 3. Terraform Remote State Storage with Azure Storage Account (last step of this section) 6 | # 2. Terraform Provider Block for AzureRM 7 | # 3. Terraform Resource Block: Define a Random Pet Resource 8 | 9 | # 1. Terraform Settings Block 10 | terraform { 11 | # 1. Required Version Terraform 12 | required_version = ">= 0.13" 13 | # 2. Required Terraform Providers 14 | required_providers { 15 | azurerm = { 16 | source = "hashicorp/azurerm" 17 | version = "~> 2.0" 18 | } 19 | azuread = { 20 | source = "hashicorp/azuread" 21 | version = "~> 1.0" 22 | } 23 | random = { 24 | source = "hashicorp/random" 25 | version = "~> 3.0" 26 | } 27 | } 28 | 29 | # Terraform State Storage to Azure Storage Container 30 | backend "azurerm" { 31 | resource_group_name = "terraform-storage-rg" 32 | storage_account_name = "terraformstatexlrwdrzs" 33 | container_name = "tfstatefiles" 34 | key = "dev.terraform.tfstate" 35 | } 36 | } 37 | 38 | 39 | 40 | # 2. Terraform Provider Block for AzureRM 41 | provider "azurerm" { 42 | features { 43 | 44 | } 45 | } 46 | 47 | # 3. Terraform Resource Block: Define a Random Pet Resource 48 | resource "random_pet" "aksrandom" { 49 | 50 | } 51 | 52 | -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-04-Create-AKS-NodePools-using-Terraform/terraform-manifests-aks/02-variables.tf: -------------------------------------------------------------------------------- 1 | # Define Input Variables 2 | # 1. Azure Location (CentralUS) 3 | # 2. Azure Resource Group Name 4 | # 3. Azure AKS Environment Name (Dev, QA, Prod) 5 | 6 | # Azure Location 7 | variable "location" { 8 | type = string 9 | description = "Azure Region where all these resources will be provisioned" 10 | default = "Central US" 11 | } 12 | 13 | # Azure Resource Group Name 14 | variable "resource_group_name" { 15 | type = string 16 | description = "This variable defines the Resource Group" 17 | default = "terraform-aks" 18 | } 19 | 20 | # Azure AKS Environment Name 21 | variable "environment" { 22 | type = string 23 | description = "This variable defines the Environment" 24 | default = "dev" 25 | } 26 | 27 | 28 | # AKS Input Variables 29 | 30 | # SSH Public Key for Linux VMs 31 | variable "ssh_public_key" { 32 | default = "~/.ssh/aks-prod-sshkeys-terraform/aksprodsshkey.pub" 33 | description = "This variable defines the SSH Public Key for Linux k8s Worker nodes" 34 | } 35 | 36 | # Windows Admin Username for k8s worker nodes 37 | variable "windows_admin_username" { 38 | type = string 39 | default = "azureuser" 40 | description = "This variable defines the Windows admin username k8s Worker nodes" 41 | } 42 | 43 | # Windows Admin Password for k8s worker nodes 44 | variable "windows_admin_password" { 45 | type = string 46 | default = "P@ssw0rd1234" 47 | description = "This variable defines the Windows admin password k8s Worker nodes" 48 | } 49 | 50 | -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-04-Create-AKS-NodePools-using-Terraform/terraform-manifests-aks/03-resource-group.tf: -------------------------------------------------------------------------------- 1 | # Terraform Resource to Create Azure Resource Group with Input Variables defined in variables.tf 2 | resource "azurerm_resource_group" "aks_rg" { 3 | name = "${var.resource_group_name}-${var.environment}" 4 | location = var.location 5 | } 6 | 7 | 8 | -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-04-Create-AKS-NodePools-using-Terraform/terraform-manifests-aks/04-aks-versions-datasource.tf: -------------------------------------------------------------------------------- 1 | # Documentation Reference: https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/kubernetes_service_versions 2 | # Datasource to get Latest Azure AKS latest Version 3 | data "azurerm_kubernetes_service_versions" "current" { 4 | location = azurerm_resource_group.aks_rg.location 5 | include_preview = false 6 | } 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-04-Create-AKS-NodePools-using-Terraform/terraform-manifests-aks/05-log-analytics-workspace.tf: -------------------------------------------------------------------------------- 1 | # Create Log Analytics Workspace 2 | resource "azurerm_log_analytics_workspace" "insights" { 3 | name = "logs-${random_pet.aksrandom.id}" 4 | location = azurerm_resource_group.aks_rg.location 5 | resource_group_name = azurerm_resource_group.aks_rg.name 6 | retention_in_days = 30 7 | } -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-04-Create-AKS-NodePools-using-Terraform/terraform-manifests-aks/06-aks-administrators-azure-ad.tf: -------------------------------------------------------------------------------- 1 | # Create Azure AD Group in Active Directory for AKS Admins 2 | resource "azuread_group" "aks_administrators" { 3 | name = "${azurerm_resource_group.aks_rg.name}-cluster-administrators" 4 | description = "Azure AKS Kubernetes administrators for the ${azurerm_resource_group.aks_rg.name}-cluster." 5 | } 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-04-Create-AKS-NodePools-using-Terraform/terraform-manifests-aks/08-outputs.tf: -------------------------------------------------------------------------------- 1 | # Create Outputs 2 | # 1. Resource Group Location 3 | # 2. Resource Group Id 4 | # 3. Resource Group Name 5 | 6 | # Resource Group Outputs 7 | output "location" { 8 | value = azurerm_resource_group.aks_rg.location 9 | } 10 | 11 | output "resource_group_id" { 12 | value = azurerm_resource_group.aks_rg.id 13 | } 14 | 15 | output "resource_group_name" { 16 | value = azurerm_resource_group.aks_rg.name 17 | } 18 | 19 | # Azure AKS Versions Datasource 20 | output "versions" { 21 | value = data.azurerm_kubernetes_service_versions.current.versions 22 | } 23 | 24 | output "latest_version" { 25 | value = data.azurerm_kubernetes_service_versions.current.latest_version 26 | } 27 | 28 | # Azure AD Group Object Id 29 | output "azure_ad_group_id" { 30 | value = azuread_group.aks_administrators.id 31 | } 32 | output "azure_ad_group_objectid" { 33 | value = azuread_group.aks_administrators.object_id 34 | } 35 | 36 | 37 | # Azure AKS Outputs 38 | 39 | output "aks_cluster_id" { 40 | value = azurerm_kubernetes_cluster.aks_cluster.id 41 | } 42 | 43 | output "aks_cluster_name" { 44 | value = azurerm_kubernetes_cluster.aks_cluster.name 45 | } 46 | 47 | output "aks_cluster_kubernetes_version" { 48 | value = azurerm_kubernetes_cluster.aks_cluster.kubernetes_version 49 | } 50 | -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-04-Create-AKS-NodePools-using-Terraform/terraform-manifests-aks/09-aks-cluster-linux-user-nodepools.tf: -------------------------------------------------------------------------------- 1 | # Create Linux Azure AKS Node Pool 2 | resource "azurerm_kubernetes_cluster_node_pool" "linux101" { 3 | availability_zones = [1, 2, 3] 4 | enable_auto_scaling = true 5 | kubernetes_cluster_id = azurerm_kubernetes_cluster.aks_cluster.id 6 | max_count = 3 7 | min_count = 1 8 | mode = "User" 9 | name = "linux101" 10 | orchestrator_version = data.azurerm_kubernetes_service_versions.current.latest_version 11 | os_disk_size_gb = 30 12 | os_type = "Linux" # Default is Linux, we can change to Windows 13 | vm_size = "Standard_DS2_v2" 14 | priority = "Regular" # Default is Regular, we can change to Spot with additional settings like eviction_policy, spot_max_price, node_labels and node_taints 15 | node_labels = { 16 | "nodepool-type" = "user" 17 | "environment" = var.environment 18 | "nodepoolos" = "linux" 19 | "app" = "java-apps" 20 | } 21 | tags = { 22 | "nodepool-type" = "user" 23 | "environment" = var.environment 24 | "nodepoolos" = "linux" 25 | "app" = "java-apps" 26 | } 27 | } -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-04-Create-AKS-NodePools-using-Terraform/terraform-manifests-aks/10-aks-cluster-windows-user-nodepools.tf: -------------------------------------------------------------------------------- 1 | # Create Windows Azure AKS Node Pool 2 | resource "azurerm_kubernetes_cluster_node_pool" "win101" { 3 | availability_zones = [1, 2, 3] 4 | enable_auto_scaling = true 5 | kubernetes_cluster_id = azurerm_kubernetes_cluster.aks_cluster.id 6 | max_count = 3 7 | min_count = 1 8 | mode = "User" 9 | name = "win101" 10 | orchestrator_version = data.azurerm_kubernetes_service_versions.current.latest_version 11 | os_disk_size_gb = 30 12 | os_type = "Windows" # Default is Linux, we can change to Windows 13 | vm_size = "Standard_DS2_v2" 14 | priority = "Regular" # Default is Regular, we can change to Spot with additional settings like eviction_policy, spot_max_price, node_labels and node_taints 15 | node_labels = { 16 | "nodepool-type" = "user" 17 | "environment" = var.environment 18 | "nodepoolos" = "windows" 19 | "app" = "dotnet-apps" 20 | } 21 | tags = { 22 | "nodepool-type" = "user" 23 | "environment" = var.environment 24 | "nodepoolos" = "windows" 25 | "app" = "dotnet-apps" 26 | } 27 | } -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-05-Create-AKS-Cluster-Custom-VNET/kube-manifests/01-Webserver-Apps/01-NginxApp1-Deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: app1-nginx-deployment 5 | labels: 6 | app: app1-nginx 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: app1-nginx 12 | template: 13 | metadata: 14 | labels: 15 | app: app1-nginx 16 | spec: 17 | containers: 18 | - name: app1-nginx 19 | image: stacksimplify/kube-nginxapp1:1.0.0 20 | ports: 21 | - containerPort: 80 22 | # To schedule pods on based on NodeSelectors 23 | nodeSelector: 24 | app: system-apps 25 | 26 | 27 | -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-05-Create-AKS-Cluster-Custom-VNET/kube-manifests/01-Webserver-Apps/02-NginxApp1-LoadBalancer-Service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: app1-nginx-clusterip-service 5 | labels: 6 | app: app1-nginx 7 | spec: 8 | type: LoadBalancer 9 | selector: 10 | app: app1-nginx 11 | ports: 12 | - port: 80 13 | targetPort: 80 14 | -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-05-Create-AKS-Cluster-Custom-VNET/kube-manifests/02-Java-Apps/01-persistent-volume-claim.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: azure-managed-disk-pvc 5 | spec: 6 | accessModes: 7 | - ReadWriteOnce 8 | storageClassName: managed-premium-retain-sc 9 | resources: 10 | requests: 11 | storage: 5Gi -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-05-Create-AKS-Cluster-Custom-VNET/kube-manifests/02-Java-Apps/02-UserManagement-ConfigMap.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: usermanagement-dbcreation-script 5 | data: 6 | mysql_usermgmt.sql: |- 7 | DROP DATABASE IF EXISTS webappdb; 8 | CREATE DATABASE webappdb; -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-05-Create-AKS-Cluster-Custom-VNET/kube-manifests/02-Java-Apps/03-mysql-deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: mysql 5 | spec: 6 | replicas: 1 7 | selector: 8 | matchLabels: 9 | app: mysql 10 | strategy: 11 | type: Recreate 12 | template: 13 | metadata: 14 | labels: 15 | app: mysql 16 | spec: 17 | containers: 18 | - name: mysql 19 | image: mysql:5.6 20 | env: 21 | - name: MYSQL_ROOT_PASSWORD 22 | value: dbpassword11 23 | ports: 24 | - containerPort: 3306 25 | name: mysql 26 | volumeMounts: 27 | - name: mysql-persistent-storage 28 | mountPath: /var/lib/mysql 29 | - name: usermanagement-dbcreation-script 30 | mountPath: /docker-entrypoint-initdb.d #https://hub.docker.com/_/mysql Refer Initializing a fresh instance 31 | volumes: 32 | - name: mysql-persistent-storage 33 | persistentVolumeClaim: 34 | claimName: azure-managed-disk-pvc 35 | - name: usermanagement-dbcreation-script 36 | configMap: 37 | name: usermanagement-dbcreation-script 38 | # To schedule pods on based on NodeSelectors 39 | nodeSelector: 40 | app: java-apps -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-05-Create-AKS-Cluster-Custom-VNET/kube-manifests/02-Java-Apps/04-mysql-clusterip-service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: mysql 5 | spec: 6 | selector: 7 | app: mysql 8 | ports: 9 | - port: 3306 10 | clusterIP: None # This means we are going to use Pod IP -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-05-Create-AKS-Cluster-Custom-VNET/kube-manifests/02-Java-Apps/06-UserMgmtWebApp-Deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: usermgmt-webapp 5 | labels: 6 | app: usermgmt-webapp 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: usermgmt-webapp 12 | template: 13 | metadata: 14 | labels: 15 | app: usermgmt-webapp 16 | spec: 17 | initContainers: 18 | - name: init-db 19 | image: busybox:1.31 20 | command: ['sh', '-c', 'echo -e "Checking for the availability of MySQL Server deployment"; while ! nc -z mysql 3306; do sleep 1; printf "-"; done; echo -e " >> MySQL DB Server has started";'] 21 | containers: 22 | - name: usermgmt-webapp 23 | image: stacksimplify/kube-usermgmt-webapp:1.0.0-MySQLDB 24 | imagePullPolicy: Always 25 | ports: 26 | - containerPort: 8080 27 | env: 28 | - name: DB_HOSTNAME 29 | value: "mysql" 30 | - name: DB_PORT 31 | value: "3306" 32 | - name: DB_NAME 33 | value: "webappdb" 34 | - name: DB_USERNAME 35 | value: "root" 36 | - name: DB_PASSWORD 37 | value: "dbpassword11" 38 | # To schedule pods on based on NodeSelectors 39 | nodeSelector: 40 | app: java-apps 41 | 42 | -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-05-Create-AKS-Cluster-Custom-VNET/kube-manifests/02-Java-Apps/07-UserMgmtWebApp-Service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: usermgmt-webapp-service 5 | labels: 6 | app: usermgmt-webapp 7 | spec: 8 | type: LoadBalancer 9 | selector: 10 | app: usermgmt-webapp 11 | ports: 12 | - port: 80 13 | targetPort: 8080 -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-05-Create-AKS-Cluster-Custom-VNET/kube-manifests/03-Windows-DotNet-Apps/01-windows-app-deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: windows-app1-deployment 5 | labels: 6 | app: windows-app1 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: windows-app1 12 | template: 13 | metadata: 14 | name: windows-app1 15 | labels: 16 | app: windows-app1 17 | spec: 18 | # To schedule pods on based on NodeSelectors 19 | nodeSelector: 20 | #"beta.kubernetes.io/os": windows 21 | app: dotnet-apps 22 | containers: 23 | - name: windows-app1 24 | image: mcr.microsoft.com/dotnet/framework/samples:aspnetapp 25 | resources: 26 | limits: 27 | cpu: 1 28 | memory: 800M 29 | requests: 30 | cpu: .1 31 | memory: 300M 32 | ports: 33 | - containerPort: 80 34 | 35 | -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-05-Create-AKS-Cluster-Custom-VNET/kube-manifests/03-Windows-DotNet-Apps/02-windows-app-loadbalancer-service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: windows-app1-loadbalancer-service 5 | spec: 6 | type: LoadBalancer 7 | selector: 8 | app: windows-app1 9 | ports: 10 | - protocol: TCP 11 | port: 80 -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-05-Create-AKS-Cluster-Custom-VNET/terraform-manifests-aks-custom-vnet/01-main.tf: -------------------------------------------------------------------------------- 1 | # We will define 2 | # 1. Terraform Settings Block 3 | # 1. Required Version Terraform 4 | # 2. Required Terraform Providers 5 | # 3. Terraform Remote State Storage with Azure Storage Account (last step of this section) 6 | # 2. Terraform Provider Block for AzureRM 7 | # 3. Terraform Resource Block: Define a Random Pet Resource 8 | 9 | # 1. Terraform Settings Block 10 | terraform { 11 | # 1. Required Version Terraform 12 | required_version = ">= 0.13" 13 | # 2. Required Terraform Providers 14 | required_providers { 15 | azurerm = { 16 | source = "hashicorp/azurerm" 17 | version = "~> 2.0" 18 | } 19 | azuread = { 20 | source = "hashicorp/azuread" 21 | version = "~> 1.0" 22 | } 23 | random = { 24 | source = "hashicorp/random" 25 | version = "~> 3.0" 26 | } 27 | } 28 | 29 | # Terraform State Storage to Azure Storage Container 30 | backend "azurerm" { 31 | resource_group_name = "terraform-storage-rg" 32 | storage_account_name = "terraformstatexlrwdrzs" 33 | container_name = "tfstatefiles" 34 | key = "terraform-custom-vnet.tfstate" 35 | } 36 | } 37 | 38 | 39 | 40 | # 2. Terraform Provider Block for AzureRM 41 | provider "azurerm" { 42 | features { 43 | 44 | } 45 | } 46 | 47 | # 3. Terraform Resource Block: Define a Random Pet Resource 48 | resource "random_pet" "aksrandom" { 49 | 50 | } 51 | 52 | -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-05-Create-AKS-Cluster-Custom-VNET/terraform-manifests-aks-custom-vnet/02-variables.tf: -------------------------------------------------------------------------------- 1 | # Define Input Variables 2 | # 1. Azure Location (CentralUS) 3 | # 2. Azure Resource Group Name 4 | # 3. Azure AKS Environment Name (Dev, QA, Prod) 5 | 6 | # Azure Location 7 | variable "location" { 8 | type = string 9 | description = "Azure Region where all these resources will be provisioned" 10 | default = "Central US" 11 | } 12 | 13 | # Azure Resource Group Name 14 | variable "resource_group_name" { 15 | type = string 16 | description = "This variable defines the Resource Group" 17 | default = "terraform-aks" 18 | } 19 | 20 | # Azure AKS Environment Name 21 | variable "environment" { 22 | type = string 23 | description = "This variable defines the Environment" 24 | default = "dev2" 25 | } 26 | 27 | 28 | # AKS Input Variables 29 | 30 | # SSH Public Key for Linux VMs 31 | variable "ssh_public_key" { 32 | default = "~/.ssh/aks-prod-sshkeys-terraform/aksprodsshkey.pub" 33 | description = "This variable defines the SSH Public Key for Linux k8s Worker nodes" 34 | } 35 | 36 | # Windows Admin Username for k8s worker nodes 37 | variable "windows_admin_username" { 38 | type = string 39 | default = "azureuser" 40 | description = "This variable defines the Windows admin username k8s Worker nodes" 41 | } 42 | 43 | # Windows Admin Password for k8s worker nodes 44 | variable "windows_admin_password" { 45 | type = string 46 | default = "P@ssw0rd1234" 47 | description = "This variable defines the Windows admin password k8s Worker nodes" 48 | } 49 | 50 | -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-05-Create-AKS-Cluster-Custom-VNET/terraform-manifests-aks-custom-vnet/03-resource-group.tf: -------------------------------------------------------------------------------- 1 | # Terraform Resource to Create Azure Resource Group with Input Variables defined in variables.tf 2 | resource "azurerm_resource_group" "aks_rg" { 3 | name = "${var.resource_group_name}-${var.environment}" 4 | location = var.location 5 | } 6 | 7 | 8 | -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-05-Create-AKS-Cluster-Custom-VNET/terraform-manifests-aks-custom-vnet/04-aks-versions-datasource.tf: -------------------------------------------------------------------------------- 1 | # Documentation Reference: https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/kubernetes_service_versions 2 | # Datasource to get Latest Azure AKS latest Version 3 | data "azurerm_kubernetes_service_versions" "current" { 4 | location = azurerm_resource_group.aks_rg.location 5 | include_preview = false 6 | } 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-05-Create-AKS-Cluster-Custom-VNET/terraform-manifests-aks-custom-vnet/05-log-analytics-workspace.tf: -------------------------------------------------------------------------------- 1 | # Create Log Analytics Workspace 2 | resource "azurerm_log_analytics_workspace" "insights" { 3 | name = "logs-${random_pet.aksrandom.id}" 4 | location = azurerm_resource_group.aks_rg.location 5 | resource_group_name = azurerm_resource_group.aks_rg.name 6 | retention_in_days = 30 7 | } -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-05-Create-AKS-Cluster-Custom-VNET/terraform-manifests-aks-custom-vnet/06-aks-administrators-azure-ad.tf: -------------------------------------------------------------------------------- 1 | # Create Azure AD Group in Active Directory for AKS Admins 2 | resource "azuread_group" "aks_administrators" { 3 | name = "${azurerm_resource_group.aks_rg.name}-cluster-administrators" 4 | description = "Azure AKS Kubernetes administrators for the ${azurerm_resource_group.aks_rg.name}-cluster." 5 | } 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-05-Create-AKS-Cluster-Custom-VNET/terraform-manifests-aks-custom-vnet/08-outputs.tf: -------------------------------------------------------------------------------- 1 | # Create Outputs 2 | # 1. Resource Group Location 3 | # 2. Resource Group Id 4 | # 3. Resource Group Name 5 | 6 | # Resource Group Outputs 7 | output "location" { 8 | value = azurerm_resource_group.aks_rg.location 9 | } 10 | 11 | output "resource_group_id" { 12 | value = azurerm_resource_group.aks_rg.id 13 | } 14 | 15 | output "resource_group_name" { 16 | value = azurerm_resource_group.aks_rg.name 17 | } 18 | 19 | # Azure AKS Versions Datasource 20 | output "versions" { 21 | value = data.azurerm_kubernetes_service_versions.current.versions 22 | } 23 | 24 | output "latest_version" { 25 | value = data.azurerm_kubernetes_service_versions.current.latest_version 26 | } 27 | 28 | # Azure AD Group Object Id 29 | output "azure_ad_group_id" { 30 | value = azuread_group.aks_administrators.id 31 | } 32 | output "azure_ad_group_objectid" { 33 | value = azuread_group.aks_administrators.object_id 34 | } 35 | 36 | 37 | # Azure AKS Outputs 38 | 39 | output "aks_cluster_id" { 40 | value = azurerm_kubernetes_cluster.aks_cluster.id 41 | } 42 | 43 | output "aks_cluster_name" { 44 | value = azurerm_kubernetes_cluster.aks_cluster.name 45 | } 46 | 47 | output "aks_cluster_kubernetes_version" { 48 | value = azurerm_kubernetes_cluster.aks_cluster.kubernetes_version 49 | } 50 | -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-05-Create-AKS-Cluster-Custom-VNET/terraform-manifests-aks-custom-vnet/09-aks-cluster-linux-user-nodepools.tf: -------------------------------------------------------------------------------- 1 | # Create Linux Azure AKS Node Pool 2 | resource "azurerm_kubernetes_cluster_node_pool" "linux101" { 3 | availability_zones = [1, 2, 3] 4 | enable_auto_scaling = true 5 | kubernetes_cluster_id = azurerm_kubernetes_cluster.aks_cluster.id 6 | max_count = 3 7 | min_count = 1 8 | mode = "User" 9 | name = "linux101" 10 | orchestrator_version = data.azurerm_kubernetes_service_versions.current.latest_version 11 | os_disk_size_gb = 30 12 | os_type = "Linux" # Default is Linux, we can change to Windows 13 | vm_size = "Standard_DS2_v2" 14 | priority = "Regular" # Default is Regular, we can change to Spot with additional settings like eviction_policy, spot_max_price, node_labels and node_taints 15 | vnet_subnet_id = azurerm_subnet.aks-default.id 16 | node_labels = { 17 | "nodepool-type" = "user" 18 | "environment" = var.environment 19 | "nodepoolos" = "linux" 20 | "app" = "java-apps" 21 | } 22 | tags = { 23 | "nodepool-type" = "user" 24 | "environment" = var.environment 25 | "nodepoolos" = "linux" 26 | "app" = "java-apps" 27 | } 28 | } -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-05-Create-AKS-Cluster-Custom-VNET/terraform-manifests-aks-custom-vnet/10-aks-cluster-windows-user-nodepools.tf: -------------------------------------------------------------------------------- 1 | # Create Windows Azure AKS Node Pool 2 | resource "azurerm_kubernetes_cluster_node_pool" "win101" { 3 | availability_zones = [1, 2, 3] 4 | enable_auto_scaling = true 5 | kubernetes_cluster_id = azurerm_kubernetes_cluster.aks_cluster.id 6 | max_count = 3 7 | min_count = 1 8 | mode = "User" 9 | name = "win101" 10 | orchestrator_version = data.azurerm_kubernetes_service_versions.current.latest_version 11 | os_disk_size_gb = 30 12 | os_type = "Windows" # Default is Linux, we can change to Windows 13 | vm_size = "Standard_DS2_v2" 14 | priority = "Regular" # Default is Regular, we can change to Spot with additional settings like eviction_policy, spot_max_price, node_labels and node_taints 15 | vnet_subnet_id = azurerm_subnet.aks-default.id 16 | node_labels = { 17 | "nodepool-type" = "user" 18 | "environment" = var.environment 19 | "nodepoolos" = "windows" 20 | "app" = "dotnet-apps" 21 | } 22 | tags = { 23 | "nodepool-type" = "user" 24 | "environment" = var.environment 25 | "nodepoolos" = "windows" 26 | "app" = "dotnet-apps" 27 | } 28 | } -------------------------------------------------------------------------------- /24-Azure-AKS-Terraform/24-05-Create-AKS-Cluster-Custom-VNET/terraform-manifests-aks-custom-vnet/11-virtual-network.tf: -------------------------------------------------------------------------------- 1 | # Create Virtual Network 2 | resource "azurerm_virtual_network" "aksvnet" { 3 | name = "aks-network" 4 | location = azurerm_resource_group.aks_rg.location 5 | resource_group_name = azurerm_resource_group.aks_rg.name 6 | address_space = ["10.0.0.0/8"] 7 | } 8 | 9 | # Create a Subnet for AKS 10 | resource "azurerm_subnet" "aks-default" { 11 | name = "aks-default-subnet" 12 | virtual_network_name = azurerm_virtual_network.aksvnet.name 13 | resource_group_name = azurerm_resource_group.aks_rg.name 14 | address_prefixes = ["10.240.0.0/16"] 15 | } 16 | 17 | -------------------------------------------------------------------------------- /25-Azure-DevOps-Terraform-Azure-AKS/Git-Repo-Files/README.md: -------------------------------------------------------------------------------- 1 | # Provision Azure AKS Cluster using Terraform and Azure DevOps 2 | 3 | ## For Step by Step Instructions 4 | - [Step by Step Instructions](https://github.com/stacksimplify/azure-aks-kubernetes-masterclass/tree/master/25-Azure-DevOps-Terraform-Azure-AKS) -------------------------------------------------------------------------------- /25-Azure-DevOps-Terraform-Azure-AKS/Git-Repo-Files/kube-manifests/01-Webserver-Apps/01-NginxApp1-Deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: app1-nginx-deployment 5 | labels: 6 | app: app1-nginx 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: app1-nginx 12 | template: 13 | metadata: 14 | labels: 15 | app: app1-nginx 16 | spec: 17 | containers: 18 | - name: app1-nginx 19 | image: stacksimplify/kube-nginxapp1:1.0.0 20 | ports: 21 | - containerPort: 80 22 | # To schedule pods on based on NodeSelectors 23 | nodeSelector: 24 | app: system-apps 25 | 26 | 27 | -------------------------------------------------------------------------------- /25-Azure-DevOps-Terraform-Azure-AKS/Git-Repo-Files/kube-manifests/01-Webserver-Apps/02-NginxApp1-LoadBalancer-Service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: app1-nginx-clusterip-service 5 | labels: 6 | app: app1-nginx 7 | spec: 8 | type: LoadBalancer 9 | selector: 10 | app: app1-nginx 11 | ports: 12 | - port: 80 13 | targetPort: 80 14 | -------------------------------------------------------------------------------- /25-Azure-DevOps-Terraform-Azure-AKS/Git-Repo-Files/kube-manifests/02-Java-Apps/01-persistent-volume-claim.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: azure-managed-disk-pvc 5 | spec: 6 | accessModes: 7 | - ReadWriteOnce 8 | storageClassName: managed-premium-retain-sc 9 | resources: 10 | requests: 11 | storage: 5Gi -------------------------------------------------------------------------------- /25-Azure-DevOps-Terraform-Azure-AKS/Git-Repo-Files/kube-manifests/02-Java-Apps/02-UserManagement-ConfigMap.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: usermanagement-dbcreation-script 5 | data: 6 | mysql_usermgmt.sql: |- 7 | DROP DATABASE IF EXISTS webappdb; 8 | CREATE DATABASE webappdb; -------------------------------------------------------------------------------- /25-Azure-DevOps-Terraform-Azure-AKS/Git-Repo-Files/kube-manifests/02-Java-Apps/03-mysql-deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: mysql 5 | spec: 6 | replicas: 1 7 | selector: 8 | matchLabels: 9 | app: mysql 10 | strategy: 11 | type: Recreate 12 | template: 13 | metadata: 14 | labels: 15 | app: mysql 16 | spec: 17 | containers: 18 | - name: mysql 19 | image: mysql:5.6 20 | env: 21 | - name: MYSQL_ROOT_PASSWORD 22 | value: dbpassword11 23 | ports: 24 | - containerPort: 3306 25 | name: mysql 26 | volumeMounts: 27 | - name: mysql-persistent-storage 28 | mountPath: /var/lib/mysql 29 | - name: usermanagement-dbcreation-script 30 | mountPath: /docker-entrypoint-initdb.d #https://hub.docker.com/_/mysql Refer Initializing a fresh instance 31 | volumes: 32 | - name: mysql-persistent-storage 33 | persistentVolumeClaim: 34 | claimName: azure-managed-disk-pvc 35 | - name: usermanagement-dbcreation-script 36 | configMap: 37 | name: usermanagement-dbcreation-script 38 | # To schedule pods on based on NodeSelectors 39 | nodeSelector: 40 | app: java-apps -------------------------------------------------------------------------------- /25-Azure-DevOps-Terraform-Azure-AKS/Git-Repo-Files/kube-manifests/02-Java-Apps/04-mysql-clusterip-service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: mysql 5 | spec: 6 | selector: 7 | app: mysql 8 | ports: 9 | - port: 3306 10 | clusterIP: None # This means we are going to use Pod IP -------------------------------------------------------------------------------- /25-Azure-DevOps-Terraform-Azure-AKS/Git-Repo-Files/kube-manifests/02-Java-Apps/06-UserMgmtWebApp-Deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: usermgmt-webapp 5 | labels: 6 | app: usermgmt-webapp 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: usermgmt-webapp 12 | template: 13 | metadata: 14 | labels: 15 | app: usermgmt-webapp 16 | spec: 17 | initContainers: 18 | - name: init-db 19 | image: busybox:1.31 20 | command: ['sh', '-c', 'echo -e "Checking for the availability of MySQL Server deployment"; while ! nc -z mysql 3306; do sleep 1; printf "-"; done; echo -e " >> MySQL DB Server has started";'] 21 | containers: 22 | - name: usermgmt-webapp 23 | image: stacksimplify/kube-usermgmt-webapp:1.0.0-MySQLDB 24 | imagePullPolicy: Always 25 | ports: 26 | - containerPort: 8080 27 | env: 28 | - name: DB_HOSTNAME 29 | value: "mysql" 30 | - name: DB_PORT 31 | value: "3306" 32 | - name: DB_NAME 33 | value: "webappdb" 34 | - name: DB_USERNAME 35 | value: "root" 36 | - name: DB_PASSWORD 37 | value: "dbpassword11" 38 | # To schedule pods on based on NodeSelectors 39 | nodeSelector: 40 | app: java-apps 41 | 42 | -------------------------------------------------------------------------------- /25-Azure-DevOps-Terraform-Azure-AKS/Git-Repo-Files/kube-manifests/02-Java-Apps/07-UserMgmtWebApp-Service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: usermgmt-webapp-service 5 | labels: 6 | app: usermgmt-webapp 7 | spec: 8 | type: LoadBalancer 9 | selector: 10 | app: usermgmt-webapp 11 | ports: 12 | - port: 80 13 | targetPort: 8080 -------------------------------------------------------------------------------- /25-Azure-DevOps-Terraform-Azure-AKS/Git-Repo-Files/kube-manifests/03-Windows-DotNet-Apps/01-windows-app-deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: windows-app1-deployment 5 | labels: 6 | app: windows-app1 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: windows-app1 12 | template: 13 | metadata: 14 | name: windows-app1 15 | labels: 16 | app: windows-app1 17 | spec: 18 | # To schedule pods on based on NodeSelectors 19 | nodeSelector: 20 | #"beta.kubernetes.io/os": windows 21 | app: dotnet-apps 22 | containers: 23 | - name: windows-app1 24 | image: mcr.microsoft.com/dotnet/framework/samples:aspnetapp 25 | resources: 26 | limits: 27 | cpu: 1 28 | memory: 800M 29 | requests: 30 | cpu: .1 31 | memory: 300M 32 | ports: 33 | - containerPort: 80 34 | 35 | -------------------------------------------------------------------------------- /25-Azure-DevOps-Terraform-Azure-AKS/Git-Repo-Files/kube-manifests/03-Windows-DotNet-Apps/02-windows-app-loadbalancer-service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: windows-app1-loadbalancer-service 5 | spec: 6 | type: LoadBalancer 7 | selector: 8 | app: windows-app1 9 | ports: 10 | - protocol: TCP 11 | port: 80 -------------------------------------------------------------------------------- /25-Azure-DevOps-Terraform-Azure-AKS/Git-Repo-Files/pipeline-backups/pipeline-inputs.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------- 2 | # Terraform State Storage Azure RM 3 | Resource Group: terraform-storage-rg 4 | Storage Account: terraformstatexlrwdrzs 5 | Container: tfstatefiles 6 | 7 | # Manifests Folder 8 | terraform-manifests 9 | 10 | # System Default Working Directory 11 | $(System.DefaultWorkingDirectory)/terraform-manifests 12 | $(Pipeline.Workspace)/terraform-manifests-out 13 | # List Files 14 | - bash: echo Contents in Pipeline Workspace Artifact Directory; ls -Ra $(System.DefaultWorkingDirectory)/terraform-manifests 15 | -------------------------------------------- 16 | # Environment Name 17 | $(DEV_ENVIRONMENT) 18 | 19 | # Dev State File Name 20 | aks-$(DEV_ENVIRONMENT).tfstate 21 | 22 | # Pipeline Working Directory 23 | $(Pipeline.Workspace)/terraform-manifests-out 24 | 25 | # Dev Command Arguments for Terraform Plan 26 | -var ssh_public_key=$(sshkey.secureFilePath) 27 | -var environment=$(DEV_ENVIRONMENT) 28 | -out $(Pipeline.Workspace)/terraform-manifests-out/$(DEV_ENVIRONMENT)-$(Build.BuildId).out 29 | 30 | # 1- way 31 | terraform plan 32 | terraform apply 33 | 34 | # 2-way 35 | terraform plan -out v1plan.out 36 | terraform apply v1plan.out 37 | 38 | 39 | # Dev Command Arguments for Terraform Apply 40 | $(Pipeline.Workspace)/terraform-manifests-out/$(DEV_ENVIRONMENT)-$(Build.BuildId).out 41 | 42 | # List Files 43 | - bash: echo Contents in Pipeline Workspace Artifact Directory; ls -Ra $(Pipeline.Workspace)/terraform-manifests-out 44 | -------------------------------------------- 45 | # Environment Name 46 | $(QA_ENVIRONMENT) 47 | 48 | # QA State File 49 | aks-$(QA_ENVIRONMENT).tfstate 50 | 51 | # Pipeline Working Directory 52 | $(Pipeline.Workspace)/terraform-manifests-out 53 | 54 | # QA Command Arguments for Terraform Plan 55 | -var ssh_public_key=$(sshkey.secureFilePath) 56 | -var environment=$(QA_ENVIRONMENT) 57 | -out $(Pipeline.Workspace)/terraform-manifests-out/$(QA_ENVIRONMENT)-$(Build.BuildId).out 58 | 59 | # QA Command Arguments for Terraform Apply 60 | $(Pipeline.Workspace)/terraform-manifests-out/$(QA_ENVIRONMENT)-$(Build.BuildId).out 61 | -------------------------------------------- 62 | 63 | -------------------------------------------------------------------------------- /25-Azure-DevOps-Terraform-Azure-AKS/Git-Repo-Files/terraform-manifests/01-main.tf: -------------------------------------------------------------------------------- 1 | # We will define 2 | # 1. Terraform Settings Block 3 | # 1. Required Version Terraform 4 | # 2. Required Terraform Providers 5 | # 3. Terraform Remote State Storage with Azure Storage Account (last step of this section) 6 | # 2. Terraform Provider Block for AzureRM 7 | # 3. Terraform Resource Block: Define a Random Pet Resource 8 | 9 | # 1. Terraform Settings Block 10 | terraform { 11 | # 1. Required Version Terraform 12 | required_version = ">= 0.13" 13 | # 2. Required Terraform Providers 14 | required_providers { 15 | azurerm = { 16 | source = "hashicorp/azurerm" 17 | version = "~> 2.0" 18 | } 19 | azuread = { 20 | source = "hashicorp/azuread" 21 | version = "~> 1.0" 22 | } 23 | random = { 24 | source = "hashicorp/random" 25 | version = "~> 3.0" 26 | } 27 | } 28 | 29 | # Terraform State Storage to Azure Storage Container 30 | backend "azurerm" { 31 | #resource_group_name = "terraform-storage-rg" 32 | #storage_account_name = "terraformstatexlrwdrzs" 33 | #container_name = "tfstatefiles" 34 | #key = "terraform-custom-vnet.tfstate" 35 | } 36 | } 37 | 38 | 39 | 40 | # 2. Terraform Provider Block for AzureRM 41 | provider "azurerm" { 42 | features { 43 | 44 | } 45 | } 46 | 47 | # 3. Terraform Resource Block: Define a Random Pet Resource 48 | resource "random_pet" "aksrandom" { 49 | 50 | } 51 | 52 | -------------------------------------------------------------------------------- /25-Azure-DevOps-Terraform-Azure-AKS/Git-Repo-Files/terraform-manifests/02-variables.tf: -------------------------------------------------------------------------------- 1 | # Define Input Variables 2 | # 1. Azure Location (CentralUS) 3 | # 2. Azure Resource Group Name 4 | # 3. Azure AKS Environment Name (Dev, QA, Prod) 5 | 6 | # Azure Location 7 | variable "location" { 8 | type = string 9 | description = "Azure Region where all these resources will be provisioned" 10 | default = "Central US" 11 | } 12 | 13 | # Azure Resource Group Name 14 | variable "resource_group_name" { 15 | type = string 16 | description = "This variable defines the Resource Group" 17 | default = "terraform-aks" 18 | } 19 | 20 | # Azure AKS Environment Name 21 | variable "environment" { 22 | type = string 23 | description = "This variable defines the Environment" 24 | #default = "dev2" 25 | } 26 | 27 | 28 | # AKS Input Variables 29 | 30 | # SSH Public Key for Linux VMs 31 | variable "ssh_public_key" { 32 | #default = "~/.ssh/aks-prod-sshkeys-terraform/aksprodsshkey.pub" 33 | description = "This variable defines the SSH Public Key for Linux k8s Worker nodes" 34 | } 35 | 36 | # Windows Admin Username for k8s worker nodes 37 | variable "windows_admin_username" { 38 | type = string 39 | default = "azureuser" 40 | description = "This variable defines the Windows admin username k8s Worker nodes" 41 | } 42 | 43 | # Windows Admin Password for k8s worker nodes 44 | variable "windows_admin_password" { 45 | type = string 46 | default = "P@ssw0rd1234" 47 | description = "This variable defines the Windows admin password k8s Worker nodes" 48 | } 49 | 50 | -------------------------------------------------------------------------------- /25-Azure-DevOps-Terraform-Azure-AKS/Git-Repo-Files/terraform-manifests/03-resource-group.tf: -------------------------------------------------------------------------------- 1 | # Terraform Resource to Create Azure Resource Group with Input Variables defined in variables.tf 2 | resource "azurerm_resource_group" "aks_rg" { 3 | name = "${var.resource_group_name}-${var.environment}" 4 | location = var.location 5 | } 6 | 7 | 8 | -------------------------------------------------------------------------------- /25-Azure-DevOps-Terraform-Azure-AKS/Git-Repo-Files/terraform-manifests/04-aks-versions-datasource.tf: -------------------------------------------------------------------------------- 1 | # Documentation Reference: https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/kubernetes_service_versions 2 | # Datasource to get Latest Azure AKS latest Version 3 | data "azurerm_kubernetes_service_versions" "current" { 4 | location = azurerm_resource_group.aks_rg.location 5 | include_preview = false 6 | } 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /25-Azure-DevOps-Terraform-Azure-AKS/Git-Repo-Files/terraform-manifests/05-log-analytics-workspace.tf: -------------------------------------------------------------------------------- 1 | # Create Log Analytics Workspace 2 | resource "azurerm_log_analytics_workspace" "insights" { 3 | name = "${var.environment}-logs-${random_pet.aksrandom.id}" 4 | location = azurerm_resource_group.aks_rg.location 5 | resource_group_name = azurerm_resource_group.aks_rg.name 6 | retention_in_days = 30 7 | } -------------------------------------------------------------------------------- /25-Azure-DevOps-Terraform-Azure-AKS/Git-Repo-Files/terraform-manifests/06-aks-administrators-azure-ad.tf: -------------------------------------------------------------------------------- 1 | # Create Azure AD Group in Active Directory for AKS Admins 2 | resource "azuread_group" "aks_administrators" { 3 | name = "${azurerm_resource_group.aks_rg.name}-administrators" 4 | description = "Azure AKS Kubernetes administrators for the ${azurerm_resource_group.aks_rg.name}-administrators cluster." 5 | } -------------------------------------------------------------------------------- /25-Azure-DevOps-Terraform-Azure-AKS/Git-Repo-Files/terraform-manifests/07-aks-cluster.tf: -------------------------------------------------------------------------------- 1 | resource "azurerm_kubernetes_cluster" "aks_cluster" { 2 | dns_prefix = "${azurerm_resource_group.aks_rg.name}" 3 | location = azurerm_resource_group.aks_rg.location 4 | name = "${azurerm_resource_group.aks_rg.name}-cluster" 5 | resource_group_name = azurerm_resource_group.aks_rg.name 6 | kubernetes_version = data.azurerm_kubernetes_service_versions.current.latest_version 7 | node_resource_group = "${azurerm_resource_group.aks_rg.name}-nrg" 8 | 9 | 10 | default_node_pool { 11 | name = "systempool" 12 | vm_size = "Standard_DS2_v2" 13 | orchestrator_version = data.azurerm_kubernetes_service_versions.current.latest_version 14 | availability_zones = [1, 2, 3] 15 | enable_auto_scaling = true 16 | max_count = 3 17 | min_count = 1 18 | os_disk_size_gb = 30 19 | type = "VirtualMachineScaleSets" 20 | node_labels = { 21 | "nodepool-type" = "system" 22 | "environment" = var.environment 23 | "nodepoolos" = "linux" 24 | "app" = "system-apps" 25 | } 26 | tags = { 27 | "nodepool-type" = "system" 28 | "environment" = var.environment 29 | "nodepoolos" = "linux" 30 | "app" = "system-apps" 31 | } 32 | } 33 | 34 | # Identity (System Assigned or Service Principal) 35 | identity { type = "SystemAssigned" } 36 | 37 | # Add On Profiles 38 | addon_profile { 39 | azure_policy { enabled = true } 40 | oms_agent { 41 | enabled = true 42 | log_analytics_workspace_id = azurerm_log_analytics_workspace.insights.id 43 | } 44 | } 45 | 46 | # RBAC and Azure AD Integration Block 47 | role_based_access_control { 48 | enabled = true 49 | azure_active_directory { 50 | managed = true 51 | admin_group_object_ids = [azuread_group.aks_administrators.id] 52 | } 53 | } 54 | 55 | # Windows Admin Profile 56 | windows_profile { 57 | admin_username = var.windows_admin_username 58 | admin_password = var.windows_admin_password 59 | } 60 | 61 | # Linux Profile 62 | linux_profile { 63 | admin_username = "ubuntu" 64 | ssh_key { 65 | key_data = file(var.ssh_public_key) 66 | } 67 | } 68 | 69 | # Network Profile 70 | network_profile { 71 | load_balancer_sku = "Standard" 72 | network_plugin = "azure" 73 | } 74 | 75 | # AKS Cluster Tags 76 | tags = { 77 | Environment = var.environment 78 | } 79 | 80 | 81 | } -------------------------------------------------------------------------------- /25-Azure-DevOps-Terraform-Azure-AKS/Git-Repo-Files/terraform-manifests/08-outputs.tf: -------------------------------------------------------------------------------- 1 | # Create Outputs 2 | # 1. Resource Group Location 3 | # 2. Resource Group Id 4 | # 3. Resource Group Name 5 | 6 | # Resource Group Outputs 7 | output "location" { 8 | value = azurerm_resource_group.aks_rg.location 9 | } 10 | 11 | output "resource_group_id" { 12 | value = azurerm_resource_group.aks_rg.id 13 | } 14 | 15 | output "resource_group_name" { 16 | value = azurerm_resource_group.aks_rg.name 17 | } 18 | 19 | # Azure AKS Versions Datasource 20 | output "versions" { 21 | value = data.azurerm_kubernetes_service_versions.current.versions 22 | } 23 | 24 | output "latest_version" { 25 | value = data.azurerm_kubernetes_service_versions.current.latest_version 26 | } 27 | 28 | # Azure AD Group Object Id 29 | output "azure_ad_group_id" { 30 | value = azuread_group.aks_administrators.id 31 | } 32 | output "azure_ad_group_objectid" { 33 | value = azuread_group.aks_administrators.object_id 34 | } 35 | 36 | 37 | # Azure AKS Outputs 38 | 39 | output "aks_cluster_id" { 40 | value = azurerm_kubernetes_cluster.aks_cluster.id 41 | } 42 | 43 | output "aks_cluster_name" { 44 | value = azurerm_kubernetes_cluster.aks_cluster.name 45 | } 46 | 47 | output "aks_cluster_kubernetes_version" { 48 | value = azurerm_kubernetes_cluster.aks_cluster.kubernetes_version 49 | } 50 | -------------------------------------------------------------------------------- /25-Azure-DevOps-Terraform-Azure-AKS/Git-Repo-Files/terraform-manifests/09-aks-cluster-linux-user-nodepools.tf: -------------------------------------------------------------------------------- 1 | # Create Linux Azure AKS Node Pool 2 | /* 3 | resource "azurerm_kubernetes_cluster_node_pool" "linux101" { 4 | availability_zones = [1, 2, 3] 5 | enable_auto_scaling = true 6 | kubernetes_cluster_id = azurerm_kubernetes_cluster.aks_cluster.id 7 | max_count = 3 8 | min_count = 1 9 | mode = "User" 10 | name = "linux101" 11 | orchestrator_version = data.azurerm_kubernetes_service_versions.current.latest_version 12 | os_disk_size_gb = 30 13 | os_type = "Linux" # Default is Linux, we can change to Windows 14 | vm_size = "Standard_DS2_v2" 15 | priority = "Regular" # Default is Regular, we can change to Spot with additional settings like eviction_policy, spot_max_price, node_labels and node_taints 16 | node_labels = { 17 | "nodepool-type" = "user" 18 | "environment" = var.environment 19 | "nodepoolos" = "linux" 20 | "app" = "java-apps" 21 | } 22 | tags = { 23 | "nodepool-type" = "user" 24 | "environment" = var.environment 25 | "nodepoolos" = "linux" 26 | "app" = "java-apps" 27 | } 28 | } 29 | */ 30 | -------------------------------------------------------------------------------- /25-Azure-DevOps-Terraform-Azure-AKS/Git-Repo-Files/terraform-manifests/10-aks-cluster-windows-user-nodepools.tf: -------------------------------------------------------------------------------- 1 | # Create Windows Azure AKS Node Pool 2 | /* 3 | resource "azurerm_kubernetes_cluster_node_pool" "win101" { 4 | availability_zones = [1, 2, 3] 5 | enable_auto_scaling = true 6 | kubernetes_cluster_id = azurerm_kubernetes_cluster.aks_cluster.id 7 | max_count = 3 8 | min_count = 1 9 | mode = "User" 10 | name = "win101" 11 | orchestrator_version = data.azurerm_kubernetes_service_versions.current.latest_version 12 | os_disk_size_gb = 30 13 | os_type = "Windows" # Default is Linux, we can change to Windows 14 | vm_size = "Standard_DS2_v2" 15 | priority = "Regular" # Default is Regular, we can change to Spot with additional settings like eviction_policy, spot_max_price, node_labels and node_taints 16 | node_labels = { 17 | "nodepool-type" = "user" 18 | "environment" = var.environment 19 | "nodepoolos" = "windows" 20 | "app" = "dotnet-apps" 21 | } 22 | tags = { 23 | "nodepool-type" = "user" 24 | "environment" = var.environment 25 | "nodepoolos" = "windows" 26 | "app" = "dotnet-apps" 27 | } 28 | } 29 | */ 30 | -------------------------------------------------------------------------------- /25-Azure-DevOps-Terraform-Azure-AKS/Git-Repo-Files/terraform-manifests/11-aks-cluster-linux102-user-nodepools.tf: -------------------------------------------------------------------------------- 1 | # Create Linux Azure AKS Node Pool 2 | /* 3 | resource "azurerm_kubernetes_cluster_node_pool" "linux102" { 4 | availability_zones = [1, 2, 3] 5 | enable_auto_scaling = true 6 | kubernetes_cluster_id = azurerm_kubernetes_cluster.aks_cluster.id 7 | max_count = 3 8 | min_count = 1 9 | mode = "User" 10 | name = "linux102" 11 | orchestrator_version = data.azurerm_kubernetes_service_versions.current.latest_version 12 | os_disk_size_gb = 30 13 | os_type = "Linux" # Default is Linux, we can change to Windows 14 | vm_size = "Standard_DS2_v2" 15 | priority = "Regular" # Default is Regular, we can change to Spot with additional settings like eviction_policy, spot_max_price, node_labels and node_taints 16 | node_labels = { 17 | "nodepool-type" = "user" 18 | "environment" = var.environment 19 | "nodepoolos" = "linux" 20 | "ui-app" = "reactjs-apps" 21 | } 22 | tags = { 23 | "nodepool-type" = "user" 24 | "environment" = var.environment 25 | "nodepoolos" = "linux" 26 | "ui-app" = "reactjs-apps" 27 | } 28 | } 29 | */ -------------------------------------------------------------------------------- /git-deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "Add files and do local commit" 4 | git add . 5 | git commit -am "Welcome to Stack Simplify" 6 | 7 | echo "Pushing to Github Repository" 8 | git push 9 | -------------------------------------------------------------------------------- /ppt-presentation/Azure-AKS-Kubernetes-Masterclass-V16.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Soprano37/stacksimplify-azure-aks-kubernetes-masterclass/f0613acf522faa27f97c34b0193344a68b20bc69/ppt-presentation/Azure-AKS-Kubernetes-Masterclass-V16.pdf -------------------------------------------------------------------------------- /ppt-presentation/Azure-AKS-Kubernetes-Masterclass-V16.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Soprano37/stacksimplify-azure-aks-kubernetes-masterclass/f0613acf522faa27f97c34b0193344a68b20bc69/ppt-presentation/Azure-AKS-Kubernetes-Masterclass-V16.pptx --------------------------------------------------------------------------------