├── 01-AGIC-Install-Greenfield └── README.md ├── 02-AGIC-Default-Backend ├── README.md └── kube-manifests │ ├── 01-myapp-Deployment.yaml │ ├── 02-myapp-ClusterIP-Service.yaml │ └── 03-Ingress-Default-Backend.yaml ├── 03-AGIC-Ingress-Paths ├── README.md └── kube-manifests │ ├── 01-NginxApp1-Deployment.yaml │ ├── 02-NginxApp1-ClusterIP-Service.yaml │ └── 03-Ingress-HTTP-Paths.yaml ├── 04-AGIC-Ingress-URL-Routing ├── 01-kube-manifests-defaultBackend │ ├── 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-MyApp-Manifests │ │ ├── 01-myapp-Deployment.yaml │ │ └── 02-myapp-ClusterIP-Service.yaml │ └── 04-IngressService-Manifests │ │ └── 01-Ingress-URL-Routing.yml ├── 02-kube-manifests-root-httppath │ ├── 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-MyApp-Manifests │ │ ├── 01-myapp-Deployment.yaml │ │ └── 02-myapp-ClusterIP-Service.yaml │ └── 04-IngressService-Manifests │ │ └── 01-Ingress-URL-Routing.yml └── README.md ├── 05-AGIC-Backend-PathPrefix ├── README.md └── kube-manifests │ ├── 01-NginxApp1-Deployment.yml │ ├── 02-NginxApp1-ClusterIP-Service.yml │ └── 03-Ingress-backend-path-prefix.yml ├── 06-AGIC-Backend-Hostname ├── README.md └── kube-manifests │ ├── 01-EchoServer-Deployment.yaml │ ├── 02-EchoServer-ClusterIP-Service.yaml │ └── 03-Ingress-backend-hostname.yaml ├── 07-AGIC-Cookie-based-Affinity ├── 01-kube-manifests-cookie-affinity │ ├── 01-EchoServer-Deployment.yaml │ ├── 02-EchoServer-ClusterIP-Service.yaml │ └── 03-Ingress-cookie-affinity.yaml ├── 02-kube-manifests-distinct-cookie │ ├── 01-EchoServer-Deployment.yaml │ ├── 02-EchoServer-ClusterIP-Service.yaml │ └── 03-Ingress-cookie-affinity-distinct.yaml └── README.md ├── 08-AGIC-Override-Frontend-Port ├── README.md └── kube-manifests │ ├── 01-myapp-Deployment.yaml │ ├── 02-myapp-ClusterIP-Service.yaml │ └── 03-Ingress-override-frontend.yaml ├── 09-AGIC-Rewrite-Rule-Set ├── README.md └── kube-manifests │ ├── 01-EchoServer-Deployment.yaml │ ├── 02-EchoServer-ClusterIP-Service.yaml │ └── 03-Ingress-rewrite-rule-set.yaml ├── 10-AGIC-Probes-Default-and-HTTP ├── 01-kube-manifests-default-backend │ ├── 01-myapp-Deployment.yaml │ ├── 02-myapp-ClusterIP-Service.yaml │ └── 03-Ingress-Default-Backend.yaml ├── 02-kube-manifests-http-path │ ├── 01-NginxApp1-Deployment.yaml │ ├── 02-NginxApp1-ClusterIP-Service.yaml │ └── 03-Ingress-HTTP-Paths.yaml └── README.md ├── 11-AGIC-Probes-Readniess-Liveness ├── 01-kube-manifests-readiness │ ├── 01-NginxApp1-Deployment.yml │ ├── 02-NginxApp1-ClusterIP-Service.yml │ └── 03-Ingress-Basic.yml ├── 02-kube-manifests-liveness │ ├── 01-NginxApp2-Deployment.yml │ ├── 02-NginxApp2-ClusterIP-Service.yml │ └── 03-Ingress-Basic.yml ├── 03-kube-manifests-both │ ├── 01-NginxApp1-Deployment.yml │ ├── 02-NginxApp1-ClusterIP-Service.yml │ └── 03-Ingress-Basic.yml └── README.md ├── 12-AGIC-Probes-Annotations ├── README.md └── kube-manifests │ ├── 01-NginxApp1-Deployment.yml │ ├── 02-NginxApp1-ClusterIP-Service.yml │ └── 03-Ingress-Basic.yml ├── 13-Delegate-Domain-from-AWS-Route53-to-Azure-DNS └── README.md ├── 14-ExternalDNS-for-AzureDNS-on-AKS ├── README.md ├── azure.json └── kube-manifests │ └── external-dns.yaml ├── 15-AGIC-ExternalDNS-Basic ├── README.md └── kube-manifests │ ├── 01-NginxApp1-Deployment.yaml │ ├── 02-NginxApp1-ClusterIP-Service.yaml │ └── 03-Ingress-with-ExternalDNS.yaml ├── 16-AGIC-Domain-Name-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-MyApp-Manifests │ ├── 01-myapp-Deployment.yaml │ └── 02-myapp-ClusterIP-Service.yaml │ └── 04-IngressService-Manifests │ └── 01-Ingress-DomainName-Based-Routing-app1-2-3.yml ├── 17-AGIC-Ingress-TLS ├── README.md ├── SSL-SelfSigned-Certs │ ├── app1-ingress.crt │ ├── app1-ingress.csr │ └── app1-ingress.key └── kube-manifests │ ├── 01-myapp-Deployment.yaml │ ├── 02-myapp-ClusterIP-Service.yaml │ └── 03-Ingress-SSL-TLS.yaml ├── 18-AGIC-SSL-Redirect ├── README.md └── kube-manifests │ ├── 01-myapp-Deployment.yaml │ ├── 02-myapp-ClusterIP-Service.yaml │ └── 03-Ingress-SSL-TLS.yaml ├── 19-AGIC-Upload-SSLCert-AppGW ├── README.md ├── SSL-SelfSigned-Certs │ ├── app2-ingress.crt │ ├── app2-ingress.csr │ ├── app2-ingress.key │ └── app2-ingress.pfx └── kube-manifests │ ├── 01-myapp-Deployment.yaml │ ├── 02-myapp-ClusterIP-Service.yaml │ └── 03-Ingress-AppGW-SSL-Cert.yaml ├── 20-AGIC-Backend-SSL-Application ├── README.md ├── SSL-SelfSigned-Certs │ ├── backend-ssl.crt │ ├── backend-ssl.csr │ └── backend-ssl.key └── kube-manifests │ ├── 01-myapp-configmap.yaml │ ├── 02-myapp-Deployment.yaml │ └── 03-myapp-LoadBalancer-Service.yaml ├── 21-AGIC-End2End-SSL ├── README.md ├── SSL-SelfSigned-Certs │ ├── backend-ssl.crt │ ├── backend-ssl.csr │ ├── backend-ssl.key │ ├── frontend-ingress.crt │ ├── frontend-ingress.csr │ └── frontend-ingress.key └── kube-manifests │ ├── 01-myapp-configmap.yaml │ ├── 02-myapp-Deployment.yaml │ ├── 03-myapp-ClusterIP-Service.yaml │ └── 04-Ingress-e2e-ssl.yaml ├── 22-AGIC-SSL-with-LetsEncrypt ├── 01-CertManager-ClusterIssuer │ └── cluster-issuer.yml ├── 02-kube-manifests │ ├── 01-NginxApp1-Deployment.yaml │ ├── 02-NginxApp1-ClusterIP-Service.yaml │ ├── 03-NginxApp2-Deployment.yaml │ ├── 04-NginxApp2-ClusterIP-Service.yaml │ └── 05-Ingress-SSL-LetsEncrypt.yaml └── README.md ├── 23-AGIC-WAF-OWASP ├── README.md └── kube-manifests │ ├── 01-NginxApp1-Deployment.yaml │ ├── 02-NginxApp1-ClusterIP-Service.yaml │ └── 03-Ingress-WAF.yaml ├── 24-AGIC-WAF-Policy ├── 01-kube-manifests-scope-RoutePath │ ├── 01-NginxApp1-Deployment.yaml │ ├── 02-NginxApp1-ClusterIP-Service.yaml │ └── 03-Ingress-WAF.yaml ├── 02-kube-manifests-scope-listener │ ├── 01-NginxApp1-Deployment.yaml │ ├── 02-NginxApp1-ClusterIP-Service.yaml │ └── 03-Ingress-WAF.yaml └── README.md ├── 25-AGIC-Private-IP ├── 01-kube-manifests │ ├── 01-EchoServer-Deployment.yaml │ ├── 02-EchoServer-ClusterIP-Service.yaml │ └── 03-Ingress-privateip.yaml ├── 02-kube-manifests-curl │ └── 01-curl-pod.yml └── README.md ├── 26-AGIC-and-Nginx-Ingress ├── README.md ├── kube-manifests │ ├── 01-App1-NginxIC │ │ ├── 01-NginxApp1-Deployment.yaml │ │ ├── 02-NginxApp1-ClusterIP-Service.yaml │ │ └── 03-Ingress.yaml │ └── 02-App2-AGIC │ │ ├── 01-NginxApp2-Deployment.yml │ │ ├── 02-NginxApp2-ClusterIP-Service.yml │ │ └── 03-Ingress.yaml └── values.yaml ├── 27-AGIC-Install-using-Helm ├── README.md ├── helm-config.yaml └── kube-manifests │ ├── 01-NginxApp1-Deployment.yaml │ ├── 02-NginxApp1-ClusterIP-Service.yaml │ └── 03-Ingress-HTTP-Paths.yaml ├── 28-AGIC-Shared-AppGateway ├── 01-kube-manifests │ ├── 01-myapp-Deployment.yaml │ ├── 02-myapp-ClusterIP-Service.yaml │ └── 03-Ingress-myapp.yaml ├── 02-prohibit-files │ ├── prohibit-all-targets.yaml │ └── prohibit-myaciapp1.yaml ├── README.md └── helm-config-shared-true.yaml ├── 29-AGIC-Watch-Namespaces ├── 01-app1-staging-kube-manifests │ ├── 01-NginxApp1-Deployment.yaml │ ├── 02-NginxApp1-ClusterIP-Service.yaml │ └── 03-Ingress-app1.yaml ├── 02-app2-production-kube-manifests │ ├── 01-NginxApp2-Deployment.yml │ ├── 02-NginxApp2-ClusterIP-Service.yml │ └── 03-Ingress-app2.yaml ├── README.md └── helm-config-watch-prod-namespace.yaml ├── README.md ├── azure-agic.png ├── azure-agic1.png ├── course-presentation └── Azure-AKS-AGIC-v2.pptx └── git-deploy.sh /01-AGIC-Install-Greenfield/README.md: -------------------------------------------------------------------------------- 1 | # Azure AGIC Install using Add-On on Azure AKS Cluster (Greenfield) 2 | 3 | ## Step-01: Introduction 4 | - Enable the AGIC add-on for a new AKS cluster with a new application gateway instance 5 | - Create New Azure AKS Cluster with 6 | - New Application Gateway 7 | - **Add On:** AGIC (ingress-appgw) 8 | - Enable Autoscaling 9 | 10 | ## Step-02: Create AKS Cluster 11 | ```t 12 | # Create Resource Group 13 | az group create --location eastus --resource-group agicdemo 14 | 15 | # Create AKS Cluser 16 | az aks create --name agic-cluster \ 17 | --resource-group agicdemo \ 18 | --network-plugin azure \ 19 | --enable-managed-identity \ 20 | --enable-addons ingress-appgw \ 21 | --appgw-name agic-appgw \ 22 | --appgw-subnet-cidr "10.225.0.0/16" \ 23 | --node-count 1 \ 24 | --enable-cluster-autoscaler \ 25 | --min-count 1 \ 26 | --max-count 2 \ 27 | --generate-ssh-keys 28 | ``` 29 | 30 | ## Step-03: Assign network contributor role to AGIC addon Managed Identity 31 | ```t 32 | # Get application gateway id from AKS addon profile 33 | appGatewayId=$(az aks show -n agic-cluster -g agicdemo -o tsv --query "addonProfiles.ingressApplicationGateway.config.effectiveApplicationGatewayId") 34 | echo $appGatewayId 35 | 36 | # Get Application Gateway subnet id 37 | appGatewaySubnetId=$(az network application-gateway show --ids $appGatewayId -o tsv --query "gatewayIPConfigurations[0].subnet.id") 38 | echo $appGatewaySubnetId 39 | 40 | # Get AGIC addon identity 41 | agicAddonIdentity=$(az aks show -n agic-cluster -g agicdemo -o tsv --query "addonProfiles.ingressApplicationGateway.identity.clientId") 42 | echo $agicAddonIdentity 43 | 44 | # Assign network contributor role to AGIC addon Managed Identity to subnet that contains the Application Gateway 45 | az role assignment create --assignee $agicAddonIdentity --scope $appGatewaySubnetId --role "Network Contributor" 46 | ``` 47 | 48 | ## Step-04: Verify AKS Cluster 49 | ```t 50 | # configure kubeconfig 51 | az aks get-credentials --resource-group agicdemo --name agic-cluster 52 | 53 | # List Kubernetes Nodes 54 | kubectl get nodes 55 | ``` 56 | 57 | ## Step-05: Verify AKS Add On 58 | ```t 59 | # List Kubernetes Deployments in kube-system namespace 60 | kubectl get deploy -n kube-system 61 | Observation: 62 | 1. Should find the deployment with name "ingress-appgw-deployment" 63 | 2. This is the Azure Application Gateway Ingress Controller Kubernetes Deployment Object 64 | 65 | # List Pods 66 | kubectl get pods -n kube-system 67 | 68 | # Describe Pod 69 | kubectl -n kube-system describe pod 70 | kubectl -n kube-system describe pod ingress-appgw-deployment-55965f45cf-x28fm 71 | Observation: 72 | 1. Review the line where you can find ingress current version downloaded 73 | 2. Pulling image "mcr.microsoft.com/azure-application-gateway/kubernetes-ingress:1.5.3" 74 | 3. You can also run the below command to find the AppGW Ingress version 75 | kubectl get deploy ingress-appgw-deployment -o yaml -n kube-system | grep "image:" 76 | 77 | # Verify ingress-appgw pod Logs 78 | kubectl -n kube-system logs -f $(kubectl -n kube-system get po | egrep -o 'ingress-appgw-deployment[A-Za-z0-9-]+') 79 | ``` 80 | 81 | ## Step-06: Verify latest release 82 | - [Azure AGIC Git Repo Releases](https://github.com/Azure/application-gateway-kubernetes-ingress/releases) 83 | - What is our takeway? 84 | - We will always find AKS Addon will be using stable version which will be few versions lesser than the latest version present in `Releases` section 85 | - Azure recommends to use AKS Add On approach (Greenfield or Brownfield) 86 | - In production, we should prefer to use AKS Add On approach only 87 | - We can also use latest version of AGIC by deploying using HELM (Not Recommended for production) 88 | 89 | ## Step-07: Verify Azure AKS Cluster using Azure Portal 90 | - Review AKS cluster all tabs 91 | 92 | ## Step-08: Verify Application Gateway using Azure Portal 93 | - Please review and observe all default settings in detail 94 | - **Overview Tab:** 95 | - Resource Group: MC_agicdemo_agic-cluster_eastus 96 | - Review frontend IP 97 | - Tier: V2 98 | - **Configuration Tab:** 99 | - For cost saving we can also change instance count to 1 and save 100 | - In next steps we will also discuss about stopping Application Gateway using command line 101 | - **Web Application Firewall Tab:** 102 | - We will enable and use this in later demos of the course. 103 | - **Backend Pools Tab:** 104 | - We should see default address pool 105 | - **Backend Settings Tab:** 106 | - We should see defaulthttpsetting 107 | - **Frontend IP configurations Tab:** 108 | - We should see public ip configured 109 | - We should see private ip not configured 110 | - **Listeners Tab:** 111 | - We should see default port 80 listener configured 112 | - **Rules Tab:** 113 | - We should see default basic rule configured 114 | - Open default rule and review `Backend Targets` tab, you should see `defaultaddresspool` 115 | - This changes when you deploy sample app in next demo. 116 | - **Health probes Tab:** 117 | - We should see default HTTP and HTTPS probes 118 | - **Properties Tab:** 119 | - Resource ID 120 | - Location 121 | - Resource group 122 | 123 | ## Step-09: Cost Saving - Stop Azure AKS and Application Gateway 124 | ```t 125 | # Azure AKS Cluster 126 | In portal, go to Overview Tab and click on "STOP" 127 | 128 | # Azure Application Gateway STOP 129 | az network application-gateway stop --name --resource-group 130 | az network application-gateway stop --name agic-appgw --resource-group MC_agicdemo_agic-cluster_eastus 131 | ``` 132 | 133 | ## Step-10: Start Azure AKS and Application Gateway 134 | ```t 135 | # Important Note 136 | - Wait for 15 minutes before starting them back 137 | 138 | # Azure AKS Cluster 139 | In portal, go to Overview Tab and click on "START" 140 | 141 | # Azure Application Gateway START 142 | az network application-gateway start --name --resource-group 143 | az network application-gateway start --name agic-appgw --resource-group MC_agicdemo_agic-cluster_eastus 144 | ``` 145 | 146 | 147 | ## Additional References 148 | - [Greenfield: AGIC Add-On on AKS Cluster](https://learn.microsoft.com/en-us/azure/application-gateway/tutorial-ingress-controller-add-on-new) 149 | - [Brownfield: AGIC Add-On on AKS Cluster](https://learn.microsoft.com/en-us/azure/application-gateway/tutorial-ingress-controller-add-on-existing) 150 | - [Greenfield: AGIC using Helm on AKS Cluster](https://learn.microsoft.com/en-us/azure/application-gateway/ingress-controller-install-new) 151 | - [Brownfield: AGIC using Helm on AKS Cluster](https://learn.microsoft.com/en-us/azure/application-gateway/ingress-controller-install-existing) 152 | - https://azure.microsoft.com/en-us/blog/application-gateway-ingress-controller-for-azure-kubernetes-service/ 153 | - https://learn.microsoft.com/en-us/azure/application-gateway/tutorial-ingress-controller-add-on-new?tryIt=true&source=docs#deploy-an-aks-cluster-with-the-add-on-enabled 154 | - https://learn.microsoft.com/en-us/azure/architecture/example-scenario/aks-agic/aks-agic 155 | -------------------------------------------------------------------------------- /02-AGIC-Default-Backend/README.md: -------------------------------------------------------------------------------- 1 | # Ingress - Default Backend 2 | 3 | ## Step-01: Introduction 4 | - We are going to understand and implement about Ingress Default Backend 5 | 6 | ## Step-02: Review k8s Application Manifests 7 | - **Deployment Manifest:** 01-myapp-Deployment.yaml 8 | - **Cluster IP Service Manifest:** 02-myapp-ClusterIP-Service.yaml 9 | 10 | ## Step-03: Review Ingress Service Manifests 11 | - [Ingress API Reference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/) 12 | - **Ingress Manifest:** 03-Ingress-Default-Backend.yaml 13 | ```yaml 14 | apiVersion: networking.k8s.io/v1 15 | kind: Ingress 16 | metadata: 17 | name: myapp-ingress-service 18 | annotations: 19 | kubernetes.io/ingress.class: azure/application-gateway 20 | spec: 21 | defaultBackend: 22 | service: 23 | name: myapp-nginx-clusterip-service 24 | port: 25 | number: 80 26 | ``` 27 | 28 | ## Step-04: Deploy and Verify 29 | ```t 30 | # Deploy Apps 31 | kubectl apply -f kube-manifests/ 32 | 33 | # List Deployments 34 | kubectl get deploy 35 | 36 | # List Pods 37 | kubectl get pods 38 | 39 | # List Services 40 | kubectl get svc 41 | 42 | # List Ingress 43 | kubectl get ingress 44 | ``` 45 | 46 | ## Step-05: Access Applications 47 | ```t 48 | # Access using curl 49 | curl http:// 50 | 51 | # Access using Browser 52 | http:// 53 | ``` 54 | 55 | ## Step-06: Verify Application Gateway Ingress Pod Logs 56 | ```t 57 | # Verify ingress-appgw pod Logs 58 | kubectl -n kube-system logs -f $(kubectl -n kube-system get po | egrep -o 'ingress-appgw-deployment[A-Za-z0-9-]+') 59 | ``` 60 | 61 | ## Step-07: Verify Azure AKS Cluster using Azure Portal 62 | - **Workloads:** 63 | - We should see `myapp-nginx-deployment` 64 | - **Services and Ingresses Tab:** 65 | - We should see `myapp-nginx-clusterip-service` 66 | 67 | ## Step-08: Verify Application Gateway using Azure Portal 68 | - Please review and observe all default settings in detail 69 | - **Backend Pools Tab:** 70 | - You should see new pool with name like `pool-default-myapp-nginx-clusterip-service-80-bp-80` 71 | - Review `IP Address` in `Backend Targets` 72 | - Verify if it is same as our POD IP 73 | - **Backend Settings Tab:** 74 | - We should see a new setting with name as `bp-default-myapp-nginx-clusterip-service-80-80-myapp-ingress-service` 75 | - Review the probe which is `defaultprobe-Http` 76 | - **Frontend IP configurations Tab:** 77 | - We should see public ip configured 78 | - We should see private ip not configured 79 | - NO CHANGES 80 | - **Listeners Tab:** 81 | - We should see default port 80 listener configured 82 | - NO CHANGES 83 | - **Rules Tab:** 84 | - We should see default basic rule configured 85 | - Open default rule and review `Backend Targets` tab, you should see `pool-default-myapp-nginx-clusterip-service-80-bp-80` 86 | - `defaultaddresspool` changed to new pool created as part of our Kubernetes deployment 87 | - **Health probes Tab:** 88 | - We should see default HTTP and HTTPS probes 89 | - Review Pod logs 90 | ```t 91 | # Verify pod Logs 92 | kubectl get pods 93 | kubectl logs -f 94 | kubectl logs -f myapp-nginx-deployment-77df6b5877-wlznj 95 | 96 | # In parallel access Application via browser 97 | http:// 98 | 99 | ## HEALTH PROBE LOGS (Application Gateway polling the Pod) 100 | 10.225.0.6 - - [03/Sep/2023:11:33:27 +0000] "GET / HTTP/1.1" 200 218 "-" "-" "-" 101 | 10.225.0.4 - - [03/Sep/2023:11:33:28 +0000] "GET / HTTP/1.1" 200 218 "-" "-" "-" 102 | 103 | # Log for request we made from browser 104 | 10.225.0.6 - - [03/Sep/2023:11:34:07 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36" "175.101.19.211:19596" 105 | ``` 106 | 107 | ## Step-09: Clean-Up Applications 108 | ```t 109 | # Delete Apps 110 | kubectl delete -f kube-manifests/ 111 | 112 | # Review Application Gateway Tabs 113 | 1. Backend Pools Tab 114 | 2. Backend Settings Tab 115 | 3. Rules Tab 116 | ``` 117 | 118 | -------------------------------------------------------------------------------- /02-AGIC-Default-Backend/kube-manifests/01-myapp-Deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: myapp-nginx-deployment 5 | labels: 6 | app: myapp-nginx 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: myapp-nginx 12 | template: 13 | metadata: 14 | labels: 15 | app: myapp-nginx 16 | spec: 17 | containers: 18 | - name: myapp-nginx 19 | image: ghcr.io/stacksimplify/kubenginx:1.0.0 20 | ports: 21 | - containerPort: 80 22 | 23 | -------------------------------------------------------------------------------- /02-AGIC-Default-Backend/kube-manifests/02-myapp-ClusterIP-Service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: myapp-nginx-clusterip-service 5 | labels: 6 | app: myapp-nginx 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | app: myapp-nginx 11 | ports: 12 | - port: 80 13 | targetPort: 80 14 | -------------------------------------------------------------------------------- /02-AGIC-Default-Backend/kube-manifests/03-Ingress-Default-Backend.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: myapp-ingress-service 5 | annotations: 6 | kubernetes.io/ingress.class: azure/application-gateway 7 | spec: 8 | #ingressClassName: azure-application-gateway 9 | defaultBackend: 10 | service: 11 | name: myapp-nginx-clusterip-service 12 | port: 13 | number: 80 14 | 15 | 16 | -------------------------------------------------------------------------------- /03-AGIC-Ingress-Paths/README.md: -------------------------------------------------------------------------------- 1 | # Ingress - Paths 2 | 3 | ## Step-01: Introduction 4 | - We are going to understand and implement about `Ingress Paths` 5 | - In addition, also discuss about `spec.ingressClassName` 6 | ```t 7 | # List Ingress Classes on AKS Cluster 8 | kubectl get ingressclass 9 | 10 | # Describe Ingress Class 11 | kubectl describe ingressclass 12 | kubectl describe ingressclass azure-application-gateway 13 | 14 | # Review YAM Output of Ingress Class 15 | kubectl get ingressclass azure-application-gateway -o yaml 16 | ``` 17 | 18 | ## Step-02: Review k8s Application Manifests 19 | - **App1 Deployment Manifest:** 01-NginxApp1-Deployment.yaml 20 | - **App1 Cluster IP Service Manifest:** 02-NginxApp1-ClusterIP-Service.yaml 21 | 22 | ## Step-03: Review Ingress Service Manifests 23 | - [Ingress API Reference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/) 24 | - Discuss in detail about [Ingress Paths](https://kubernetes.io/docs/concepts/services-networking/ingress/#examples) 25 | - **Ingress Manifest:** 03-Ingress-HTTP-Paths.yaml 26 | ```yaml 27 | apiVersion: networking.k8s.io/v1 28 | kind: Ingress 29 | metadata: 30 | name: nginxapp1-ingress-service 31 | spec: 32 | ingressClassName: azure-application-gateway 33 | rules: 34 | - http: 35 | paths: 36 | - path: / # Comment at Step-09 37 | #- path: /app1 # UnComment at Step-09 38 | pathType: Prefix 39 | backend: 40 | service: 41 | name: app1-nginx-clusterip-service 42 | port: 43 | number: 80 44 | ``` 45 | 46 | ## Step-04: Deploy and Verify 47 | ```t 48 | # Deploy Apps 49 | kubectl apply -f kube-manifests/ 50 | 51 | # List Deployments 52 | kubectl get deploy 53 | 54 | # List Pods 55 | kubectl get pods 56 | 57 | # List Services 58 | kubectl get svc 59 | 60 | # List Ingress 61 | kubectl get ingress 62 | ``` 63 | 64 | ## Step-05: Access Applications 65 | ```t 66 | # Access Root Context 67 | curl http:// 68 | http:// 69 | Observation: default nginx index.html should be displayed 70 | 71 | # Access /app1 72 | curl http:///app1/index.html 73 | http:///app1/index.html 74 | Observation: app1 index.html should be displayed 75 | ``` 76 | 77 | ## Step-06: Verify Application Gateway Ingress Pod Logs 78 | ```t 79 | # Verify ingress-appgw pod Logs 80 | kubectl -n kube-system logs -f $(kubectl -n kube-system get po | egrep -o 'ingress-appgw-deployment[A-Za-z0-9-]+') 81 | ``` 82 | 83 | ## Step-07: Verify Azure AKS Cluster using Azure Portal 84 | - **Workloads:** 85 | - We should see `app1-nginx-deployment` 86 | - **Services and Ingresses Tab:** 87 | - We should see `app1-nginx-clusterip-service` 88 | 89 | ## Step-08: Verify Application Gateway using Azure Portal 90 | - Please review and observe all default settings in detail 91 | - **Backend Pools Tab:** Review Backend Pools 92 | - **Backend Settings Tab:** 93 | - Review `Backend Port` 94 | - Review the probe `custom probe` 95 | - **Rules Tab:** 96 | - We should see default basic rule configured 97 | - Open default rule and review `Backend Targets` tab 98 | - **Health probes Tab:** 99 | - We should see `custom HTTP probe` created 100 | - Review Pod logs (optional) 101 | ```t 102 | # Verify pod Logs 103 | kubectl get pods 104 | kubectl logs -f 105 | kubectl logs -f app1-nginx-deployment-ff56dcf94-j7nq8 106 | 107 | # In parallel access Application via browser 108 | http:///app1/index.html 109 | 110 | ## HEALTH PROBE LOGS (Application Gateway polling the Pod) 111 | 10.225.0.6 - - [03/Sep/2023:11:33:27 +0000] "GET / HTTP/1.1" 200 218 "-" "-" "-" 112 | 10.225.0.4 - - [03/Sep/2023:11:33:28 +0000] "GET / HTTP/1.1" 200 218 "-" "-" "-" 113 | 114 | # Log for request we made from browser 115 | 10.225.0.6 - - [03/Sep/2023:11:34:07 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36" "175.101.19.211:19596" 116 | ``` 117 | 118 | ## Step-09: Update Ingress Path, Deploy and Verify 119 | ```t 120 | # Change Path from / to /app1 121 | spec: 122 | rules: 123 | - http: 124 | paths: 125 | #- path: / # Comment at Step-09 126 | - path: /app1 # UnComment at Step-09 127 | 128 | # Deploy and Verify 129 | kubectl apply -f kube-manifests 130 | 131 | # Access Root Context 132 | curl http:// 133 | http:// 134 | Observation: 135 | 1. This should fail, and we should get 502 bad gateway error from AppGw 136 | 2. Go to AppGw -> Rules -> Backend Targets, we should see a path based rule 137 | 138 | # Access /app1 139 | curl http:///app1/index.html 140 | http:///app1/index.html 141 | Observation: 142 | 1. app1 index.html should be displayed 143 | 2. Go to AppGw -> Rules -> Backend Targets, we should see a path based rule 144 | ``` 145 | 146 | ## Step-10: Scale the Application and Verify if new pods added in AppGw Backend Pools 147 | ```t 148 | # List Pod with Pod IP 149 | kubectl get pods -o wide 150 | 151 | # Scale our Application and see those all pod IPs displayed as Backend Targets 152 | kubectl scale deployment app1-nginx-deployment --replicas=5 153 | 154 | # List Pod with Pod IP 155 | kubectl get pods -o wide 156 | 157 | # Go to AppGw -> Backend Pools 158 | 1. We should see 5 pods added with Pod IPs 159 | ``` 160 | 161 | ## Step-11: Clean-Up Applications 162 | ```t 163 | # Delete Apps 164 | kubectl delete -f kube-manifests/ 165 | 166 | # Review Application Gateway Tabs 167 | 1. Backend Pools Tab 168 | 2. Backend Settings Tab 169 | 3. Rules Tab 170 | ``` -------------------------------------------------------------------------------- /03-AGIC-Ingress-Paths/kube-manifests/01-NginxApp1-Deployment.yaml: -------------------------------------------------------------------------------- 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: ghcr.io/stacksimplify/kube-nginxapp1:1.0.0 20 | ports: 21 | - containerPort: 80 22 | 23 | -------------------------------------------------------------------------------- /03-AGIC-Ingress-Paths/kube-manifests/02-NginxApp1-ClusterIP-Service.yaml: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /03-AGIC-Ingress-Paths/kube-manifests/03-Ingress-HTTP-Paths.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: nginxapp1-ingress-service 5 | spec: 6 | ingressClassName: azure-application-gateway 7 | rules: 8 | - http: 9 | paths: 10 | - path: / # Comment at Step-09 11 | #- path: /app1 # UnComment at Step-09 12 | pathType: Prefix 13 | backend: 14 | service: 15 | name: app1-nginx-clusterip-service 16 | port: 17 | number: 80 18 | 19 | 20 | -------------------------------------------------------------------------------- /04-AGIC-Ingress-URL-Routing/01-kube-manifests-defaultBackend/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: ghcr.io/stacksimplify/kube-nginxapp1:1.0.0 20 | ports: 21 | - containerPort: 80 22 | 23 | -------------------------------------------------------------------------------- /04-AGIC-Ingress-URL-Routing/01-kube-manifests-defaultBackend/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 | -------------------------------------------------------------------------------- /04-AGIC-Ingress-URL-Routing/01-kube-manifests-defaultBackend/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: ghcr.io/stacksimplify/kube-nginxapp2:1.0.0 20 | ports: 21 | - containerPort: 80 22 | -------------------------------------------------------------------------------- /04-AGIC-Ingress-URL-Routing/01-kube-manifests-defaultBackend/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 | -------------------------------------------------------------------------------- /04-AGIC-Ingress-URL-Routing/01-kube-manifests-defaultBackend/03-MyApp-Manifests/01-myapp-Deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: myapp-nginx-deployment 5 | labels: 6 | app: myapp-nginx 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: myapp-nginx 12 | template: 13 | metadata: 14 | labels: 15 | app: myapp-nginx 16 | spec: 17 | containers: 18 | - name: myapp-nginx 19 | image: ghcr.io/stacksimplify/kubenginx:1.0.0 20 | ports: 21 | - containerPort: 80 22 | 23 | -------------------------------------------------------------------------------- /04-AGIC-Ingress-URL-Routing/01-kube-manifests-defaultBackend/03-MyApp-Manifests/02-myapp-ClusterIP-Service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: myapp-nginx-clusterip-service 5 | labels: 6 | app: myapp-nginx 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | app: myapp-nginx 11 | ports: 12 | - port: 80 13 | targetPort: 80 14 | -------------------------------------------------------------------------------- /04-AGIC-Ingress-URL-Routing/01-kube-manifests-defaultBackend/04-IngressService-Manifests/01-Ingress-URL-Routing.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: ingress-url-routing 5 | spec: 6 | ingressClassName: azure-application-gateway 7 | defaultBackend: 8 | service: 9 | name: myapp-nginx-clusterip-service 10 | port: 11 | number: 80 12 | rules: 13 | - http: 14 | paths: 15 | - path: /app1 16 | pathType: Prefix 17 | backend: 18 | service: 19 | name: app1-nginx-clusterip-service 20 | port: 21 | number: 80 22 | - path: /app2 23 | pathType: Prefix 24 | backend: 25 | service: 26 | name: app2-nginx-clusterip-service 27 | port: 28 | number: 80 29 | # - path: / 30 | # pathType: Prefix 31 | # backend: 32 | # service: 33 | # name: myapp-nginx-clusterip-service 34 | # port: 35 | # number: 80 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /04-AGIC-Ingress-URL-Routing/02-kube-manifests-root-httppath/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: ghcr.io/stacksimplify/kube-nginxapp1:1.0.0 20 | ports: 21 | - containerPort: 80 22 | 23 | -------------------------------------------------------------------------------- /04-AGIC-Ingress-URL-Routing/02-kube-manifests-root-httppath/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 | -------------------------------------------------------------------------------- /04-AGIC-Ingress-URL-Routing/02-kube-manifests-root-httppath/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: ghcr.io/stacksimplify/kube-nginxapp2:1.0.0 20 | ports: 21 | - containerPort: 80 22 | -------------------------------------------------------------------------------- /04-AGIC-Ingress-URL-Routing/02-kube-manifests-root-httppath/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 | -------------------------------------------------------------------------------- /04-AGIC-Ingress-URL-Routing/02-kube-manifests-root-httppath/03-MyApp-Manifests/01-myapp-Deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: myapp-nginx-deployment 5 | labels: 6 | app: myapp-nginx 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: myapp-nginx 12 | template: 13 | metadata: 14 | labels: 15 | app: myapp-nginx 16 | spec: 17 | containers: 18 | - name: myapp-nginx 19 | image: ghcr.io/stacksimplify/kubenginx:1.0.0 20 | ports: 21 | - containerPort: 80 22 | 23 | -------------------------------------------------------------------------------- /04-AGIC-Ingress-URL-Routing/02-kube-manifests-root-httppath/03-MyApp-Manifests/02-myapp-ClusterIP-Service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: myapp-nginx-clusterip-service 5 | labels: 6 | app: myapp-nginx 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | app: myapp-nginx 11 | ports: 12 | - port: 80 13 | targetPort: 80 14 | -------------------------------------------------------------------------------- /04-AGIC-Ingress-URL-Routing/02-kube-manifests-root-httppath/04-IngressService-Manifests/01-Ingress-URL-Routing.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: ingress-url-routing 5 | spec: 6 | ingressClassName: azure-application-gateway 7 | rules: 8 | - http: 9 | paths: 10 | - path: /app1 11 | pathType: Prefix 12 | backend: 13 | service: 14 | name: app1-nginx-clusterip-service 15 | port: 16 | number: 80 17 | - path: /app2 18 | pathType: Prefix 19 | backend: 20 | service: 21 | name: app2-nginx-clusterip-service 22 | port: 23 | number: 80 24 | - path: / 25 | pathType: Prefix 26 | backend: 27 | service: 28 | name: myapp-nginx-clusterip-service 29 | port: 30 | number: 80 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /04-AGIC-Ingress-URL-Routing/README.md: -------------------------------------------------------------------------------- 1 | # Azure Ingress - URL Routing 2 | 3 | ## Step-01: Introduction 4 | - We are going to understand and implement about `Ingress Path based/URL Routing` 5 | 6 | ## Step-02: Review k8s Application Manifests 7 | - **App1 Application Folder:** 01-NginxApp1-Manifests 8 | - 01-NginxApp1-Deployment.yml 9 | - 02-NginxApp1-ClusterIP-Service.yaml 10 | - **App2 Application Folder:** 01-NginxApp2-Manifests 11 | - 01-NginxApp2-Deployment.yml 12 | - 02-NginxApp2-ClusterIP-Service.yaml 13 | - **Myapp Application Folder (Default Backend):** 03-MyApp-Manifests 14 | - 01-myapp-Deployment.yaml 15 | - 02-myapp-ClusterIP-Service.yaml 16 | 17 | ## Step-03: Review Ingress Service Manifests 18 | - [Ingress API Reference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/) 19 | - Discuss in detail about [Ingress Paths](https://kubernetes.io/docs/concepts/services-networking/ingress/#examples) 20 | - **Ingress Manifest:** 01-Ingress-URL-Routing.yml 21 | ```yaml 22 | apiVersion: networking.k8s.io/v1 23 | kind: Ingress 24 | metadata: 25 | name: ingress-url-routing 26 | spec: 27 | ingressClassName: azure-application-gateway 28 | defaultBackend: 29 | service: 30 | name: myapp-nginx-clusterip-service 31 | port: 32 | number: 80 33 | rules: 34 | - http: 35 | paths: 36 | - path: /app1 37 | pathType: Prefix 38 | backend: 39 | service: 40 | name: app1-nginx-clusterip-service 41 | port: 42 | number: 80 43 | - path: /app2 44 | pathType: Prefix 45 | backend: 46 | service: 47 | name: app2-nginx-clusterip-service 48 | port: 49 | number: 80 50 | # - path: / 51 | # pathType: Prefix 52 | # backend: 53 | # service: 54 | # name: myapp-nginx-clusterip-service 55 | # port: 56 | # number: 80 57 | ``` 58 | 59 | ## Step-04: Deploy and Verify 60 | ```t 61 | # Deploy Apps 62 | kubectl apply -R -f 01-kube-manifests-defaultBackend/ 63 | 64 | # List Deployments 65 | kubectl get deploy 66 | 67 | # List Pods 68 | kubectl get pods 69 | 70 | # List Services 71 | kubectl get svc 72 | 73 | # List Ingress 74 | kubectl get ingress 75 | ``` 76 | 77 | ## Step-05: Access Applications 78 | ```t 79 | # Access App1 (/app1) Application 80 | curl http:///app1/index.html 81 | http:///app1/index.html 82 | 83 | # Access App2 (/app2) Application 84 | curl http:///app2/index.html 85 | http:///app2/index.html 86 | 87 | # Access MyApp (Root Context /) Application 88 | curl http:// 89 | http:// 90 | ``` 91 | 92 | ## Step-06: Verify Application Gateway Ingress Pod Logs 93 | ```t 94 | # Verify ingress-appgw pod Logs 95 | kubectl -n kube-system logs -f $(kubectl -n kube-system get po | egrep -o 'ingress-appgw-deployment[A-Za-z0-9-]+') 96 | ``` 97 | 98 | ## Step-07: Verify Azure AKS Cluster using Azure Portal 99 | - **Workloads:** Review workloads 100 | - **Services and Ingresses Tab:** Review services 101 | 102 | ## Step-08: Verify Application Gateway using Azure Portal 103 | - Please review and observe all default settings in detail 104 | - **Backend Pools Tab:** Review Backend Pools 105 | - **Backend Settings Tab:** 106 | - Review `Backend Port` 107 | - Review the probe `custom probe` 108 | ```t 109 | # Make a note of these settings 110 | 1. In AppGW -> Backend Settings for Root Context defaultBackend (bp-default-myapp-nginx-clusterip-service-80-80-ingress-url-routing) will use "defaultprobe-Http" instead of dedicated HTTP Probe 111 | ``` 112 | - **Rules Tab:** 113 | - We should see default basic rule configured 114 | - Open default rule and review `Backend Targets` tab 115 | - **Health probes Tab:** 116 | - We should see `custom HTTP probe` created for App1 and App2 and they use their own probe 117 | - For `defaultBackend`, we will see `defaultprobe-HTTP` is used 118 | 119 | ## Step-09: Clean-Up Applications 120 | ```t 121 | # Delete Apps 122 | kubectl delete -R -f 01-kube-manifests-defaultBackend/ 123 | 124 | # Review Application Gateway Tabs 125 | 1. Backend Pools Tab 126 | 2. Backend Settings Tab 127 | 3. Rules Tab 128 | ``` 129 | 130 | ## Step-10: Update Ingress Root Context to use "path: /" instead of defaultBackend 131 | - **Kube Manifests Folder:** 02-kube-manifests-root-httppath 132 | ```yaml 133 | apiVersion: networking.k8s.io/v1 134 | kind: Ingress 135 | metadata: 136 | name: ingress-url-routing 137 | spec: 138 | ingressClassName: azure-application-gateway 139 | rules: 140 | - http: 141 | paths: 142 | - path: /app1 143 | pathType: Prefix 144 | backend: 145 | service: 146 | name: app1-nginx-clusterip-service 147 | port: 148 | number: 80 149 | - path: /app2 150 | pathType: Prefix 151 | backend: 152 | service: 153 | name: app2-nginx-clusterip-service 154 | port: 155 | number: 80 156 | - path: / 157 | pathType: Prefix 158 | backend: 159 | service: 160 | name: myapp-nginx-clusterip-service 161 | port: 162 | number: 80 163 | ``` 164 | ## Step-11: Deploy and Verify 165 | ```t 166 | # Deploy and Verify 167 | kubectl apply -f 02-kube-manifests-root-httppath/ 168 | 169 | # Review Key Difference 170 | 1. In AppGW -> Backend Settings we will see that for Root Context related setting (bp-default-myapp-nginx-clusterip-service-80-80-ingress-url-routing), dedicated HTTP probe other than "defaultprobe-Http" 171 | 172 | # Access App1 (/app1) Application 173 | curl http:///app1/index.html 174 | http:///app1/index.html 175 | 176 | # Access App2 (/app2) Application 177 | curl http:///app2/index.html 178 | http:///app2/index.html 179 | 180 | # Access MyApp (Root Context /) Application 181 | curl http:// 182 | http:// 183 | ``` 184 | 185 | ## Step-12: Clean-Up Applications 186 | ```t 187 | # Delete Apps 188 | kubectl delete -f 02-kube-manifests-root-httppath/ 189 | 190 | # Review Application Gateway Tabs 191 | 1. Backend Pools Tab 192 | 2. Backend Settings Tab 193 | 3. Rules Tab 194 | ``` -------------------------------------------------------------------------------- /05-AGIC-Backend-PathPrefix/README.md: -------------------------------------------------------------------------------- 1 | # Azure Gateway Ingress - Backend Annotations Path Prefix 2 | 3 | ## Step-01: Introduction 4 | - We are going to understand and implement a Backend Annotation listed below 5 | ```yaml 6 | # Azure Ingress Backend Annotation 7 | annotations: 8 | kubernetes.io/ingress.class: azure/application-gateway 9 | appgw.ingress.kubernetes.io/backend-path-prefix: "/app1/" 10 | ``` 11 | 12 | ## Step-02: Review k8s Application Manifests 13 | - **kube-manifests:** 14 | - 01-NginxApp1-Deployment.yml 15 | - 02-NginxApp1-ClusterIP-Service.yaml 16 | - 03-Ingress-backend-path-prefix.yml 17 | 18 | ## Step-03: Review Ingress Service Manifests 19 | - [Ingress API Reference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/) 20 | - [AGIC Backend Hostname Annotation](https://azure.github.io/application-gateway-kubernetes-ingress/annotations/#backend-path-prefix) 21 | - **Ingress Manifest:** 03-Ingress-backend-path-prefix.yml 22 | 23 | ```yaml 24 | apiVersion: networking.k8s.io/v1 25 | kind: Ingress 26 | metadata: 27 | name: nginxapp1-ingress-service 28 | annotations: 29 | appgw.ingress.kubernetes.io/backend-path-prefix: "/app1/" 30 | spec: 31 | ingressClassName: azure-application-gateway 32 | rules: 33 | - http: 34 | paths: 35 | - path: /myapps/app1 36 | pathType: Prefix 37 | backend: 38 | service: 39 | name: app1-nginx-clusterip-service 40 | port: 41 | number: 80 42 | ``` 43 | 44 | ## Step-04: Deploy and Verify 45 | ```t 46 | # Deploy Apps 47 | kubectl apply -f kube-manifests/ 48 | 49 | # List Deployments 50 | kubectl get deploy 51 | 52 | # List Pods 53 | kubectl get pods 54 | 55 | # List Services 56 | kubectl get svc 57 | 58 | # List Ingress 59 | kubectl get ingress 60 | ``` 61 | 62 | ## Step-05: Access Applications 63 | ```t 64 | # Access Application (curl) 65 | curl http:///myapps/app1/index.html 66 | 67 | # Access Application (Browser) 68 | http:///myapps/app1/index.html 69 | ``` 70 | 71 | ## Step-06: Verify Application Gateway Ingress Pod Logs 72 | ```t 73 | # Verify ingress-appgw pod Logs 74 | kubectl -n kube-system logs -f $(kubectl -n kube-system get po | egrep -o 'ingress-appgw-deployment[A-Za-z0-9-]+') 75 | ``` 76 | 77 | ## Step-07: Verify Azure AKS Cluster using Azure Portal 78 | - **Workloads:** Review workloads 79 | - **Services and Ingresses Tab:** Review services 80 | 81 | ## Step-08: Verify Application Gateway using Azure Portal 82 | - **Backend Settings Tab:** 83 | - Review `Override backend path` 84 | - **Rules Tab:** Review Rules Tab 85 | 86 | ## Step-09: Clean-Up Applications 87 | ```t 88 | # Delete Apps 89 | kubectl delete -f kube-manifests/ 90 | 91 | # Review Application Gateway Tabs 92 | 1. Backend Pools Tab 93 | 2. Backend Settings Tab 94 | 3. Rules Tab 95 | ``` 96 | -------------------------------------------------------------------------------- /05-AGIC-Backend-PathPrefix/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: ghcr.io/stacksimplify/kube-nginxapp1:1.0.0 20 | ports: 21 | - containerPort: 80 22 | 23 | -------------------------------------------------------------------------------- /05-AGIC-Backend-PathPrefix/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 | -------------------------------------------------------------------------------- /05-AGIC-Backend-PathPrefix/kube-manifests/03-Ingress-backend-path-prefix.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: nginxapp1-ingress-service 5 | annotations: 6 | appgw.ingress.kubernetes.io/backend-path-prefix: "/app1/" 7 | spec: 8 | ingressClassName: azure-application-gateway 9 | rules: 10 | - http: 11 | paths: 12 | - path: /myapps/app1 13 | pathType: Prefix 14 | backend: 15 | service: 16 | name: app1-nginx-clusterip-service 17 | port: 18 | number: 80 19 | 20 | 21 | -------------------------------------------------------------------------------- /06-AGIC-Backend-Hostname/README.md: -------------------------------------------------------------------------------- 1 | # Azure Gateway Ingress - Backend Annotations Hostname 2 | 3 | ## Step-01: Introduction 4 | - We are going to understand and implement a Backend Annotation listed below 5 | ```yaml 6 | # Azure Ingress Backend Annotation 7 | annotations: 8 | appgw.ingress.kubernetes.io/backend-hostname: "internal.stacksimplify.com" 9 | ``` 10 | 11 | ## Step-02: Review k8s Application Manifests 12 | - **kube-manifests:** 13 | - 01-EchoServer-Deployment.yaml 14 | - 02-EchoServer-ClusterIP-Service.yaml 15 | - 03-Ingress-backend-hostname.yaml 16 | 17 | ## Step-03: Review Ingress Service Manifests 18 | - [Ingress API Reference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/) 19 | - [AGIC Backend Hostname Annotation](https://azure.github.io/application-gateway-kubernetes-ingress/annotations/#backend-hostname) 20 | - **Ingress Manifest:** 03-Ingress-backend-hostname.yaml 21 | ```yaml 22 | apiVersion: networking.k8s.io/v1 23 | kind: Ingress 24 | metadata: 25 | name: echoserver-ingress-service 26 | annotations: 27 | #appgw.ingress.kubernetes.io/backend-hostname: "internal.example.com" 28 | spec: 29 | ingressClassName: azure-application-gateway 30 | rules: 31 | - http: 32 | paths: 33 | - path: / 34 | pathType: Prefix 35 | backend: 36 | service: 37 | name: echoserver-clusterip-service 38 | port: 39 | number: 80 40 | ``` 41 | 42 | ## Step-04: Deploy and Verify 43 | ```t 44 | # Deploy without Backend Hostname Annotation 45 | 1. First we will deploy without backend hostname annotation, review the output 46 | 2. Then we will enable the backend hostname annotation and review the output 47 | 48 | # Deploy Apps 49 | kubectl apply -f kube-manifests/ 50 | 51 | # List Deployments 52 | kubectl get deploy 53 | 54 | # List Pods 55 | kubectl get pods 56 | 57 | # List Services 58 | kubectl get svc 59 | 60 | # List Ingress 61 | kubectl get ingress 62 | 63 | # Access Application (curl) 64 | curl http:/// 65 | 66 | # Access Application (Browser) 67 | http:/// 68 | ``` 69 | 70 | ## Step-05: Verify Application Gateway using Azure Portal 71 | - **Backend Settings Tab:** 72 | - Review `Override with new host name` 73 | 74 | ## Step-06: Uncomment Backend Hostname Annotation, Deploy and Verify 75 | ```t 76 | # In Ingress manifest uncomment 77 | annotations: 78 | appgw.ingress.kubernetes.io/backend-hostname: "internal.stacksimplify.com" 79 | 80 | # Deploy Apps 81 | kubectl apply -f kube-manifests/ 82 | 83 | # List Ingress 84 | kubectl get ingress 85 | 86 | # Access Application (curl) 87 | curl http:/// 88 | 89 | # Access Application (Browser) 90 | http:/// 91 | ``` 92 | 93 | ## Step-07: Verify Application Gateway using Azure Portal 94 | - **Backend Settings Tab:** 95 | - Review `Override with new host name` 96 | 97 | ## Step-08: Clean-Up Applications 98 | ```t 99 | # Delete Apps 100 | kubectl delete -f kube-manifests/ 101 | 102 | # Review Application Gateway Tabs 103 | 1. Backend Pools Tab 104 | 2. Backend Settings Tab 105 | 3. Rules Tab 106 | ``` 107 | -------------------------------------------------------------------------------- /06-AGIC-Backend-Hostname/kube-manifests/01-EchoServer-Deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: echoserver-deployment 5 | labels: 6 | app: echoserver 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: echoserver 12 | template: 13 | metadata: 14 | labels: 15 | app: echoserver 16 | spec: 17 | containers: 18 | - name: echoserver 19 | image: k8s.gcr.io/e2e-test-images/echoserver:2.5 20 | ports: 21 | - containerPort: 8080 22 | 23 | -------------------------------------------------------------------------------- /06-AGIC-Backend-Hostname/kube-manifests/02-EchoServer-ClusterIP-Service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: echoserver-clusterip-service 5 | labels: 6 | app: echoserver 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | app: echoserver 11 | ports: 12 | - port: 80 13 | targetPort: 8080 14 | -------------------------------------------------------------------------------- /06-AGIC-Backend-Hostname/kube-manifests/03-Ingress-backend-hostname.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: echoserver-ingress-service 5 | annotations: 6 | #appgw.ingress.kubernetes.io/backend-hostname: "internal.stacksimplify.com" 7 | spec: 8 | ingressClassName: azure-application-gateway 9 | rules: 10 | - http: 11 | paths: 12 | - path: / 13 | pathType: Prefix 14 | backend: 15 | service: 16 | name: echoserver-clusterip-service 17 | port: 18 | number: 80 19 | 20 | 21 | -------------------------------------------------------------------------------- /07-AGIC-Cookie-based-Affinity/01-kube-manifests-cookie-affinity/01-EchoServer-Deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: echoserver-deployment 5 | labels: 6 | app: echoserver 7 | spec: 8 | replicas: 3 9 | selector: 10 | matchLabels: 11 | app: echoserver 12 | template: 13 | metadata: 14 | labels: 15 | app: echoserver 16 | spec: 17 | containers: 18 | - name: echoserver 19 | image: k8s.gcr.io/e2e-test-images/echoserver:2.5 20 | ports: 21 | - containerPort: 8080 22 | 23 | -------------------------------------------------------------------------------- /07-AGIC-Cookie-based-Affinity/01-kube-manifests-cookie-affinity/02-EchoServer-ClusterIP-Service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: echoserver-clusterip-service 5 | labels: 6 | app: echoserver 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | app: echoserver 11 | ports: 12 | - port: 80 13 | targetPort: 8080 14 | -------------------------------------------------------------------------------- /07-AGIC-Cookie-based-Affinity/01-kube-manifests-cookie-affinity/03-Ingress-cookie-affinity.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: echoserver-ingress-service 5 | annotations: 6 | appgw.ingress.kubernetes.io/cookie-based-affinity: "true" 7 | spec: 8 | ingressClassName: azure-application-gateway 9 | rules: 10 | - http: 11 | paths: 12 | - path: / 13 | pathType: Prefix 14 | backend: 15 | service: 16 | name: echoserver-clusterip-service 17 | port: 18 | number: 80 19 | 20 | 21 | -------------------------------------------------------------------------------- /07-AGIC-Cookie-based-Affinity/02-kube-manifests-distinct-cookie/01-EchoServer-Deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: echoserver-deployment 5 | labels: 6 | app: echoserver 7 | spec: 8 | replicas: 3 9 | selector: 10 | matchLabels: 11 | app: echoserver 12 | template: 13 | metadata: 14 | labels: 15 | app: echoserver 16 | spec: 17 | containers: 18 | - name: echoserver 19 | image: k8s.gcr.io/e2e-test-images/echoserver:2.5 20 | ports: 21 | - containerPort: 8080 22 | 23 | -------------------------------------------------------------------------------- /07-AGIC-Cookie-based-Affinity/02-kube-manifests-distinct-cookie/02-EchoServer-ClusterIP-Service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: echoserver-clusterip-service 5 | labels: 6 | app: echoserver 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | app: echoserver 11 | ports: 12 | - port: 80 13 | targetPort: 8080 14 | -------------------------------------------------------------------------------- /07-AGIC-Cookie-based-Affinity/02-kube-manifests-distinct-cookie/03-Ingress-cookie-affinity-distinct.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: echoserver-ingress-service 5 | annotations: 6 | appgw.ingress.kubernetes.io/cookie-based-affinity: "true" 7 | appgw.ingress.kubernetes.io/cookie-based-affinity-distinct-name: "true" 8 | spec: 9 | ingressClassName: azure-application-gateway 10 | rules: 11 | - http: 12 | paths: 13 | - path: / 14 | pathType: Prefix 15 | backend: 16 | service: 17 | name: echoserver-clusterip-service 18 | port: 19 | number: 80 20 | 21 | 22 | -------------------------------------------------------------------------------- /07-AGIC-Cookie-based-Affinity/README.md: -------------------------------------------------------------------------------- 1 | # Azure Gateway Ingress - Cookie Based Affinity Annotation 2 | 3 | ## Step-01: Introduction 4 | - We are going to understand and implement a Cookie based Affinity Annotations listed below 5 | ```yaml 6 | # Azure Ingress Cookie based Affinity Annotations 7 | annotations: 8 | appgw.ingress.kubernetes.io/cookie-based-affinity: "true" 9 | appgw.ingress.kubernetes.io/cookie-based-affinity-distinct-name: "true" 10 | ``` 11 | 12 | ## Step-02: Review k8s Application Manifests 13 | - **kube-manifests Folder:** 01-kube-manifests-cookie-affinity 14 | - 01-EchoServer-Deployment.yaml 15 | - 02-EchoServer-ClusterIP-Service.yaml 16 | - 03-Ingress-cookie-affinity.yaml 17 | 18 | ## Step-03: Review Ingress Service Manifests 19 | - [Ingress API Reference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/) 20 | - [Cookie Based Affinity Annotation](https://azure.github.io/application-gateway-kubernetes-ingress/annotations/#cookie-based-affinity) 21 | - **Ingress Manifest:** 03-Ingress-cookie-affinity.yaml 22 | ```yaml 23 | apiVersion: networking.k8s.io/v1 24 | kind: Ingress 25 | metadata: 26 | name: echoserver-ingress-service 27 | annotations: 28 | appgw.ingress.kubernetes.io/cookie-based-affinity: "true" 29 | spec: 30 | ingressClassName: azure-application-gateway 31 | rules: 32 | - http: 33 | paths: 34 | - path: / 35 | pathType: Prefix 36 | backend: 37 | service: 38 | name: echoserver-clusterip-service 39 | port: 40 | number: 80 41 | ``` 42 | 43 | ## Step-04: Deploy and Verify 44 | ```t 45 | # Deploy Apps 46 | kubectl apply -f 01-kube-manifests-cookie-affinity 47 | 48 | # List Deployments 49 | kubectl get deploy 50 | 51 | # List Pods 52 | kubectl get pods 53 | 54 | # List Services 55 | kubectl get svc 56 | 57 | # List Ingress 58 | kubectl get ingress 59 | 60 | # Access Application (curl) 61 | curl http:/// 62 | Observation: 63 | 1. With curl requests distribute to different k8s pods 64 | 65 | # Access Application (Browser) 66 | http:/// 67 | Observation 68 | 1. With cookie affinity enabled, a AppGW cookie is set on browser and you will see that request always sent to same k8s pod. 69 | 2. Review the cookie on browser using Google Chrome Developer Tools 70 | MacOS Shortcut: Press CMD + OPTION + I 71 | Windows Shortcut: Press F12 or Ctrl + Shift + I. 72 | 3. Cookie name looks as "ApplicationGatewayAffinity" 73 | ``` 74 | 75 | ## Step-05: Verify Application Gateway using Azure Portal 76 | - **Backend Settings Tab:** 77 | - Review `Cookie Affinity`, it should be enabled 78 | 79 | ## Step-06: Delete 01-kube-manifests-cookie-affinity 80 | ```t 81 | # Uninstall k8s Resources 82 | kubectl delete -f 01-kube-manifests-cookie-affinity/ 83 | ``` 84 | 85 | ## Step-07: Review k8s Application Manifests 86 | - **kube-manifests Folder:** 02-kube-manifests-distinct-cookie 87 | - 01-EchoServer-Deployment.yaml 88 | - 02-EchoServer-ClusterIP-Service.yaml 89 | - 03-Ingress-cookie-affinity-distinct.yaml 90 | 91 | ## Step-08: Review Ingress Service Manifests 92 | - [Ingress API Reference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/) 93 | - [Distinct Cookie Annotation](https://azure.github.io/application-gateway-kubernetes-ingress/annotations/#distinct-cookie-name) 94 | - **Ingress Manifest:** 03-Ingress-cookie-affinity.yaml 95 | ```yaml 96 | apiVersion: networking.k8s.io/v1 97 | kind: Ingress 98 | metadata: 99 | name: echoserver-ingress-service 100 | annotations: 101 | appgw.ingress.kubernetes.io/cookie-based-affinity: "true" 102 | appgw.ingress.kubernetes.io/cookie-based-affinity-distinct-name: "true" 103 | spec: 104 | ingressClassName: azure-application-gateway 105 | rules: 106 | - http: 107 | paths: 108 | - path: / 109 | pathType: Prefix 110 | backend: 111 | service: 112 | name: echoserver-clusterip-service 113 | port: 114 | number: 80 115 | ``` 116 | 117 | ## Step-09: Deploy and Verify 118 | ```t 119 | # Deploy Apps 120 | kubectl apply -f 02-kube-manifests-distinct-cookie 121 | 122 | # List Deployments 123 | kubectl get deploy 124 | 125 | # List Pods 126 | kubectl get pods 127 | 128 | # List Services 129 | kubectl get svc 130 | 131 | # List Ingress 132 | kubectl get ingress 133 | 134 | # Access Application (curl) 135 | curl http:/// 136 | Observation: 137 | 1. With curl requests distribute to different k8s pods 138 | 139 | # Access Application (Browser) 140 | http:/// 141 | Observation 142 | 1. With distinct cookie affinity enabled, a AppGW cookie per backend is set on browser and you will see that request always sent to same k8s pod. 143 | 2. Review the cookie on browser using Google Chrome Developer Tools -> Network Tab 144 | MacOS Shortcut: Press CMD + OPTION + I 145 | Windows Shortcut: Press F12 or Ctrl + Shift + I. 146 | 3. Cookie name looks as below 147 | appgw-affinity- 148 | appgw-affinity-6b33b5c2a07e13ed106bb9a11903dffc 149 | ``` 150 | 151 | ## Step-10: Verify Application Gateway using Azure Portal 152 | - **Backend Settings Tab:** 153 | - Review `Cookie Affinity`, it should be enabled 154 | - `Affinity Cookie name` also contains value something like `appgw-affinity-6b33b5c2a07e13ed106bb9a11903dffc`. This should match the cookie name we have seen via Google Developer Tools Network Tab 155 | 156 | ## Step-11: Clean-Up Applications 157 | ```t 158 | # Delete Apps 159 | kubectl delete -f 02-kube-manifests-distinct-cookie/ 160 | 161 | # Review Application Gateway Tabs 162 | 1. Backend Pools Tab 163 | 2. Backend Settings Tab 164 | 3. Rules Tab 165 | ``` 166 | 167 | -------------------------------------------------------------------------------- /08-AGIC-Override-Frontend-Port/README.md: -------------------------------------------------------------------------------- 1 | # Azure Gateway Ingress - Override Frontend Port 2 | 3 | ## Step-01: Introduction 4 | - We are going to understand and implement how to Override frontend port using Ingress Service 5 | ```yaml 6 | # Azure Ingress Override Frontend Port 7 | annotations: 8 | appgw.ingress.kubernetes.io/override-frontend-port: "8080" 9 | ``` 10 | 11 | ## Step-02: Review k8s Application Manifests 12 | - **kube-manifests:** 13 | - 01-myapp-Deployment.yaml 14 | - 02-myapp-ClusterIP-Service.yaml 15 | - 03-Ingress-override-frontend.yaml 16 | 17 | ## Step-03: Review Ingress Service Manifests 18 | - [Ingress API Reference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/) 19 | - [AGIC Override Frontend Port Annotation](https://azure.github.io/application-gateway-kubernetes-ingress/annotations/#override-frontend-port) 20 | - **Ingress Manifest:** 03-Ingress-override-frontend.yaml 21 | ```yaml 22 | apiVersion: networking.k8s.io/v1 23 | kind: Ingress 24 | metadata: 25 | name: myapp-ingress-service 26 | annotations: 27 | appgw.ingress.kubernetes.io/override-frontend-port: "8080" 28 | spec: 29 | ingressClassName: azure-application-gateway 30 | rules: 31 | - http: 32 | paths: 33 | - path: / 34 | pathType: Prefix 35 | backend: 36 | service: 37 | name: myapp-nginx-clusterip-service 38 | port: 39 | number: 80 40 | ``` 41 | 42 | ## Step-03: Deploy and Verify 43 | ```t 44 | # Deploy Apps 45 | kubectl apply -f kube-manifests/ 46 | 47 | # List Deployments 48 | kubectl get deploy 49 | 50 | # List Pods 51 | kubectl get pods 52 | 53 | # List Services 54 | kubectl get svc 55 | 56 | # List Ingress 57 | kubectl get ingress 58 | 59 | # Access Application (curl) 60 | curl http://:8080/ 61 | 62 | # Access Application (Browser) 63 | http://:8080/ 64 | ``` 65 | 66 | ## Step-04: Verify Application Gateway using Azure Portal 67 | - **Listeners Tab:** Review Rules Tab 68 | - You should find the port as `8080` 69 | 70 | ## Step-05: Clean-Up Applications 71 | ```t 72 | # Delete Apps 73 | kubectl delete -f kube-manifests/ 74 | 75 | # Review Application Gateway Tabs 76 | 1. Backend Pools Tab 77 | 2. Backend Settings Tab 78 | 3. Rules Tab 79 | ``` 80 | -------------------------------------------------------------------------------- /08-AGIC-Override-Frontend-Port/kube-manifests/01-myapp-Deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: myapp-nginx-deployment 5 | labels: 6 | app: myapp-nginx 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: myapp-nginx 12 | template: 13 | metadata: 14 | labels: 15 | app: myapp-nginx 16 | spec: 17 | containers: 18 | - name: myapp-nginx 19 | image: ghcr.io/stacksimplify/kubenginx:1.0.0 20 | ports: 21 | - containerPort: 80 22 | 23 | -------------------------------------------------------------------------------- /08-AGIC-Override-Frontend-Port/kube-manifests/02-myapp-ClusterIP-Service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: myapp-nginx-clusterip-service 5 | labels: 6 | app: myapp-nginx 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | app: myapp-nginx 11 | ports: 12 | - port: 80 13 | targetPort: 80 14 | -------------------------------------------------------------------------------- /08-AGIC-Override-Frontend-Port/kube-manifests/03-Ingress-override-frontend.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: myapp-ingress-service 5 | annotations: 6 | appgw.ingress.kubernetes.io/override-frontend-port: "8080" 7 | spec: 8 | ingressClassName: azure-application-gateway 9 | rules: 10 | - http: 11 | paths: 12 | - path: / 13 | pathType: Prefix 14 | backend: 15 | service: 16 | name: myapp-nginx-clusterip-service 17 | port: 18 | number: 80 19 | 20 | -------------------------------------------------------------------------------- /09-AGIC-Rewrite-Rule-Set/README.md: -------------------------------------------------------------------------------- 1 | # Azure Gateway Ingress - Rewrite Rule Set Annotation 2 | 3 | ## Step-01: Introduction 4 | - We are going to understand and implement Rewrite Rule Set Annotation 5 | ```yaml 6 | # Azure Ingress Rewrite Rule Set Annotation 7 | annotations: 8 | appgw.ingress.kubernetes.io/rewrite-rule-set: my-headers-rewrite-ruleset 9 | spec: 10 | ``` 11 | 12 | ## Step-02: Review k8s Application Manifests 13 | - **kube-manifests:** 14 | - 01-EchoServer-Deployment.yaml 15 | - 02-EchoServer-ClusterIP-Service.yaml 16 | - 03-Ingress-rewrite-rule-set.yaml 17 | 18 | ## Step-03: Review Ingress Service Manifests 19 | - [Ingress API Reference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/) 20 | - [AGIC Rewrite Rule Set Annotation](https://azure.github.io/application-gateway-kubernetes-ingress/annotations/#rewrite-rule-set) 21 | - **Ingress Manifest:** 03-Ingress-rewrite-rule-set.yaml 22 | ```yaml 23 | apiVersion: networking.k8s.io/v1 24 | kind: Ingress 25 | metadata: 26 | name: echoserver-ingress-service 27 | annotations: 28 | appgw.ingress.kubernetes.io/rewrite-rule-set: my-headers-rewrite-ruleset 29 | spec: 30 | ingressClassName: azure-application-gateway 31 | rules: 32 | - http: 33 | paths: 34 | - path: / 35 | pathType: Prefix 36 | backend: 37 | service: 38 | name: echoserver-clusterip-service 39 | port: 40 | number: 80 41 | ``` 42 | 43 | ## Step-04: Create Rewrite Rule Set in Application Gateway 44 | - Go to AppGw -> agic-appgw -> Settings -> Rewrites 45 | ### Name and Association Tab 46 | - **Name:** my-headers-rewrite-ruleset 47 | - **Routing Rules | Paths:** Select the Rule 48 | - Click **Next** 49 | ### Rewrite Rule Configuration 50 | - Click on **Add rewrite rule** 51 | - **Rewrite rule name:** custom-mydomain-header 52 | - Click on **Click to configure this action** 53 | - **Rewrite Type:** Request Header 54 | - **Action Type:** Set 55 | - **Header name:** Select `Custom Header` 56 | - **Custom header:** mydomain 57 | - **Header value:** stacksimplify.com 58 | - Click **ok** 59 | - Click on **Create** 60 | 61 | 62 | ## Step-05: Deploy and Verify 63 | ```t 64 | # Deploy Apps 65 | kubectl apply -f kube-manifests/ 66 | 67 | # List Deployments 68 | kubectl get deploy 69 | 70 | # List Pods 71 | kubectl get pods 72 | 73 | # List Services 74 | kubectl get svc 75 | 76 | # List Ingress 77 | kubectl get ingress 78 | 79 | # Access Application (curl) 80 | curl http:/// 81 | 82 | # Access Application (Browser) 83 | http:/// 84 | Observation: 85 | 1. You should see that rewrite rule executed and header `mydomain=stacksimplify.com` sent to backend application server 86 | ``` 87 | 88 | ## Step-06: Clean-Up Applications 89 | ```t 90 | # Delete Apps 91 | kubectl delete -f kube-manifests/ 92 | 93 | # Review Application Gateway Tabs 94 | 1. Backend Pools Tab 95 | 2. Backend Settings Tab 96 | 3. Rules Tab 97 | ``` 98 | -------------------------------------------------------------------------------- /09-AGIC-Rewrite-Rule-Set/kube-manifests/01-EchoServer-Deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: echoserver-deployment 5 | labels: 6 | app: echoserver 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: echoserver 12 | template: 13 | metadata: 14 | labels: 15 | app: echoserver 16 | spec: 17 | containers: 18 | - name: echoserver 19 | image: k8s.gcr.io/e2e-test-images/echoserver:2.5 20 | ports: 21 | - containerPort: 8080 22 | 23 | -------------------------------------------------------------------------------- /09-AGIC-Rewrite-Rule-Set/kube-manifests/02-EchoServer-ClusterIP-Service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: echoserver-clusterip-service 5 | labels: 6 | app: echoserver 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | app: echoserver 11 | ports: 12 | - port: 80 13 | targetPort: 8080 14 | -------------------------------------------------------------------------------- /09-AGIC-Rewrite-Rule-Set/kube-manifests/03-Ingress-rewrite-rule-set.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: echoserver-ingress-service 5 | annotations: 6 | appgw.ingress.kubernetes.io/rewrite-rule-set: my-headers-rewrite-ruleset 7 | spec: 8 | ingressClassName: azure-application-gateway 9 | rules: 10 | - http: 11 | paths: 12 | - path: / 13 | pathType: Prefix 14 | backend: 15 | service: 16 | name: echoserver-clusterip-service 17 | port: 18 | number: 80 19 | 20 | 21 | -------------------------------------------------------------------------------- /10-AGIC-Probes-Default-and-HTTP/01-kube-manifests-default-backend/01-myapp-Deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: myapp-nginx-deployment 5 | labels: 6 | app: myapp-nginx 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: myapp-nginx 12 | template: 13 | metadata: 14 | labels: 15 | app: myapp-nginx 16 | spec: 17 | containers: 18 | - name: myapp-nginx 19 | image: ghcr.io/stacksimplify/kubenginx:1.0.0 20 | ports: 21 | - containerPort: 80 22 | 23 | -------------------------------------------------------------------------------- /10-AGIC-Probes-Default-and-HTTP/01-kube-manifests-default-backend/02-myapp-ClusterIP-Service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: myapp-nginx-clusterip-service 5 | labels: 6 | app: myapp-nginx 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | app: myapp-nginx 11 | ports: 12 | - port: 80 13 | targetPort: 80 14 | -------------------------------------------------------------------------------- /10-AGIC-Probes-Default-and-HTTP/01-kube-manifests-default-backend/03-Ingress-Default-Backend.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: myapp-ingress-service 5 | spec: 6 | ingressClassName: azure-application-gateway 7 | defaultBackend: 8 | service: 9 | name: myapp-nginx-clusterip-service 10 | port: 11 | number: 80 12 | 13 | 14 | -------------------------------------------------------------------------------- /10-AGIC-Probes-Default-and-HTTP/02-kube-manifests-http-path/01-NginxApp1-Deployment.yaml: -------------------------------------------------------------------------------- 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: ghcr.io/stacksimplify/kube-nginxapp1:1.0.0 20 | ports: 21 | - containerPort: 80 22 | 23 | -------------------------------------------------------------------------------- /10-AGIC-Probes-Default-and-HTTP/02-kube-manifests-http-path/02-NginxApp1-ClusterIP-Service.yaml: -------------------------------------------------------------------------------- 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-AGIC-Probes-Default-and-HTTP/02-kube-manifests-http-path/03-Ingress-HTTP-Paths.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: nginxapp1-ingress-service 5 | spec: 6 | ingressClassName: azure-application-gateway 7 | rules: 8 | - http: 9 | paths: 10 | - path: /app1 11 | pathType: Prefix 12 | backend: 13 | service: 14 | name: app1-nginx-clusterip-service 15 | port: 16 | number: 80 17 | 18 | 19 | -------------------------------------------------------------------------------- /10-AGIC-Probes-Default-and-HTTP/README.md: -------------------------------------------------------------------------------- 1 | # Azure Gateway Ingress - Health Probes 2 | 3 | ## Step-01: Introduction 4 | - We are going to understand and implement Health Probes 5 | - We are going to learn that 6 | - **Usecase-1:** when we use `defaultBackend` in Ingress Service how is the Health probe created 7 | ```yaml 8 | apiVersion: networking.k8s.io/v1 9 | kind: Ingress 10 | metadata: 11 | name: myapp-ingress-service 12 | spec: 13 | ingressClassName: azure-application-gateway 14 | defaultBackend: 15 | service: 16 | name: myapp-nginx-clusterip-service 17 | port: 18 | number: 80 19 | ``` 20 | - **Usecase-2:** When we use `HTTP Paths` in Ingress Service how is the Health probe created 21 | ```yaml 22 | apiVersion: networking.k8s.io/v1 23 | kind: Ingress 24 | metadata: 25 | name: nginxapp1-ingress-service 26 | spec: 27 | ingressClassName: azure-application-gateway 28 | rules: 29 | - http: 30 | paths: 31 | - path: /app1 32 | pathType: Prefix 33 | backend: 34 | service: 35 | name: app1-nginx-clusterip-service 36 | port: 37 | number: 80 38 | ``` 39 | 40 | ## Step-02: Review k8s Application Manifests 41 | ### kube-manifests: 01-kube-manifests-default-backend 42 | - 01-myapp-Deployment.yaml 43 | - 02-myapp-ClusterIP-Service.yaml 44 | - 03-Ingress-Default-Backend.yaml 45 | ### kube-manifests: 02-kube-manifests-http-path 46 | - 01-NginxApp1-Deployment.yaml 47 | - 02-NginxApp1-ClusterIP-Service.yaml 48 | - 03-Ingress-HTTP-Paths.yaml 49 | 50 | ## Step-03: Deploy and Verify 51 | ```t 52 | # Deploy Apps 53 | kubectl apply -f 01-kube-manifests-default-backend/ 54 | kubectl apply -f 02-kube-manifests-http-path/ 55 | 56 | # List Deployments 57 | kubectl get deploy 58 | 59 | # List Pods 60 | kubectl get pods 61 | 62 | # List Services 63 | kubectl get svc 64 | 65 | # List Ingress 66 | kubectl get ingress 67 | 68 | # Access Application (curl) 69 | curl http:// 70 | curl http:///app1/index.html 71 | 72 | # Access Application (Browser) 73 | http:// 74 | http:///app1/index.html 75 | ``` 76 | 77 | ## Step-04: Verify Application Gateway using Azure Portal 78 | - **Backend Settings Tab:** 79 | - Review both applications `backend settings` 80 | - Primarily review `Custom Probe` 81 | - **Default Backend App:** Should use the `defaultprobe-Http probe` 82 | - **HTTP Path App:** This should creata a custom probe with `/app1` as path 83 | - **Health Probes Tab:** 84 | - Review both Health probes 85 | - Perform Health probe **TEST** 86 | ```t 87 | # Verify Pods logs during Probe Test 88 | kubectl get pods 89 | kubectl logs -f 90 | ``` 91 | 92 | ## Step-05: Clean-Up Applications 93 | ```t 94 | # Delete Apps 95 | kubectl delete -f 01-kube-manifests-default-backend/ 96 | kubectl delete -f 02-kube-manifests-http-path/ 97 | 98 | # Review Application Gateway Tabs 99 | 1. Backend Pools Tab 100 | 2. Backend Settings Tab 101 | 3. Rules Tab 102 | ``` 103 | -------------------------------------------------------------------------------- /11-AGIC-Probes-Readniess-Liveness/01-kube-manifests-readiness/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: ghcr.io/stacksimplify/kube-nginxapp1:1.0.0 20 | ports: 21 | - containerPort: 80 22 | readinessProbe: 23 | httpGet: 24 | path: /app1/index.html 25 | port: 80 26 | httpHeaders: 27 | - name: Custom-Header 28 | value: APP1 29 | initialDelaySeconds: 6 30 | periodSeconds: 31 31 | -------------------------------------------------------------------------------- /11-AGIC-Probes-Readniess-Liveness/01-kube-manifests-readiness/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 | -------------------------------------------------------------------------------- /11-AGIC-Probes-Readniess-Liveness/01-kube-manifests-readiness/03-Ingress-Basic.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: nginxapp1-ingress-service 5 | spec: 6 | ingressClassName: azure-application-gateway 7 | rules: 8 | - http: 9 | paths: 10 | - path: / 11 | pathType: Prefix 12 | backend: 13 | service: 14 | name: app1-nginx-clusterip-service 15 | port: 16 | number: 80 17 | 18 | 19 | -------------------------------------------------------------------------------- /11-AGIC-Probes-Readniess-Liveness/02-kube-manifests-liveness/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: ghcr.io/stacksimplify/kube-nginxapp2:1.0.0 20 | ports: 21 | - containerPort: 80 22 | livenessProbe: 23 | httpGet: 24 | path: /app2/index.html 25 | port: 80 26 | httpHeaders: 27 | - name: Custom-Header 28 | value: APP2 29 | initialDelaySeconds: 5 30 | periodSeconds: 30 -------------------------------------------------------------------------------- /11-AGIC-Probes-Readniess-Liveness/02-kube-manifests-liveness/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 | -------------------------------------------------------------------------------- /11-AGIC-Probes-Readniess-Liveness/02-kube-manifests-liveness/03-Ingress-Basic.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: nginxapp2-ingress-service 5 | spec: 6 | ingressClassName: azure-application-gateway 7 | rules: 8 | - http: 9 | paths: 10 | - path: / 11 | pathType: Prefix 12 | backend: 13 | service: 14 | name: app2-nginx-clusterip-service 15 | port: 16 | number: 80 17 | 18 | 19 | -------------------------------------------------------------------------------- /11-AGIC-Probes-Readniess-Liveness/03-kube-manifests-both/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: ghcr.io/stacksimplify/kube-nginxapp1:1.0.0 20 | ports: 21 | - containerPort: 80 22 | readinessProbe: 23 | httpGet: 24 | path: /readiness 25 | port: 80 26 | httpHeaders: 27 | - name: Custom-Header 28 | value: readinessprobe 29 | initialDelaySeconds: 5 30 | periodSeconds: 30 31 | livenessProbe: 32 | httpGet: 33 | path: /liveness 34 | port: 80 35 | httpHeaders: 36 | - name: Custom-Header 37 | value: livenessprobe 38 | initialDelaySeconds: 5 39 | periodSeconds: 30 -------------------------------------------------------------------------------- /11-AGIC-Probes-Readniess-Liveness/03-kube-manifests-both/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 | -------------------------------------------------------------------------------- /11-AGIC-Probes-Readniess-Liveness/03-kube-manifests-both/03-Ingress-Basic.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: nginxapp1-ingress-service 5 | spec: 6 | ingressClassName: azure-application-gateway 7 | rules: 8 | - http: 9 | paths: 10 | - path: / 11 | pathType: Prefix 12 | backend: 13 | service: 14 | name: app1-nginx-clusterip-service 15 | port: 16 | number: 80 17 | 18 | 19 | -------------------------------------------------------------------------------- /11-AGIC-Probes-Readniess-Liveness/README.md: -------------------------------------------------------------------------------- 1 | # Azure Gateway Ingress - Health Probes (Readiness and Liveness) 2 | 3 | ## Step-01: Introduction 4 | - We are going to understand and implement Health Probes 5 | - Readiness Probe 6 | - Liveness Probe 7 | - Also going to test when we use both probes in kubernetes deployment, which takes priority 8 | 9 | ## Step-02: Usecase-1: Readiness Probe 10 | ```t 11 | # Review the below kube-manifests 12 | # kube-manifests: 01-kube-manifests-readiness 13 | - 01-NginxApp1-Deployment.yaml 14 | - 02-NginxApp1-ClusterIP-Service.yaml 15 | - 03-Ingress-Basic.yml 16 | 17 | # Deploy Apps 18 | kubectl apply -f 01-kube-manifests-readiness/ 19 | 20 | # List Deployments 21 | kubectl get deploy 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 | # Access Application (curl) 33 | curl http:///app1/index.html 34 | 35 | # Access Application (Browser) 36 | http:///app1/index.html 37 | 38 | # Verify Application Gateway Health Probe 39 | - Go to AppGw -> agic-appgw -> Settings -> Health Probes 40 | - Perform TEST 41 | 42 | # Uninstall Apps 43 | kubectl delete -f 01-kube-manifests-readiness/ 44 | ``` 45 | 46 | 47 | ## Step-03: Usecase-2: Liveness Probe 48 | ```t 49 | # Review the below kube-manifests 50 | ## kube-manifests: 02-kube-manifests-liveness 51 | - 01-NginxApp2-Deployment.yml 52 | - 02-NginxApp2-ClusterIP-Service.yml 53 | - 03-Ingress-Basic.yml 54 | 55 | # Deploy Apps 56 | kubectl apply -f 02-kube-manifests-liveness/ 57 | 58 | # List Deployments 59 | kubectl get deploy 60 | 61 | # List Pods 62 | kubectl get pods 63 | 64 | # List Services 65 | kubectl get svc 66 | 67 | # List Ingress 68 | kubectl get ingress 69 | 70 | # Access Application (curl) 71 | curl http:///app2/index.html 72 | 73 | # Access Application (Browser) 74 | http:///app1/index.html 75 | 76 | # Verify Application Gateway Health Probe 77 | - Go to AppGw -> agic-appgw -> Settings -> Health Probes 78 | - Perform TEST 79 | 80 | # Uninstall Apps 81 | kubectl delete -f 02-kube-manifests-liveness/ 82 | ``` 83 | ## Step-04: Usecase-3: Readiness and Liveness Probe 84 | ```t 85 | # Review the below kube-manifests 86 | ## kube-manifests: 03-kube-manifests-both 87 | - 01-NginxApp1-Deployment.yaml 88 | - 02-NginxApp1-ClusterIP-Service.yaml 89 | - 03-Ingress-Basic.yml 90 | 91 | # Deploy Apps 92 | kubectl apply -f 03-kube-manifests-both/ 93 | 94 | # List Deployments 95 | kubectl get deploy 96 | 97 | # List Pods 98 | kubectl get pods 99 | 100 | # List Services 101 | kubectl get svc 102 | 103 | # List Ingress 104 | kubectl get ingress 105 | 106 | # Access Application (curl) 107 | curl http:///app1/index.html 108 | http:///app1/index.html 109 | Observation: 110 | 1. NO TESTING, App Access willt fail. 111 | 2. There is no context at application like "/readiness" or "/liveness" 112 | 3. This is just to see which probe takes PRIORITY when READINESS and LIVENESS both declared in Kubernetes Deployment. 113 | 114 | 115 | # Verify Application Gateway Health Probe 116 | - Go to AppGw -> agic-appgw -> Settings -> Health Probes 117 | 118 | # Uninstall Apps 119 | kubectl delete -f 03-kube-manifests-both/ 120 | ``` 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /12-AGIC-Probes-Annotations/README.md: -------------------------------------------------------------------------------- 1 | # Azure AGIC Ingress - Health Probes (AGIC Annotations) 2 | 3 | ## Step-01: Introduction 4 | - We are going to understand and implement Health Probes using AGIC Annotations 5 | - [AGIC Health Probe Annotations](https://azure.github.io/application-gateway-kubernetes-ingress/annotations/#health-probe-hostname) 6 | ```yaml 7 | annotations: 8 | # Health Probe Annotations 9 | appgw.ingress.kubernetes.io/health-probe-hostname: "myapp1.stacksimplify.com" 10 | appgw.ingress.kubernetes.io/health-probe-port: "80" 11 | appgw.ingress.kubernetes.io/health-probe-path: /app1/index.html 12 | appgw.ingress.kubernetes.io/health-probe-status-codes: "200-205, 206" 13 | appgw.ingress.kubernetes.io/health-probe-interval: "32" 14 | appgw.ingress.kubernetes.io/health-probe-timeout: "32" 15 | appgw.ingress.kubernetes.io/health-probe-unhealthy-threshold: "4" 16 | ``` 17 | 18 | ## Step-02: Health Probe Annotations 19 | - [AGIC Health Probe Annotations](https://azure.github.io/application-gateway-kubernetes-ingress/annotations/#health-probe-path) 20 | ```t 21 | # Review the below kube-manifests 22 | # kube-manifests: 01-kube-manifests-readiness 23 | - 01-NginxApp1-Deployment.yaml 24 | - 02-NginxApp1-ClusterIP-Service.yaml 25 | - 03-Ingress-Basic.yml 26 | 27 | # Deploy Apps 28 | kubectl apply -f kube-manifests/ 29 | 30 | # List Deployments 31 | kubectl get deploy 32 | 33 | # List Pods 34 | kubectl get pods 35 | 36 | # List Services 37 | kubectl get svc 38 | 39 | # List Ingress 40 | kubectl get ingress 41 | 42 | # Access Application (curl) 43 | curl http:///app1/index.html 44 | 45 | # Access Application (Browser) 46 | http:///app1/index.html 47 | 48 | # Verify Application Gateway Health Probe 49 | - Go to AppGw -> agic-appgw -> Settings -> Health Probes 50 | - Perform TEST 51 | 52 | # Uninstall Apps 53 | kubectl delete -f kube-manifests/ 54 | ``` 55 | -------------------------------------------------------------------------------- /12-AGIC-Probes-Annotations/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: ghcr.io/stacksimplify/kube-nginxapp1:1.0.0 20 | ports: 21 | - containerPort: 80 22 | 23 | -------------------------------------------------------------------------------- /12-AGIC-Probes-Annotations/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 | -------------------------------------------------------------------------------- /12-AGIC-Probes-Annotations/kube-manifests/03-Ingress-Basic.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: nginxapp1-ingress-service 5 | annotations: 6 | # Health Probe Annotations 7 | appgw.ingress.kubernetes.io/health-probe-hostname: "myapp1.stacksimplify.com" 8 | appgw.ingress.kubernetes.io/health-probe-port: "80" 9 | appgw.ingress.kubernetes.io/health-probe-path: /app1/index.html 10 | appgw.ingress.kubernetes.io/health-probe-status-codes: "200-205, 206" 11 | appgw.ingress.kubernetes.io/health-probe-interval: "32" 12 | appgw.ingress.kubernetes.io/health-probe-timeout: "32" 13 | appgw.ingress.kubernetes.io/health-probe-unhealthy-threshold: "4" 14 | spec: 15 | ingressClassName: azure-application-gateway 16 | rules: 17 | - http: 18 | paths: 19 | - path: / 20 | pathType: Prefix 21 | backend: 22 | service: 23 | name: app1-nginx-clusterip-service 24 | port: 25 | number: 80 26 | 27 | 28 | -------------------------------------------------------------------------------- /13-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 | -------------------------------------------------------------------------------- /14-ExternalDNS-for-AzureDNS-on-AKS/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": "a16aed69-233f-4e2e-8494-6489e3224490" 7 | } -------------------------------------------------------------------------------- /14-ExternalDNS-for-AzureDNS-on-AKS/kube-manifests/external-dns.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: external-dns 5 | --- 6 | apiVersion: rbac.authorization.k8s.io/v1 7 | kind: ClusterRole 8 | metadata: 9 | name: external-dns 10 | rules: 11 | - apiGroups: [""] 12 | resources: ["services","endpoints","pods", "nodes"] 13 | verbs: ["get","watch","list"] 14 | - apiGroups: ["extensions","networking.k8s.io"] 15 | resources: ["ingresses"] 16 | verbs: ["get","watch","list"] 17 | --- 18 | apiVersion: rbac.authorization.k8s.io/v1 19 | kind: ClusterRoleBinding 20 | metadata: 21 | name: external-dns-viewer 22 | roleRef: 23 | apiGroup: rbac.authorization.k8s.io 24 | kind: ClusterRole 25 | name: external-dns 26 | subjects: 27 | - kind: ServiceAccount 28 | name: external-dns 29 | namespace: default 30 | --- 31 | apiVersion: apps/v1 32 | kind: Deployment 33 | metadata: 34 | name: external-dns 35 | spec: 36 | strategy: 37 | type: Recreate 38 | selector: 39 | matchLabels: 40 | app: external-dns 41 | template: 42 | metadata: 43 | labels: 44 | app: external-dns 45 | spec: 46 | serviceAccountName: external-dns 47 | containers: 48 | - name: external-dns 49 | image: registry.k8s.io/external-dns/external-dns:v0.13.5 50 | args: 51 | - --source=service 52 | - --source=ingress 53 | #- --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. 54 | - --provider=azure 55 | #- --azure-resource-group=MyDnsResourceGroup # (optional) use the DNS zones from the tutorial's resource group 56 | - --txt-prefix=externaldns- 57 | volumeMounts: 58 | - name: azure-config-file 59 | mountPath: /etc/kubernetes 60 | readOnly: true 61 | volumes: 62 | - name: azure-config-file 63 | secret: 64 | secretName: azure-config-file 65 | -------------------------------------------------------------------------------- /15-AGIC-ExternalDNS-Basic/README.md: -------------------------------------------------------------------------------- 1 | # Azure AGIC Ingress - External DNS Basic 2 | 3 | ## Step-01: Introduction 4 | - Deploy a sample Application with Ingress in combination with External DNS 5 | - When we use External DNS, Hostname defined in `Ingress Service` should be automatically added as `Record Set` in `Azure DNS Zones` 6 | 7 | ## Step-02: Review Kubernetes Manifests 8 | - 01-NginxApp1-Deployment.yaml 9 | - 02-NginxApp1-ClusterIP-Service.yaml 10 | - 03-Ingress-with-ExternalDNS.yaml 11 | ```yaml 12 | apiVersion: networking.k8s.io/v1 13 | kind: Ingress 14 | metadata: 15 | name: nginxapp1-ingress-service 16 | spec: 17 | ingressClassName: azure-application-gateway 18 | rules: 19 | - host: myapp1.kubeoncloud.com 20 | http: 21 | paths: 22 | - path: / 23 | pathType: Prefix 24 | backend: 25 | service: 26 | name: app1-nginx-clusterip-service 27 | port: 28 | number: 80 29 | ``` 30 | 31 | ## Step-03: Deploy Application and Test 32 | 33 | ### Step-03-01: Deploy Application 34 | ```t 35 | # Deploy Application 36 | kubectl apply -f kube-manifests/ 37 | 38 | # Verify Pods and Services 39 | kubectl get po,svc 40 | 41 | # Verify Ingress 42 | kubectl get ingress 43 | ``` 44 | 45 | ### Step-03-02: Verify logs in External DNS Pod 46 | - Wait for 1 to 3 minutes for Record Set update in DNZ Zones 47 | ```t 48 | # Verify ExternalDNS Logs 49 | kubectl logs -f $(kubectl get po | egrep -o 'external-dns[A-Za-z0-9-]+') 50 | ``` 51 | - External DNS Pod Logs 52 | ```log 53 | time="2023-09-01T06:21:58Z" level=info msg="Updating A record named 'myapp1' to '13.86.123.83' for Azure DNS zone 'kubeoncloud.com'." 54 | time="2023-09-01T06:21:59Z" level=info msg="Updating TXT record named 'externaldns-myapp1' to '\"heritage=external-dns,external-dns/owner=default,external-dns/resource=ingress/default/nginxapp1-ingress-service\"' for Azure DNS zone 'kubeoncloud.com'." 55 | time="2023-09-01T06:22:00Z" level=info msg="Updating TXT record named 'externaldns-a-myapp1' to '\"heritage=external-dns,external-dns/owner=default,external-dns/resource=ingress/default/nginxapp1-ingress-service\"' for Azure DNS zone 'kubeoncloud.com'." 56 | ``` 57 | 58 | ### Step-03-03: Verify Record Set in DNS Zones -> kubeoncloud.com 59 | - Go to All Services -> DNS Zones -> kubeoncloud.com 60 | - Verify if we have `myapp1.kubeoncloud.com` created 61 | ```t 62 | # Template Command 63 | az network dns record-set a list -g -z 64 | 65 | # Replace DNS Zones Resource Group and yourdomain 66 | az network dns record-set a list -g dns-zones -z kubeoncloud.com 67 | 68 | # Additionally you can review via Azure Portal 69 | Go to Portal -> DNS Zones -> 70 | Review records in "Overview" Tab 71 | ``` 72 | - Perform `nslookup` test 73 | ```t 74 | # nslookup Test 75 | Kalyans-Mac-mini:kube-manifests kalyanreddy$ nslookup myapp1.kubeoncloud.com 76 | Server: 192.168.1.1 77 | Address: 192.168.1.1#53 78 | 79 | Non-authoritative answer: 80 | Name: myapp1.kubeoncloud.com 81 | Address: 52.158.161.63 82 | 83 | Kalyans-Mac-mini:kube-manifests kalyanreddy$ 84 | 85 | ``` 86 | 87 | ### Step-03-04: Access Application and Test 88 | ```t 89 | # Access Application 90 | http://myapp1.kubeoncloud.com 91 | http://myapp1.kubeoncloud.com/app1/index.html 92 | 93 | # Important Note: Replace kubeoncloud.com with your domain name 94 | ``` 95 | 96 | ## Step-04: Clean-Up 97 | ### Step-04-01: Delete Application and Verify 98 | ```t 99 | # Delete Application 100 | kubectl delete -f kube-manifests/ 101 | 102 | # Verify External DNS pod to ensure record set got deleted 103 | kubectl logs -f $(kubectl get po | egrep -o 'external-dns[A-Za-z0-9-]+') 104 | 105 | # Verify Record set got automatically deleted in DNS Zones 106 | # Template Command 107 | az network dns record-set a list -g -z 108 | 109 | # Replace DNS Zones Resource Group and yourdomain 110 | az network dns record-set a list -g dns-zones -z kubeoncloud.com 111 | 112 | # Additionally you can review via Azure Portal 113 | Go to Portal -> DNS Zones -> 114 | Review records in "Overview" Tab 115 | 116 | ``` 117 | ### Step-04-02: Deleting DNS Record Log from External DNS 118 | ```log 119 | time="2023-09-01T06:22:59Z" level=info msg="Deleting A record named 'myapp1' for Azure DNS zone 'kubeoncloud.com'." 120 | time="2023-09-01T06:23:00Z" level=info msg="Deleting TXT record named 'externaldns-myapp1' for Azure DNS zone 'kubeoncloud.com'." 121 | time="2023-09-01T06:23:00Z" level=info msg="Deleting TXT record named 'externaldns-a-myapp1' for Azure DNS zone 'kubeoncloud.com'." 122 | ``` -------------------------------------------------------------------------------- /15-AGIC-ExternalDNS-Basic/kube-manifests/01-NginxApp1-Deployment.yaml: -------------------------------------------------------------------------------- 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: ghcr.io/stacksimplify/kube-nginxapp1:1.0.0 20 | ports: 21 | - containerPort: 80 22 | 23 | -------------------------------------------------------------------------------- /15-AGIC-ExternalDNS-Basic/kube-manifests/02-NginxApp1-ClusterIP-Service.yaml: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /15-AGIC-ExternalDNS-Basic/kube-manifests/03-Ingress-with-ExternalDNS.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: nginxapp1-ingress-service 5 | spec: 6 | ingressClassName: azure-application-gateway 7 | rules: 8 | - host: myapp1.kubeoncloud.com 9 | http: 10 | paths: 11 | - path: /app1 12 | pathType: Prefix 13 | backend: 14 | service: 15 | name: app1-nginx-clusterip-service 16 | port: 17 | number: 80 18 | 19 | -------------------------------------------------------------------------------- /16-AGIC-Domain-Name-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 | ## Step-02: Review k8s Application Manifests 8 | - App1 Manifests 9 | - App2 Manifests 10 | - App3 Manifests 11 | 12 | ## Step-03: Review Ingress Service Manifests 13 | - 01-Ingress-DomainName-Based-Routing-app1-2-3.yml 14 | ```yaml 15 | apiVersion: networking.k8s.io/v1 16 | kind: Ingress 17 | metadata: 18 | name: ingress-app1-app2-app3 19 | spec: 20 | ingressClassName: azure-application-gateway 21 | rules: 22 | - host: eapp1.kubeoncloud.com 23 | http: 24 | paths: 25 | - path: / 26 | pathType: Prefix 27 | backend: 28 | service: 29 | name: app1-nginx-clusterip-service 30 | port: 31 | number: 80 32 | - host: eapp2.kubeoncloud.com 33 | http: 34 | paths: 35 | - path: / 36 | pathType: Prefix 37 | backend: 38 | service: 39 | name: app2-nginx-clusterip-service 40 | port: 41 | number: 80 42 | - host: eapp3.kubeoncloud.com 43 | http: 44 | paths: 45 | - path: / 46 | pathType: Prefix 47 | backend: 48 | service: 49 | name: myapp-nginx-clusterip-service 50 | port: 51 | number: 80 52 | ``` 53 | 54 | ## Step-04: Deploy and Verify 55 | ```t 56 | # Deploy Apps 57 | kubectl apply -R -f kube-manifests/ 58 | 59 | # List Pods 60 | kubectl get pods 61 | 62 | # List Services 63 | kubectl get svc 64 | 65 | # List Ingress 66 | kubectl get ingress 67 | 68 | # Verify External DNS pod to ensure record set got deleted 69 | kubectl logs -f $(kubectl get po | egrep -o 'external-dns[A-Za-z0-9-]+') 70 | 71 | 72 | # Verify Record set got automatically deleted in DNS Zones 73 | # Template Command 74 | az network dns record-set a list -g -z 75 | 76 | # Replace DNS Zones Resource Group and yourdomain 77 | az network dns record-set a list -g dns-zones -z kubeoncloud.com 78 | 79 | # Additionally you can review via Azure Portal 80 | Go to Portal -> DNS Zones -> 81 | Review records in "Overview" Tab 82 | ``` 83 | 84 | ## Step-05: Review Azure Application Gateway using Azure Portal 85 | ```t 86 | # Review Azure AppGW Listeners 87 | 1. Go to Azure AppGW -> agic-appgw -> Settings -> Listeners 88 | 2. We should see 3 Listeners created 1 for each Application 89 | 3. All 3 are Port 80 listeners 90 | 4. Can we create 3 listeners with same port 80 ? 91 | 5. Yes we can create multiple listeners with same port provided there hostname is different 92 | 6. Open any one listener and review the "Host type" and "Host names" settings 93 | ``` 94 | ## Step-06: Access Applications 95 | ```t 96 | # Access App1 97 | http://eapp1.kubeoncloud.com/app1/index.html 98 | 99 | # Access App2 100 | http://eapp2.kubeoncloud.com/app2/index.html 101 | 102 | # Access MyApp 103 | http://eapp3.kubeoncloud.com 104 | 105 | ``` 106 | 107 | ## Step-07: Clean-Up Applications 108 | ```t 109 | # Delete Apps 110 | kubectl delete -R -f kube-manifests/ 111 | 112 | # Verify Record set got automatically deleted in DNS Zones 113 | # Template Command 114 | az network dns record-set a list -g -z 115 | 116 | # Replace DNS Zones Resource Group and yourdomain 117 | az network dns record-set a list -g dns-zones -z kubeoncloud.com 118 | 119 | # Additionally you can review via Azure Portal 120 | Go to Portal -> DNS Zones -> 121 | Review records in "Overview" Tab 122 | ``` 123 | 124 | -------------------------------------------------------------------------------- /16-AGIC-Domain-Name-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: ghcr.io/stacksimplify/kube-nginxapp1:1.0.0 20 | ports: 21 | - containerPort: 80 22 | 23 | -------------------------------------------------------------------------------- /16-AGIC-Domain-Name-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 | -------------------------------------------------------------------------------- /16-AGIC-Domain-Name-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: ghcr.io/stacksimplify/kube-nginxapp2:1.0.0 20 | ports: 21 | - containerPort: 80 22 | -------------------------------------------------------------------------------- /16-AGIC-Domain-Name-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 | -------------------------------------------------------------------------------- /16-AGIC-Domain-Name-Routing/kube-manifests/03-MyApp-Manifests/01-myapp-Deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: myapp-nginx-deployment 5 | labels: 6 | app: myapp-nginx 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: myapp-nginx 12 | template: 13 | metadata: 14 | labels: 15 | app: myapp-nginx 16 | spec: 17 | containers: 18 | - name: myapp-nginx 19 | image: ghcr.io/stacksimplify/kubenginx:1.0.0 20 | ports: 21 | - containerPort: 80 22 | 23 | -------------------------------------------------------------------------------- /16-AGIC-Domain-Name-Routing/kube-manifests/03-MyApp-Manifests/02-myapp-ClusterIP-Service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: myapp-nginx-clusterip-service 5 | labels: 6 | app: myapp-nginx 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | app: myapp-nginx 11 | ports: 12 | - port: 80 13 | targetPort: 80 14 | -------------------------------------------------------------------------------- /16-AGIC-Domain-Name-Routing/kube-manifests/04-IngressService-Manifests/01-Ingress-DomainName-Based-Routing-app1-2-3.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: ingress-app1-app2-app3 5 | spec: 6 | ingressClassName: azure-application-gateway 7 | rules: 8 | - host: eapp1.kubeoncloud.com 9 | http: 10 | paths: 11 | - path: / 12 | pathType: Prefix 13 | backend: 14 | service: 15 | name: app1-nginx-clusterip-service 16 | port: 17 | number: 80 18 | - host: eapp2.kubeoncloud.com 19 | http: 20 | paths: 21 | - path: / 22 | pathType: Prefix 23 | backend: 24 | service: 25 | name: app2-nginx-clusterip-service 26 | port: 27 | number: 80 28 | - host: eapp3.kubeoncloud.com 29 | http: 30 | paths: 31 | - path: / 32 | pathType: Prefix 33 | backend: 34 | service: 35 | name: myapp-nginx-clusterip-service 36 | port: 37 | number: 80 38 | -------------------------------------------------------------------------------- /17-AGIC-Ingress-TLS/README.md: -------------------------------------------------------------------------------- 1 | # Azure AGIC Ingress - TLS 2 | 3 | ## Step-00: Pre-requisites 4 | 1. Verify if Azure AKS Cluster is created 5 | 2. Verify if kubeconfig for kubectl is configured in your local terminal 6 | ```t 7 | # Configure kubeconfig for kubectl 8 | az aks get-credentials --resource-group agicdemo --name agic-cluster 9 | 10 | # List Kubernetes Nodes 11 | kubectl get nodes 12 | ``` 13 | 14 | 3. ExternalDNS Controller should be installed and ready to use 15 | ```t 16 | # List Deployments 17 | kubectl get deploy 18 | 19 | # List External DNS Pods 20 | kubectl get pods 21 | ``` 22 | 23 | ## Step-01: Introduction 24 | 1. Implement Self Signed SSL Certificates with Azure AGIC Ingress Service 25 | 2. Create SSL Certificates using OpenSSL. 26 | 3. Create Kubernetes Secret with SSL Certificate and Private Key 27 | 4. Reference these Kubernetes Secrets in Ingress Service **Ingress spec.tls** 28 | 29 | ## Step-02: App1 - Create Self-Signed SSL Certificates and Kubernetes Secrets 30 | ```t 31 | # Change Directory 32 | cd SSL-SelfSigned-Certs 33 | 34 | # Create your app1 private key: 35 | openssl genrsa -out app1-ingress.key 2048 36 | 37 | # Create your app1 certificate signing request: 38 | openssl req -new -key app1-ingress.key -out app1-ingress.csr -subj "/CN=app1.kubeoncloud.com" 39 | 40 | # Create your app1 certificate: 41 | openssl x509 -req -days 7300 -in app1-ingress.csr -signkey app1-ingress.key -out app1-ingress.crt 42 | 43 | # Create a Secret that holds your app1 certificate and key: 44 | cd SSL-SelfSigned-Certs 45 | kubectl create secret tls app1-secret --cert app1-ingress.crt --key app1-ingress.key 46 | 47 | # List Secrets 48 | kubectl get secrets 49 | ``` 50 | 51 | ## Step-03: Review App1 kube-manifests 52 | 1. 01-myapp-Deployment.yaml 53 | 2. 02-myapp-ClusterIP-Service.yaml 54 | 55 | ## Step-04: Review 03-Ingress-SSL-TLS.yaml 56 | ```yaml 57 | apiVersion: networking.k8s.io/v1 58 | kind: Ingress 59 | metadata: 60 | name: ingress-app1-ssl-tls 61 | spec: 62 | ingressClassName: azure-application-gateway 63 | # SSL Certs - Associate using Kubernetes Secrets 64 | tls: 65 | - secretName: app1-secret 66 | rules: 67 | - host: app1.kubeoncloud.com 68 | http: 69 | paths: 70 | - path: / 71 | pathType: Prefix 72 | backend: 73 | service: 74 | name: myapp-nginx-clusterip-service 75 | port: 76 | number: 80 77 | ``` 78 | 79 | 80 | ## Step-05: Deploy Kubernetes Manifests and Verify 81 | ```t 82 | # Deploy Kubernetes Manifests 83 | kubectl apply -f kube-manifests 84 | 85 | # List Deployments 86 | kubectl get deploy 87 | 88 | # List Pods 89 | kubectl get pods 90 | 91 | # List Services 92 | kubectl get svc 93 | 94 | # List Ingress Services 95 | kubectl get ingress 96 | 97 | # Describe Ingress Service 98 | kubectl describe ingress ingress-selfsigned-ssl-tls 99 | 100 | # Verify external-dns Controller logs 101 | kubectl logs -f $(kubectl get po | egrep -o 'external-dns[A-Za-z0-9-]+') 102 | [or] 103 | kubectl get pods 104 | kubectl logs -f 105 | 106 | # Verify Azure DNS 107 | 1. Go to DNS Zones -> kubeoncloud.com 108 | 2. Review the new DNS record created 109 | 110 | # Verify SSL Certificate on Azure App Gateway 111 | 1. Go to Azure Application Gateway -> agic-appgw -> Settings -> Listeners 112 | 2. We should see a 443 listener created 113 | 3. Click on Tab "Listeners TLS Certificates" 114 | 4. We should see our SSL Certificate uploaded to Azure AppGw from Kubernetes secret we created "app1-secret" 115 | 5. Review the 443 Listener Port, Certificate, Listener Type, Host Type and Host names 116 | ``` 117 | 118 | ## Step-06: Access Application 119 | ```t 120 | # Access Application using HTTPS URL 121 | https://app1.kubeoncloud.com 122 | 123 | Observation: 124 | 1. You will get a warning "The certificate is not trusted because it is self-signed.". Click on "Accept the risk and continue" 125 | 126 | # Access Application using HTTP 127 | http://app1.kubeoncloud.com 128 | 129 | Observation: 130 | 1. There is no port 80 listener so request should fail 131 | 2. We can create a SSL Redirect from port 80 to port 443 (HTTP to HTTPS) which we will do in our next demo 132 | 3. We will not clean-up our Application in this demo. 133 | ``` 134 | 135 | -------------------------------------------------------------------------------- /17-AGIC-Ingress-TLS/SSL-SelfSigned-Certs/app1-ingress.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICxTCCAa0CFDNbvQLXAAwTcIYGYZrGmyzjfCIhMA0GCSqGSIb3DQEBCwUAMB8x 3 | HTAbBgNVBAMMFGFwcDEua3ViZW9uY2xvdWQuY29tMB4XDTIzMDkyNDAwMTQyN1oX 4 | DTQzMDkxOTAwMTQyN1owHzEdMBsGA1UEAwwUYXBwMS5rdWJlb25jbG91ZC5jb20w 5 | ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDqRfXlLziGUgiRe9LUpvmP 6 | mE0vcxwjvtQiKPkO2jwLr82TODlKtO1hbQyi7pwZ6LxOXSWIzML7Capsm7gosems 7 | xHm8yponJZ010QjD20wnWjn+JJXo7DbcM5dxdHvpuH/HypNWm3lx7JqupqT4GiTx 8 | 1acSwNqN3dGsxn6SNJj8qvqvaMMIOrrviSQHLqihRiSNw+4vgNqFc5Mw8rTg9sW0 9 | RbzYIzvgK+S1ZvL0sAoNvlaWtBWm5ey0Z68b05FE6z7TDJPxT/NuqtUXmgd++gBT 10 | Pgph+Rpgzy53I78c/D2LqZyAxi94S+wPYbQwsllawy4RxYTUikJzKijTesJ6X8mb 11 | AgMBAAEwDQYJKoZIhvcNAQELBQADggEBANLnJfvgcolEkij9BOGGb20Qq5yZmZ3s 12 | ZIeVPjcuZjyVme8bEURhyLFneSnjLb1I2TwrSsxJdbXBc/AsxLWYgCjqEfNUx6fd 13 | xkd40pnIo1Q/4Hm83z1/hpdaUdHNvHmw1WtS1NOHLgEt87EbCpUYY/oGXeOlE3qp 14 | QiWg3qr015uc24f97PfdtDDgytEWbvhrPXAMGSkctLCPhToXVB88HnU5r3UuBQjs 15 | 0PZa9LxIxsTs2nFeyohiCZHN6F/+nANeGjBmWU69YqFA9k4NLWh7ckIcTn2A2SmK 16 | yOw4aHJUv/AHVcKIReWnywWdA6C9f1AFbAaGm8V7ws9HWPVnmVSZY0U= 17 | -----END CERTIFICATE----- 18 | -------------------------------------------------------------------------------- /17-AGIC-Ingress-TLS/SSL-SelfSigned-Certs/app1-ingress.csr: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE REQUEST----- 2 | MIICZDCCAUwCAQAwHzEdMBsGA1UEAwwUYXBwMS5rdWJlb25jbG91ZC5jb20wggEi 3 | MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDqRfXlLziGUgiRe9LUpvmPmE0v 4 | cxwjvtQiKPkO2jwLr82TODlKtO1hbQyi7pwZ6LxOXSWIzML7Capsm7gosemsxHm8 5 | yponJZ010QjD20wnWjn+JJXo7DbcM5dxdHvpuH/HypNWm3lx7JqupqT4GiTx1acS 6 | wNqN3dGsxn6SNJj8qvqvaMMIOrrviSQHLqihRiSNw+4vgNqFc5Mw8rTg9sW0RbzY 7 | IzvgK+S1ZvL0sAoNvlaWtBWm5ey0Z68b05FE6z7TDJPxT/NuqtUXmgd++gBTPgph 8 | +Rpgzy53I78c/D2LqZyAxi94S+wPYbQwsllawy4RxYTUikJzKijTesJ6X8mbAgMB 9 | AAGgADANBgkqhkiG9w0BAQsFAAOCAQEAsTSBW17jJQpmPAhLSUIYQqcaumLQxkiA 10 | mISFoKMYR3sFNKPkSC5mi1Wk8JLVUpRlYZwZorOSFxHG5R33gjbVq5WnDB3iaXKa 11 | C38EmlF3JMNlWCVHReVRRgzTmdOxTlXjE07znLafGmb2cKQhQN5soXARdUG2LRQW 12 | o8o121AI8xGJWoDtEVaHK+sOkZfPuu2/m8a4DH2xGeHc6MJbjVb/KYQ5H++n6crX 13 | ShxC3hA+yR0DS5sOfr+5B+6DRVfSf4o6QiYh4VGxyFvEpPpIlKUCNgaX/R/eDfHh 14 | XSKtyVkz3q8ZoAQPAprefUFlXFREykOWyDMeeKw/AUnb6pgLgIfABQ== 15 | -----END CERTIFICATE REQUEST----- 16 | -------------------------------------------------------------------------------- /17-AGIC-Ingress-TLS/SSL-SelfSigned-Certs/app1-ingress.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDqRfXlLziGUgiR 3 | e9LUpvmPmE0vcxwjvtQiKPkO2jwLr82TODlKtO1hbQyi7pwZ6LxOXSWIzML7Caps 4 | m7gosemsxHm8yponJZ010QjD20wnWjn+JJXo7DbcM5dxdHvpuH/HypNWm3lx7Jqu 5 | pqT4GiTx1acSwNqN3dGsxn6SNJj8qvqvaMMIOrrviSQHLqihRiSNw+4vgNqFc5Mw 6 | 8rTg9sW0RbzYIzvgK+S1ZvL0sAoNvlaWtBWm5ey0Z68b05FE6z7TDJPxT/NuqtUX 7 | mgd++gBTPgph+Rpgzy53I78c/D2LqZyAxi94S+wPYbQwsllawy4RxYTUikJzKijT 8 | esJ6X8mbAgMBAAECggEALdzwXKO37yPUJZcWGSdvJ9trEOT6F01efimDSJMUujz6 9 | g9236ZYt+qq8lJEd4jyb0MOPe46KhVbJFGYP0XezBW2ZX4pST2OfuU9o5d7is7mI 10 | LObAqk7EFqvK9B0XvROvgE96NLRPPCxTw+k/1opXvThUculqX+eTCr35PWoqoRv/ 11 | 7cJu6AVVSwMsQM3V4YgiSgoEI1vfrXXCWJQrMPjGSjAnzV26mET9WYlKyRu3Fpl2 12 | gCu31OubcsBY96ySppa1l1awQpk4nGjwGpz2GH70Zd+kko9gF0L6NRYWhc6jJu7o 13 | 2JoxXBZJJCbjzRPfmkUpvO80kGkjlMxax0chtpJZ0QKBgQD+sild9kk5cVRPD/Yb 14 | rKZvO2K8MTU1TLnM2eFefklQznzX5eLsgIIg7QV7cvUzRq8D+bw03YIBBj8p5D1z 15 | j0CjKg1eBNv0fpDgz+iLyGL8HgjTchqvzu3S7BnlZ91OsB+mxNBCzB59nuf7lf/q 16 | a5HL+SttyZAdcMtwfUyHGrPn7wKBgQDreQfAfJvM6MmJvhK0op2jAFNsjHEtPHK+ 17 | wEpyvHfB26O92PW5w61S9OdOg8uEFcjJOPVS8kQHKzB3pgRKlMvYt1FYndkD0FhH 18 | IoTkwgWow/4OEZdABE+MyVOa+gQi++bd1wlR3qqNt6DKXQIStSdTm60EA+E0A+15 19 | VOfG+PNtFQKBgGTeZFmtJ3TTeENTm/F73/Jff4vupRb1ywPhKktFEn4pOPI8PjHR 20 | 9zdZB3nLnmZvUPLvHeWF8G29bpiFpvy0ODImfmLE4+OhmHkgfgWWF/WnY3FyWDVW 21 | a4PEM8FR8CiwwehHO/+oXU789v0Be/f4ICa7CMMTN7shJ8DmLr+3CJcLAoGALPOi 22 | 7jUbjQeXicsWSROOIlLqmhtJc8hJY27UB4lBF2n1nUVwy3C2gtKr4Yo5bNK3zOop 23 | sxb6s5+kFgNEaHR1Yb7FMbSYfCjm4VWOpxj++ZPIySjEhf0MrqS0aC54YbFTBmCJ 24 | r+5hAsLeWCNfRPD+O/DJG64d7M8fI3147bwSxG0CgYEAt344svcGXBq6k0HyFqHj 25 | 845OK/yHqS8RSvNqUTNqSJEaQto60xs8j5z+CBo6HZvl5LPM0FAgy76jeko6M5IF 26 | vYkSbH6G/RT1/Mcd8tQBw9QGPlnrVPIH4UV8BaXOXfK2e1xkTdWt66Jj8LeD6k6g 27 | ig/lXpoD+e3abtQt/OgLt+w= 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /17-AGIC-Ingress-TLS/kube-manifests/01-myapp-Deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: myapp-nginx-deployment 5 | labels: 6 | app: myapp-nginx 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: myapp-nginx 12 | template: 13 | metadata: 14 | labels: 15 | app: myapp-nginx 16 | spec: 17 | containers: 18 | - name: myapp-nginx 19 | image: ghcr.io/stacksimplify/kubenginx:1.0.0 20 | ports: 21 | - containerPort: 80 22 | 23 | -------------------------------------------------------------------------------- /17-AGIC-Ingress-TLS/kube-manifests/02-myapp-ClusterIP-Service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: myapp-nginx-clusterip-service 5 | labels: 6 | app: myapp-nginx 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | app: myapp-nginx 11 | ports: 12 | - port: 80 13 | targetPort: 80 14 | -------------------------------------------------------------------------------- /17-AGIC-Ingress-TLS/kube-manifests/03-Ingress-SSL-TLS.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: ingress-selfsigned-ssl-tls 5 | spec: 6 | ingressClassName: azure-application-gateway 7 | # SSL Certs - Associate using Kubernetes Secrets 8 | tls: 9 | - secretName: app1-secret 10 | rules: 11 | - host: app1.kubeoncloud.com 12 | http: 13 | paths: 14 | - path: / 15 | pathType: Prefix 16 | backend: 17 | service: 18 | name: myapp-nginx-clusterip-service 19 | port: 20 | number: 80 21 | -------------------------------------------------------------------------------- /18-AGIC-SSL-Redirect/README.md: -------------------------------------------------------------------------------- 1 | # AGIC Ingress - SSL Redirect 2 | 3 | ## Step-01: Introduction 4 | - We are going to understand and implement the AGIC Ingress SSL Redirect Annotation 5 | ```yaml 6 | # AGIC Ingress SSL Redirect Annotation 7 | appgw.ingress.kubernetes.io/ssl-redirect: "true" 8 | ``` 9 | 10 | ## Step-02: Review 03-Ingress-SSL-TLS.yaml 11 | - [AGIC SSL Redirect Annotation](https://azure.github.io/application-gateway-kubernetes-ingress/annotations/#ssl-redirect) 12 | ```yaml 13 | apiVersion: networking.k8s.io/v1 14 | kind: Ingress 15 | metadata: 16 | name: ingress-selfsigned-ssl-tls 17 | annotations: 18 | appgw.ingress.kubernetes.io/ssl-redirect: "true" 19 | spec: 20 | ingressClassName: azure-application-gateway 21 | # SSL Certs - Associate using Kubernetes Secrets 22 | tls: 23 | - secretName: app1-secret 24 | rules: 25 | - host: app1.kubeoncloud.com 26 | http: 27 | paths: 28 | - path: / 29 | pathType: Prefix 30 | backend: 31 | service: 32 | name: myapp-nginx-clusterip-service 33 | port: 34 | number: 80 35 | ``` 36 | 37 | ## Step-03: Deploy and Verify 38 | ```t 39 | # Deploy updated Ingress Manifest 40 | kubectl apply -f kube-manifests/ 41 | 42 | # Access Application (HTTP URL) 43 | http://app1.kubeoncloud.com 44 | Observation: 45 | 1. HTTP URL should redirect to HTTPS URL 46 | 47 | # Review Azure Application Gateway Listeners 48 | 1. Go to Azure Application Gateway -> agic-appgw -> Settings -> Listeners 49 | 2. We should see a 80 listener created, open and review the associated Rule 50 | 3. In Rule, Backend Targets section we should 51 | Target Type: Redirection 52 | Redirection Type: permanent 53 | Target Listener: this will be 443 listener 54 | ``` 55 | 56 | ## Step-04: Clean-Up 57 | ```t 58 | # Delete Application 59 | kubectl delete -f kube-manifests/ 60 | 61 | # Delete Kubernetes Secret 62 | kubectl delete secret app1-secret 63 | kubectl get secrets 64 | 65 | # Delete SSL Certificate from AppGW 66 | 1. Go to Azure Portal -> AppGW -> agic-appgw -> Settings -> Listeners 67 | 2. In "Listeners TLS Certificates" Tab -> Open "cert-default-app1-secret" and click on "Delete" 68 | 3. Provide name of certificate to delete "cert-default-app1-secret" 69 | 4. Click on "Delete" 70 | ``` -------------------------------------------------------------------------------- /18-AGIC-SSL-Redirect/kube-manifests/01-myapp-Deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: myapp-nginx-deployment 5 | labels: 6 | app: myapp-nginx 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: myapp-nginx 12 | template: 13 | metadata: 14 | labels: 15 | app: myapp-nginx 16 | spec: 17 | containers: 18 | - name: myapp-nginx 19 | image: ghcr.io/stacksimplify/kubenginx:1.0.0 20 | ports: 21 | - containerPort: 80 22 | 23 | -------------------------------------------------------------------------------- /18-AGIC-SSL-Redirect/kube-manifests/02-myapp-ClusterIP-Service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: myapp-nginx-clusterip-service 5 | labels: 6 | app: myapp-nginx 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | app: myapp-nginx 11 | ports: 12 | - port: 80 13 | targetPort: 80 14 | -------------------------------------------------------------------------------- /18-AGIC-SSL-Redirect/kube-manifests/03-Ingress-SSL-TLS.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: ingress-selfsigned-ssl-tls 5 | annotations: 6 | appgw.ingress.kubernetes.io/ssl-redirect: "true" 7 | spec: 8 | ingressClassName: azure-application-gateway 9 | # SSL Certs - Associate using Kubernetes Secrets 10 | tls: 11 | - secretName: app1-secret 12 | rules: 13 | - host: app1.kubeoncloud.com 14 | http: 15 | paths: 16 | - path: / 17 | pathType: Prefix 18 | backend: 19 | service: 20 | name: myapp-nginx-clusterip-service 21 | port: 22 | number: 80 23 | -------------------------------------------------------------------------------- /19-AGIC-Upload-SSLCert-AppGW/README.md: -------------------------------------------------------------------------------- 1 | # Azure AGIC Ingress - SSL Certs Upload to AppGW 2 | 3 | ## Step-01: Introduction 4 | - We are going to understand and implement `appgw-ssl-certificate` Annotation 5 | - We are going to upload an SSL Certificate to Azure AppGW and use it in our Ingress Manifest Annotation 6 | ```yaml 7 | annotations: 8 | appgw.ingress.kubernetes.io/ssl-redirect: "true" 9 | appgw.ingress.kubernetes.io/appgw-ssl-certificate: "app2sslcert" 10 | ``` 11 | 12 | ## Step-02: App2 - Create Self-Signed SSL Certificates 13 | ```t 14 | # Change Directory 15 | cd SSL-SelfSigned-Certs 16 | 17 | # Create your app2 private key: 18 | openssl genrsa -out app2-ingress.key 2048 19 | 20 | # Create your app2 certificate signing request: 21 | openssl req -new -key app2-ingress.key -out app2-ingress.csr -subj "/CN=app2.kubeoncloud.com" 22 | 23 | # Create your app2 certificate: 24 | openssl x509 -req -days 7300 -in app2-ingress.csr -signkey app2-ingress.key -out app2-ingress.crt 25 | 26 | # Convert Certificate and Key to PFX Format 27 | openssl pkcs12 -export -in app2-ingress.crt -inkey app2-ingress.key -passout pass:certpass123 -out app2-ingress.pfx 28 | ``` 29 | 30 | ## Step-03: Upload Certificate to Azure Application Gateway 31 | ```t 32 | # Change Directory 33 | cd SSL-SelfSigned-Certs 34 | 35 | # Gather Information about AGIC 36 | 1. AGIC Name: agic-appgw 37 | 2. AGIC Resource Group: MC_agicdemo_agic-cluster_eastus 38 | 39 | # List SSL Cets in AppGW 40 | az network application-gateway ssl-cert list --resource-group MC_agicdemo_agic-cluster_eastus --gateway-name agic-appgw 41 | 42 | # Upload Certificate to AppGW 43 | az network application-gateway ssl-cert create \ 44 | --resource-group MC_agicdemo_agic-cluster_eastus \ 45 | --gateway-name agic-appgw \ 46 | -n app2sslcert \ 47 | --cert-file app2-ingress.pfx \ 48 | --cert-password "certpass123" 49 | 50 | # List SSL Cets in AppGW 51 | az network application-gateway ssl-cert list --resource-group MC_agicdemo_agic-cluster_eastus --gateway-name agic-appgw 52 | 53 | # Show app2sslcert from AppGW 54 | az network application-gateway ssl-cert show -n app2sslcert --resource-group MC_agicdemo_agic-cluster_eastus --gateway-name agic-appgw 55 | 56 | # Verify the same using Azure Portal 57 | 1. Go to Azure Portal -> App GW -> agic-appgw -> Settings -> Listeners 58 | 2. In "Listeners TLS Certificates" tab, we should find our "app2sslcert" listed 59 | ``` 60 | 61 | ## Step-04: Review 03-Ingress-AppGW-SSL-Cert.yaml 62 | ```yaml 63 | apiVersion: networking.k8s.io/v1 64 | kind: Ingress 65 | metadata: 66 | name: ingress-selfsigned-ssl-tls 67 | annotations: 68 | appgw.ingress.kubernetes.io/ssl-redirect: "true" 69 | appgw.ingress.kubernetes.io/appgw-ssl-certificate: "app2sslcert" 70 | spec: 71 | ingressClassName: azure-application-gateway 72 | rules: 73 | - host: app2.kubeoncloud.com 74 | http: 75 | paths: 76 | - path: / 77 | pathType: Prefix 78 | backend: 79 | service: 80 | name: myapp-nginx-clusterip-service 81 | port: 82 | number: 80 83 | ``` 84 | 85 | 86 | ## Step-05: Deploy Kubernetes Manifests and Verify 87 | ```t 88 | # Change Directory 89 | cd 19-AGIC-Upload-SSLCert-AppGW 90 | 91 | # Deploy Kubernetes Manifests 92 | kubectl apply -f kube-manifests/ 93 | 94 | # List Deployments 95 | kubectl get deploy 96 | 97 | # List Pods 98 | kubectl get pods 99 | 100 | # List Services 101 | kubectl get svc 102 | 103 | # List Ingress Services 104 | kubectl get ingress 105 | 106 | # Describe Ingress Service 107 | kubectl describe ingress ingress-selfsigned-appgw-ssl 108 | 109 | # Verify external-dns Controller logs 110 | kubectl logs -f $(kubectl get po | egrep -o 'external-dns[A-Za-z0-9-]+') 111 | [or] 112 | kubectl get pods 113 | kubectl logs -f 114 | 115 | # Verify Azure DNS 116 | 1. Go to DNS Zones -> kubeoncloud.com 117 | 2. Review the new DNS record created 118 | ``` 119 | 120 | ## Step-06: Access Application 121 | ```t 122 | # Access Application HTTP URL 123 | http://app2.kubeoncloud.com 124 | Observation: 125 | 1. Should redirect to HTTPS URL 126 | 127 | # Access Application HTTPS URL 128 | https://app2.kubeoncloud.com 129 | 130 | Observation: 131 | 1. You will get a warning "The certificate is not trusted because it is self-signed.". Click on "Accept the risk and continue" 132 | 2. Review SSL Certificate CN from browser 133 | ``` 134 | 135 | 136 | ## Step-07: Clean-Up 137 | ```t 138 | # Delete Application 139 | kubectl delete -f kube-manifests/ 140 | 141 | # Delete SSL Certificate from AppGW (Optional) 142 | 1. Go to Azure Portal -> AppGW -> agic-appgw -> Settings -> Listeners 143 | 2. In "Listeners TLS Certificates" Tab -> Open "app2sslcert" and click on "Delete" 144 | 3. Provide name of certificate to delete "app2sslcert" 145 | 4. Click on "Delete" 146 | ``` 147 | 148 | -------------------------------------------------------------------------------- /19-AGIC-Upload-SSLCert-AppGW/SSL-SelfSigned-Certs/app2-ingress.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICxTCCAa0CFDQzl5vSbqKfO9KVSIoUWHnCGs69MA0GCSqGSIb3DQEBCwUAMB8x 3 | HTAbBgNVBAMMFGFwcDIua3ViZW9uY2xvdWQuY29tMB4XDTIzMDkyNDAxMzEzOFoX 4 | DTQzMDkxOTAxMzEzOFowHzEdMBsGA1UEAwwUYXBwMi5rdWJlb25jbG91ZC5jb20w 5 | ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCwz/lBgEg7NG9pVSKov9c6 6 | UI00ZSmyYPsf9EbZDxZLrWRiNtUQA/MGD3MuckPWnFplX26iBXim6YQEpvrldtjb 7 | MbuefdPd7dlV9A1NvSYPc0Q+aUX+jv8D/zzVaQKe5yfP8ca62BMk3mFgQvCPTCW+ 8 | u6DJMB93pIMkqHkjAzE8p5P1o8codWBgd4Mg2Ur6guFaaqYInimno/8fSL0ShehJ 9 | PeBLF7wiZ8DrxW5P7DTDyB/1+WYUyW5zuZnnVrctSyvJLqCNsIp18zzRMQlK9ku/ 10 | sNPjMRfxpOMzv6Jsze2+kZCCFxxPikvRX2SgAKwR8cDroQaU5+p8qDgqfOUXtp3x 11 | AgMBAAEwDQYJKoZIhvcNAQELBQADggEBAD3AKZS9CXIiqCW/e9aZA6eAEXv30wNr 12 | ZPMYbykFi3RkKyR/+doBe0T0442joS+PPY5Noo+xgSqHH6j9U1xw4SCvmJmLc+sX 13 | yGbtL8+vtn5+EKaudOllg+wPd7sFO1iTic1QF8TulM2eZJv8O8Up73TG/FzQGp4g 14 | aXW5HwhjMp1o+lcF7J6dk3sP1V4Poke5xyWOH9XOJXodmk2CUEF3XZW4dgOnU1n5 15 | wE73tNm2zNutfjooJsPj35cRX/vOYMT1e/+KEONG3ZepeL8la9kCY0LSrXHZVUuD 16 | BzI4CICaa6MLIfCHMlS7l6D4ftlbwCdVcqrJwu+Qxyk7GNhnU60OEkA= 17 | -----END CERTIFICATE----- 18 | -------------------------------------------------------------------------------- /19-AGIC-Upload-SSLCert-AppGW/SSL-SelfSigned-Certs/app2-ingress.csr: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE REQUEST----- 2 | MIICZDCCAUwCAQAwHzEdMBsGA1UEAwwUYXBwMi5rdWJlb25jbG91ZC5jb20wggEi 3 | MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCwz/lBgEg7NG9pVSKov9c6UI00 4 | ZSmyYPsf9EbZDxZLrWRiNtUQA/MGD3MuckPWnFplX26iBXim6YQEpvrldtjbMbue 5 | fdPd7dlV9A1NvSYPc0Q+aUX+jv8D/zzVaQKe5yfP8ca62BMk3mFgQvCPTCW+u6DJ 6 | MB93pIMkqHkjAzE8p5P1o8codWBgd4Mg2Ur6guFaaqYInimno/8fSL0ShehJPeBL 7 | F7wiZ8DrxW5P7DTDyB/1+WYUyW5zuZnnVrctSyvJLqCNsIp18zzRMQlK9ku/sNPj 8 | MRfxpOMzv6Jsze2+kZCCFxxPikvRX2SgAKwR8cDroQaU5+p8qDgqfOUXtp3xAgMB 9 | AAGgADANBgkqhkiG9w0BAQsFAAOCAQEAg+q2pit4AArVoX/1vYOCANY6gbaBQZB9 10 | NtxzywIYUHlZ3xmt4jxsj3vS5SAsFZcCPKUUchJsxWcpLgR1bH6UfbTwpXhlzXfV 11 | uVkY0FaTLwdOmFwTtHyjA50jf8TcNorASuSqyy/1EYpQFbImHOxDrDNcMHIWtcYl 12 | RV4B8WCcJm/BxtyUc7lzA+3iUKd3IIcqWifqDU6ESH8FaEjI8ayKV5EtXH6l84ir 13 | EbJLlkovZ4qdE4mEkZdl6sPWJHADEO8PggLSdTsD4yKQmbCcNZ/w/lYDyN5RRu1V 14 | rdUF8F4qFoTZM+FMYFBbt0r5TWELkhYIxnEKw27TvP79fLOQmaoDow== 15 | -----END CERTIFICATE REQUEST----- 16 | -------------------------------------------------------------------------------- /19-AGIC-Upload-SSLCert-AppGW/SSL-SelfSigned-Certs/app2-ingress.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCwz/lBgEg7NG9p 3 | VSKov9c6UI00ZSmyYPsf9EbZDxZLrWRiNtUQA/MGD3MuckPWnFplX26iBXim6YQE 4 | pvrldtjbMbuefdPd7dlV9A1NvSYPc0Q+aUX+jv8D/zzVaQKe5yfP8ca62BMk3mFg 5 | QvCPTCW+u6DJMB93pIMkqHkjAzE8p5P1o8codWBgd4Mg2Ur6guFaaqYInimno/8f 6 | SL0ShehJPeBLF7wiZ8DrxW5P7DTDyB/1+WYUyW5zuZnnVrctSyvJLqCNsIp18zzR 7 | MQlK9ku/sNPjMRfxpOMzv6Jsze2+kZCCFxxPikvRX2SgAKwR8cDroQaU5+p8qDgq 8 | fOUXtp3xAgMBAAECggEAC4H3CappKRdMKAQfPcdB9rzpj88vaU7IEWft7jB98D4l 9 | sixk7huqXHWIIYNU2Hneep9n3S+Izyjpdim4WykYIJ4KRXIQO8Rq+IiU5BTLORwK 10 | BUYx73PhnkzlVJ4hdPOmWEb2uvrstgyA3x8Zi+Ngx9rrh6Se6650ovURxfOuJ5xv 11 | JySwgtbFh+iQx/pEgdDtcM1ccXoA/lIS74oCC+6J4X7PxmlGoLVOY38rULO94kcx 12 | VzEE9Yxb3YVUkHKNG+h7mS4dpszWnQj6Vo88mRCZnDl93JGfjTi4ypgaOzL4DWf4 13 | /d6/lDcTRKvARVG98UT8K4zKOs1jCp9ymyoBUHcNVQKBgQDdnnYJub4tGkm4brEo 14 | 0LZ3usR2cyUXmigic2DaLtHzP9l8b2Z2v8149V9qL5a+6oAV/tQ67b2C7og50AlA 15 | saz94RgfDTlDyMOMlt7CwvO8qanY8htauXdgatMrkFklvIhd+NzlCSO/UtY21Q5i 16 | qZyscpNLgIM1FhNkChIrX+C5JQKBgQDMPgff5p+w8z0hQPIX8fxuZrgpUmBevZyE 17 | JM9CSTj7fdWv4c+q5+aSmJ9fy77hjdrOB6DgMk5HlaA+I7B1XCh9TNHPkyHKjYBj 18 | v4fqskAgX8cbOkHcHiijgB+svmzk1Xnzmh955EcPggVNwgXm26U9+RGLjNoIR4cl 19 | V/3TKY/V3QKBgQCU5QTLDfb+mH3VItF16ZveHyYlqsDN9a1nT/tPO0ulUU2Oc830 20 | lHK5BKohTm3KQQTjQj1WhingEOCHbwT4aScfvx6Upi7GItl22Fo7of1d0OOjNS45 21 | qwfQSJUt3KJ4Xw2DjVLjsltJDJ+NYWFz2h7AIY5imKoOfZFzkeyZJaZ23QKBgDUg 22 | QX4dCBbH/nOi6BYQbL/u2iJtegHKwmahCIROdZL9NVMtoo3rCk/BgVsyrTEQbATB 23 | eTg3/aKjKe5f7Ctq0GFfVQfwVo7QZcAMdvc2bHW/VBQiADWYZqu4zQRq9/pCCRmz 24 | UlKrbUx8XpLOUCivo3jOS6EH/0K+EEpHbA+8NNzFAoGAakJEiPQe7Gd1Q4qD+qfE 25 | BNrbWUQQx8pK97kdQ/s9Xlkh0B7q4ZdNMMSuUxkRZVpjR6cxjrqWAU70cVXxK3f/ 26 | yGRWqJGhulDMEWimRMIlxL1+EqUJ1NkNYrlh/xWQ6/pAFnuu+oXbzS8wUDo+vZzo 27 | kL+owP+ZK28JfKhBFInKjr4= 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /19-AGIC-Upload-SSLCert-AppGW/SSL-SelfSigned-Certs/app2-ingress.pfx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stacksimplify/azure-kubernetes-service-agic/8855a9b2d627362865c514914c99475b6842e79b/19-AGIC-Upload-SSLCert-AppGW/SSL-SelfSigned-Certs/app2-ingress.pfx -------------------------------------------------------------------------------- /19-AGIC-Upload-SSLCert-AppGW/kube-manifests/01-myapp-Deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: myapp-nginx-deployment 5 | labels: 6 | app: myapp-nginx 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: myapp-nginx 12 | template: 13 | metadata: 14 | labels: 15 | app: myapp-nginx 16 | spec: 17 | containers: 18 | - name: myapp-nginx 19 | image: ghcr.io/stacksimplify/kubenginx:1.0.0 20 | ports: 21 | - containerPort: 80 22 | 23 | -------------------------------------------------------------------------------- /19-AGIC-Upload-SSLCert-AppGW/kube-manifests/02-myapp-ClusterIP-Service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: myapp-nginx-clusterip-service 5 | labels: 6 | app: myapp-nginx 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | app: myapp-nginx 11 | ports: 12 | - port: 80 13 | targetPort: 80 14 | -------------------------------------------------------------------------------- /19-AGIC-Upload-SSLCert-AppGW/kube-manifests/03-Ingress-AppGW-SSL-Cert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: ingress-selfsigned-appgw-ssl 5 | annotations: 6 | appgw.ingress.kubernetes.io/ssl-redirect: "true" 7 | appgw.ingress.kubernetes.io/appgw-ssl-certificate: "app2sslcert" 8 | spec: 9 | ingressClassName: azure-application-gateway 10 | rules: 11 | - host: app2.kubeoncloud.com 12 | http: 13 | paths: 14 | - path: / 15 | pathType: Prefix 16 | backend: 17 | service: 18 | name: myapp-nginx-clusterip-service 19 | port: 20 | number: 80 21 | -------------------------------------------------------------------------------- /20-AGIC-Backend-SSL-Application/README.md: -------------------------------------------------------------------------------- 1 | # AGIC - Build and Verify Backend SSL Application 2 | 3 | ## Step-01: Introduction 4 | 5 | 6 | ## Step-02: Backend - Create Self-Signed SSL Certificates 7 | ```t 8 | # Change Directory 9 | cd SSL-SelfSigned-Certs 10 | 11 | # Create your backend private key: 12 | openssl genrsa -out backend-ssl.key 2048 13 | 14 | # Create your backend certificate signing request: 15 | openssl req -new -key backend-ssl.key -out backend-ssl.csr -subj "/CN=backend.kubeoncloud.com" 16 | 17 | # Create your backend certificate: 18 | openssl x509 -req -days 7300 -in backend-ssl.csr -signkey backend-ssl.key -out backend-ssl.crt 19 | ``` 20 | 21 | ## Step-03: Create Kubernetes Secret with Backend Cert and Key 22 | ```t 23 | # Change Directory 24 | cd SSL-SelfSigned-Certs 25 | 26 | # Create a Secret that holds your backend certificate and key: 27 | kubectl create secret tls backend-tls-secret --cert backend-ssl.crt --key backend-ssl.key 28 | 29 | # List Secrets 30 | kubectl get secrets 31 | ``` 32 | 33 | ## Step-04: Create Kubernetes Configmap for Nginx Config File 34 | - **File Name:** 01-myapp-configmap.yaml 35 | ```yaml 36 | apiVersion: v1 37 | kind: ConfigMap 38 | metadata: 39 | name: nginx-configfile-cm 40 | data: 41 | default.conf: |- 42 | server { 43 | listen 80 default_server; 44 | listen 443 ssl; 45 | root /usr/share/nginx/html; 46 | index index.html; 47 | ssl_certificate /etc/nginx/ssl/tls.crt; 48 | ssl_certificate_key /etc/nginx/ssl/tls.key; 49 | } 50 | ``` 51 | 52 | ## Step-05: Create Kubernetes Deployment with VolumeMounts and Volumes 53 | - **File Name:** 02-myapp-Deployment.yaml 54 | ```yaml 55 | apiVersion: apps/v1 56 | kind: Deployment 57 | metadata: 58 | name: myapp-nginx-deployment 59 | labels: 60 | app: myapp-nginx 61 | spec: 62 | replicas: 1 63 | selector: 64 | matchLabels: 65 | app: myapp-nginx 66 | template: 67 | metadata: 68 | labels: 69 | app: myapp-nginx 70 | spec: 71 | containers: 72 | - name: myapp-nginx 73 | image: ghcr.io/stacksimplify/kubenginx:1.0.0 74 | ports: 75 | - containerPort: 443 76 | volumeMounts: 77 | - mountPath: /etc/nginx/ssl 78 | name: backend-ssl-certs-volume 79 | - mountPath: /etc/nginx/conf.d 80 | name: nginx-configfile-volume 81 | volumes: 82 | - name: backend-ssl-certs-volume 83 | secret: 84 | secretName: backend-tls-secret 85 | - name: nginx-configfile-volume 86 | configMap: 87 | name: nginx-configfile-cm 88 | ``` 89 | 90 | ## Step-06: Create Kubernetes LoadBalancer Service 91 | - **File Name:** 03-myapp-LoadBalancer-Service.yaml 92 | ```yaml 93 | apiVersion: v1 94 | kind: Service 95 | metadata: 96 | name: myapp-nginx-loadbalancer-service 97 | labels: 98 | app: myapp-nginx 99 | spec: 100 | type: LoadBalancer 101 | selector: 102 | app: myapp-nginx 103 | ports: 104 | - port: 443 105 | targetPort: 443 106 | ``` 107 | 108 | ## Step-07: Deploy and Verify 109 | ```t 110 | # Deploy Application 111 | kubectl deploy -f kube-manifests/ 112 | 113 | # List k8s Deployments 114 | kubectl get deploy 115 | 116 | # List k8s Services 117 | kubectl get svc 118 | 119 | # List k8s Pods 120 | kubectl get pods 121 | 122 | # Verify by connecting to Pod 123 | kubectl exec --stdin --tty -- /bin/bash 124 | kubectl exec --stdin --tty myapp-nginx-deployment-65b8578fcc-6qmpc -- /bin/bash 125 | 126 | # Verify Nginx Config File in container 127 | cd /etc/nginx/conf.d 128 | cat default.conf 129 | 130 | # Verify SSL Certs in Container 131 | cd /etc/nginx/ssl/ 132 | cat tls.key 133 | cat tls.crt 134 | 135 | # Decode SSL Cert to verify it is the same SSL cert 136 | https://www.sslshopper.com/certificate-decoder.html 137 | 138 | # Access Application 139 | kubectl get svc 140 | https:// 141 | Observation: 142 | 1. Review SSL Certificate CN Name 143 | 2. It should match with what we created. 144 | 3. In our case it is "backend.kubeoncloud.com" 145 | ``` 146 | 147 | ## Step-08: Clean-Up 148 | ```t 149 | # Delete Application 150 | kubectl delete -f kube-manifests/ 151 | 152 | # DONT Delete Kubernetes Secret 153 | kubectl get secrets 154 | Kubernetes Secret Name: backend-tls-secret 155 | Observation: 156 | 1. We will use this secret in next demo "E2E Ingress SSL" 157 | ``` 158 | -------------------------------------------------------------------------------- /20-AGIC-Backend-SSL-Application/SSL-SelfSigned-Certs/backend-ssl.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICyzCCAbMCFEBBPo5rW7b9dpQsFlSTVh35qQ/CMA0GCSqGSIb3DQEBCwUAMCIx 3 | IDAeBgNVBAMMF2JhY2tlbmQua3ViZW9uY2xvdWQuY29tMB4XDTIzMDkyNDA0MzYw 4 | MloXDTQzMDkxOTA0MzYwMlowIjEgMB4GA1UEAwwXYmFja2VuZC5rdWJlb25jbG91 5 | ZC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIYFqWutughSr6 6 | gCBnFpVYjvRvnNEcTSou6k/pLkCn5iP06mSFArCMbHqxykQKtnuchoWkn6Oq037H 7 | wWv8td1cmWyhMfhdrjm2Ga8VS6jyZ3rArIeoEQinCEEyefIkCYMnlbVePAv9HPSK 8 | NUZmZr2ylRuRrvM1KTVT1No/jFAaBXAOETTNmYFeTRNLvQwJtMCHUTglDnoORBNC 9 | eqDacuc0dlftdMSirPK2VS13xS/cw5TxxhUAOBGOXCvysVta2b9gD582R/B0ONCT 10 | Xja9f91StE9qwQvUwVSRDh/HboUL4AG/sol7ibu60Ce2QlU4spGepqYw69dA0UYY 11 | im8+7m3TAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAHd9SZOKS09HNUUT1cm4b/qC 12 | IzLsnQVBnLmIzfPPvfp2Hgj0NJfkWqNrrwNYGhug9+PaWae33pmfbO2qGxdSh8Dr 13 | w3VZkaYdSze8l7B3WrKzfliZ1rBXLtGEjvsw02nXDpmcTGNHMIS45ilsJ0TpXLTO 14 | 9/1TS7lXwaVzo86mPiw4BZoEQ830QAMvdLfAlb1UkoLSrY0ya65ZZau/NY58BJAL 15 | BaPeJx0uh0f7G7R8ILiCT8bPgcW5XHgjn6Abph7gJ4aa71UEkPLXQEWfLg4j/C68 16 | 8QHTut/vVim9MmMWErlpZcgNk+YmBZHEvsQg8MzvbkHjK/EXAnA9lN5ovtqeD78= 17 | -----END CERTIFICATE----- 18 | -------------------------------------------------------------------------------- /20-AGIC-Backend-SSL-Application/SSL-SelfSigned-Certs/backend-ssl.csr: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE REQUEST----- 2 | MIICZzCCAU8CAQAwIjEgMB4GA1UEAwwXYmFja2VuZC5rdWJlb25jbG91ZC5jb20w 3 | ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIYFqWutughSr6gCBnFpVY 4 | jvRvnNEcTSou6k/pLkCn5iP06mSFArCMbHqxykQKtnuchoWkn6Oq037HwWv8td1c 5 | mWyhMfhdrjm2Ga8VS6jyZ3rArIeoEQinCEEyefIkCYMnlbVePAv9HPSKNUZmZr2y 6 | lRuRrvM1KTVT1No/jFAaBXAOETTNmYFeTRNLvQwJtMCHUTglDnoORBNCeqDacuc0 7 | dlftdMSirPK2VS13xS/cw5TxxhUAOBGOXCvysVta2b9gD582R/B0ONCTXja9f91S 8 | tE9qwQvUwVSRDh/HboUL4AG/sol7ibu60Ce2QlU4spGepqYw69dA0UYYim8+7m3T 9 | AgMBAAGgADANBgkqhkiG9w0BAQsFAAOCAQEAa04C/nQ04AVoj2MJRT9U2RcYVa7R 10 | NxIM7s9FOzSfZ4GE3yUfaoz4m+QkGALz0GEYxtyTj4W3jcLwbkQUC8+vlfPFYf6s 11 | gWuNHMBlCHdA29Hlkb1KHYBR1tj7ZhN22+xHYowimSUi4xoJtU0vOu7OBZZM3a39 12 | im26N3v8cnmSeCkWb95hxTo4r2JKR8/k2d3qgff5ewLZ92y9BAAE/WjLG4qtSacj 13 | TMBIzx/2bGzr1pbd8Y/7Fnrc4DhXjjfPbLr2pevWyps8o/HZZTGDL+l1UQztTobq 14 | JetLKxUEVjL1+A6oQ5b9YpTkeEHle3FOdkc0mXk1tvPLiwtpGp9ObsdMGw== 15 | -----END CERTIFICATE REQUEST----- 16 | -------------------------------------------------------------------------------- /20-AGIC-Backend-SSL-Application/SSL-SelfSigned-Certs/backend-ssl.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDIYFqWutughSr6 3 | gCBnFpVYjvRvnNEcTSou6k/pLkCn5iP06mSFArCMbHqxykQKtnuchoWkn6Oq037H 4 | wWv8td1cmWyhMfhdrjm2Ga8VS6jyZ3rArIeoEQinCEEyefIkCYMnlbVePAv9HPSK 5 | NUZmZr2ylRuRrvM1KTVT1No/jFAaBXAOETTNmYFeTRNLvQwJtMCHUTglDnoORBNC 6 | eqDacuc0dlftdMSirPK2VS13xS/cw5TxxhUAOBGOXCvysVta2b9gD582R/B0ONCT 7 | Xja9f91StE9qwQvUwVSRDh/HboUL4AG/sol7ibu60Ce2QlU4spGepqYw69dA0UYY 8 | im8+7m3TAgMBAAECggEAIfAP58+mOz3S1bK1ykAM837i77SDxmNbba7J8hifYtCb 9 | 7nN0qwKVnHMTJOG5PIdD0HMIV6WiNuCzbGnaPGchIvnpaDPqeRN1Ot6GxPiXmNbl 10 | 95RBNboM2R2QzVfSJ0BlMmMs4NUSwsAQuwfi8J0eLA0NKlOTZcGhAp3eiTzepElS 11 | PJB8ATXBDC3tMyKoalj0OBxbTui7gBL32DQprsyjxsBeKHWWowjjGQxIRDuOMOrQ 12 | cdakAanRiq4aYl1O8jtQnHdUGVjOZTnszRN35hFTthX0wgmdv7ODda+vNo4m16MW 13 | bE89dc63MCALdhiSX2HhFSP41wvZJ4ZLqSkbCgUqoQKBgQD+w2TkmmVWgi10r7qy 14 | raOUtAlOu3hArOHfsP8iGU+NIQTNTVMy0k9yPdaztXlFi2BQqmsGKqxNYtsKANmo 15 | S8Vp1nMFFPuK00ePHbihHkuSz3Gr4XTHPzGAO5r31NSeuKOMkh8tSHfgZjD3fsNw 16 | JnsPL8vNEa6kfCYTmj7V1DzA1wKBgQDJWV7miDhERuIONcwF2SEp9Km2afRzS9T3 17 | EeW56X2zHQjQcP7+7xih6eLocyXxmE56ggyZ2e6WN4Figq+KHAjr6eyp+1yjquX0 18 | RHhbvoqwveTv69xe8B/aw4bI9+uaXDt82U+bLwGwjV/pr8q3IW7CBHa1cWuBGthT 19 | zxcyBaxPZQKBgQC/f0QhieTOh/9/DHB7yoWBS2sLoWMcylbme/brPLdNUBp577uw 20 | IeHR76WpY6mKmt+FAvR7qCvn53zaIhV5qar0iVvf4AvMKFBLxX14rnsEGaZKGqha 21 | 9KdSynsL+xDvVb6p9VQ2B5kENgxsnP5vGJ27pqO8u6PYw/EjHvhIZsZb9QKBgBVX 22 | 3uJrACPkq6O7+iOIj6Zl4/ONKbdrC2khQYvCf2uUIVIPGEinyaGoLEBdrGD+txrv 23 | XCyW2F6eBZ4OolLug9eWFVszZO+IdxW8iFGZUhRIHNN92f9KTuYeodP9y8CyFDA4 24 | zOJzSieP5OHdm4xsA9SXKoozOqUV1maT5i6MQWatAoGBAL+Yp7wkYjoF5JYTV5IU 25 | 8NbaSQ7zOMI96NRYQFjTcZRbKRh5gSmxZtE31P9Yt3oJWXxeF/PALtXxFRdnjplH 26 | xGNzHlXhyE2JguUNrOePz1TA9UpLXnujiuKbEAIRkhSd5iLb2rC1k5Lil8XDp6S2 27 | Fbjznfid0h9dv2qlDo+4zMjy 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /20-AGIC-Backend-SSL-Application/kube-manifests/01-myapp-configmap.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: nginx-configfile-cm 5 | data: 6 | default.conf: |- 7 | server { 8 | listen 80 default_server; 9 | listen 443 ssl; 10 | root /usr/share/nginx/html; 11 | index index.html; 12 | ssl_certificate /etc/nginx/ssl/tls.crt; 13 | ssl_certificate_key /etc/nginx/ssl/tls.key; 14 | } 15 | 16 | -------------------------------------------------------------------------------- /20-AGIC-Backend-SSL-Application/kube-manifests/02-myapp-Deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: myapp-nginx-deployment 5 | labels: 6 | app: myapp-nginx 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: myapp-nginx 12 | template: 13 | metadata: 14 | labels: 15 | app: myapp-nginx 16 | spec: 17 | containers: 18 | - name: myapp-nginx 19 | image: ghcr.io/stacksimplify/kubenginx:1.0.0 20 | ports: 21 | - containerPort: 443 22 | volumeMounts: 23 | - mountPath: /etc/nginx/ssl 24 | name: backend-ssl-certs-volume 25 | - mountPath: /etc/nginx/conf.d 26 | name: nginx-configfile-volume 27 | volumes: 28 | - name: backend-ssl-certs-volume 29 | secret: 30 | secretName: backend-tls-secret 31 | - name: nginx-configfile-volume 32 | configMap: 33 | name: nginx-configfile-cm 34 | -------------------------------------------------------------------------------- /20-AGIC-Backend-SSL-Application/kube-manifests/03-myapp-LoadBalancer-Service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: myapp-nginx-loadbalancer-service 5 | labels: 6 | app: myapp-nginx 7 | spec: 8 | type: LoadBalancer 9 | selector: 10 | app: myapp-nginx 11 | ports: 12 | - port: 443 13 | targetPort: 443 14 | -------------------------------------------------------------------------------- /21-AGIC-End2End-SSL/SSL-SelfSigned-Certs/backend-ssl.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICyzCCAbMCFEBBPo5rW7b9dpQsFlSTVh35qQ/CMA0GCSqGSIb3DQEBCwUAMCIx 3 | IDAeBgNVBAMMF2JhY2tlbmQua3ViZW9uY2xvdWQuY29tMB4XDTIzMDkyNDA0MzYw 4 | MloXDTQzMDkxOTA0MzYwMlowIjEgMB4GA1UEAwwXYmFja2VuZC5rdWJlb25jbG91 5 | ZC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIYFqWutughSr6 6 | gCBnFpVYjvRvnNEcTSou6k/pLkCn5iP06mSFArCMbHqxykQKtnuchoWkn6Oq037H 7 | wWv8td1cmWyhMfhdrjm2Ga8VS6jyZ3rArIeoEQinCEEyefIkCYMnlbVePAv9HPSK 8 | NUZmZr2ylRuRrvM1KTVT1No/jFAaBXAOETTNmYFeTRNLvQwJtMCHUTglDnoORBNC 9 | eqDacuc0dlftdMSirPK2VS13xS/cw5TxxhUAOBGOXCvysVta2b9gD582R/B0ONCT 10 | Xja9f91StE9qwQvUwVSRDh/HboUL4AG/sol7ibu60Ce2QlU4spGepqYw69dA0UYY 11 | im8+7m3TAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAHd9SZOKS09HNUUT1cm4b/qC 12 | IzLsnQVBnLmIzfPPvfp2Hgj0NJfkWqNrrwNYGhug9+PaWae33pmfbO2qGxdSh8Dr 13 | w3VZkaYdSze8l7B3WrKzfliZ1rBXLtGEjvsw02nXDpmcTGNHMIS45ilsJ0TpXLTO 14 | 9/1TS7lXwaVzo86mPiw4BZoEQ830QAMvdLfAlb1UkoLSrY0ya65ZZau/NY58BJAL 15 | BaPeJx0uh0f7G7R8ILiCT8bPgcW5XHgjn6Abph7gJ4aa71UEkPLXQEWfLg4j/C68 16 | 8QHTut/vVim9MmMWErlpZcgNk+YmBZHEvsQg8MzvbkHjK/EXAnA9lN5ovtqeD78= 17 | -----END CERTIFICATE----- 18 | -------------------------------------------------------------------------------- /21-AGIC-End2End-SSL/SSL-SelfSigned-Certs/backend-ssl.csr: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE REQUEST----- 2 | MIICZzCCAU8CAQAwIjEgMB4GA1UEAwwXYmFja2VuZC5rdWJlb25jbG91ZC5jb20w 3 | ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIYFqWutughSr6gCBnFpVY 4 | jvRvnNEcTSou6k/pLkCn5iP06mSFArCMbHqxykQKtnuchoWkn6Oq037HwWv8td1c 5 | mWyhMfhdrjm2Ga8VS6jyZ3rArIeoEQinCEEyefIkCYMnlbVePAv9HPSKNUZmZr2y 6 | lRuRrvM1KTVT1No/jFAaBXAOETTNmYFeTRNLvQwJtMCHUTglDnoORBNCeqDacuc0 7 | dlftdMSirPK2VS13xS/cw5TxxhUAOBGOXCvysVta2b9gD582R/B0ONCTXja9f91S 8 | tE9qwQvUwVSRDh/HboUL4AG/sol7ibu60Ce2QlU4spGepqYw69dA0UYYim8+7m3T 9 | AgMBAAGgADANBgkqhkiG9w0BAQsFAAOCAQEAa04C/nQ04AVoj2MJRT9U2RcYVa7R 10 | NxIM7s9FOzSfZ4GE3yUfaoz4m+QkGALz0GEYxtyTj4W3jcLwbkQUC8+vlfPFYf6s 11 | gWuNHMBlCHdA29Hlkb1KHYBR1tj7ZhN22+xHYowimSUi4xoJtU0vOu7OBZZM3a39 12 | im26N3v8cnmSeCkWb95hxTo4r2JKR8/k2d3qgff5ewLZ92y9BAAE/WjLG4qtSacj 13 | TMBIzx/2bGzr1pbd8Y/7Fnrc4DhXjjfPbLr2pevWyps8o/HZZTGDL+l1UQztTobq 14 | JetLKxUEVjL1+A6oQ5b9YpTkeEHle3FOdkc0mXk1tvPLiwtpGp9ObsdMGw== 15 | -----END CERTIFICATE REQUEST----- 16 | -------------------------------------------------------------------------------- /21-AGIC-End2End-SSL/SSL-SelfSigned-Certs/backend-ssl.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDIYFqWutughSr6 3 | gCBnFpVYjvRvnNEcTSou6k/pLkCn5iP06mSFArCMbHqxykQKtnuchoWkn6Oq037H 4 | wWv8td1cmWyhMfhdrjm2Ga8VS6jyZ3rArIeoEQinCEEyefIkCYMnlbVePAv9HPSK 5 | NUZmZr2ylRuRrvM1KTVT1No/jFAaBXAOETTNmYFeTRNLvQwJtMCHUTglDnoORBNC 6 | eqDacuc0dlftdMSirPK2VS13xS/cw5TxxhUAOBGOXCvysVta2b9gD582R/B0ONCT 7 | Xja9f91StE9qwQvUwVSRDh/HboUL4AG/sol7ibu60Ce2QlU4spGepqYw69dA0UYY 8 | im8+7m3TAgMBAAECggEAIfAP58+mOz3S1bK1ykAM837i77SDxmNbba7J8hifYtCb 9 | 7nN0qwKVnHMTJOG5PIdD0HMIV6WiNuCzbGnaPGchIvnpaDPqeRN1Ot6GxPiXmNbl 10 | 95RBNboM2R2QzVfSJ0BlMmMs4NUSwsAQuwfi8J0eLA0NKlOTZcGhAp3eiTzepElS 11 | PJB8ATXBDC3tMyKoalj0OBxbTui7gBL32DQprsyjxsBeKHWWowjjGQxIRDuOMOrQ 12 | cdakAanRiq4aYl1O8jtQnHdUGVjOZTnszRN35hFTthX0wgmdv7ODda+vNo4m16MW 13 | bE89dc63MCALdhiSX2HhFSP41wvZJ4ZLqSkbCgUqoQKBgQD+w2TkmmVWgi10r7qy 14 | raOUtAlOu3hArOHfsP8iGU+NIQTNTVMy0k9yPdaztXlFi2BQqmsGKqxNYtsKANmo 15 | S8Vp1nMFFPuK00ePHbihHkuSz3Gr4XTHPzGAO5r31NSeuKOMkh8tSHfgZjD3fsNw 16 | JnsPL8vNEa6kfCYTmj7V1DzA1wKBgQDJWV7miDhERuIONcwF2SEp9Km2afRzS9T3 17 | EeW56X2zHQjQcP7+7xih6eLocyXxmE56ggyZ2e6WN4Figq+KHAjr6eyp+1yjquX0 18 | RHhbvoqwveTv69xe8B/aw4bI9+uaXDt82U+bLwGwjV/pr8q3IW7CBHa1cWuBGthT 19 | zxcyBaxPZQKBgQC/f0QhieTOh/9/DHB7yoWBS2sLoWMcylbme/brPLdNUBp577uw 20 | IeHR76WpY6mKmt+FAvR7qCvn53zaIhV5qar0iVvf4AvMKFBLxX14rnsEGaZKGqha 21 | 9KdSynsL+xDvVb6p9VQ2B5kENgxsnP5vGJ27pqO8u6PYw/EjHvhIZsZb9QKBgBVX 22 | 3uJrACPkq6O7+iOIj6Zl4/ONKbdrC2khQYvCf2uUIVIPGEinyaGoLEBdrGD+txrv 23 | XCyW2F6eBZ4OolLug9eWFVszZO+IdxW8iFGZUhRIHNN92f9KTuYeodP9y8CyFDA4 24 | zOJzSieP5OHdm4xsA9SXKoozOqUV1maT5i6MQWatAoGBAL+Yp7wkYjoF5JYTV5IU 25 | 8NbaSQ7zOMI96NRYQFjTcZRbKRh5gSmxZtE31P9Yt3oJWXxeF/PALtXxFRdnjplH 26 | xGNzHlXhyE2JguUNrOePz1TA9UpLXnujiuKbEAIRkhSd5iLb2rC1k5Lil8XDp6S2 27 | Fbjznfid0h9dv2qlDo+4zMjy 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /21-AGIC-End2End-SSL/SSL-SelfSigned-Certs/frontend-ingress.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICzTCCAbUCFEOgqqWFHznKs+lNWac1dVK9Zui4MA0GCSqGSIb3DQEBCwUAMCMx 3 | ITAfBgNVBAMMGGZyb250ZW5kLmt1YmVvbmNsb3VkLmNvbTAeFw0yMzA5MjQwNTE4 4 | MjFaFw00MzA5MTkwNTE4MjFaMCMxITAfBgNVBAMMGGZyb250ZW5kLmt1YmVvbmNs 5 | b3VkLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAIOEoU+8BPEf 6 | GBrmZlpNCDw09lD8XsnPnTHEep6TavyHdf452G89v7DOIg/1U8wxmdYG813b3ZZy 7 | 7nyh18TWcO2RWVFcr8cMBKCXXgRU1wCuDsj72ODgNV2bNxgD0h+OA4tCVsnvNy2h 8 | ecrvTHBDh/VBLvkFpJa/Adezf8WjIn33rJ7+R7PaBNvIe/GNOTC0OX+DrYpSWnNV 9 | M3au5hI1aGYLt+R6mowxrcIvNMGAv/ho94eY7iJOIO2slHgIbXZBw3rtfRRcNF7n 10 | 4tgSaX2SHnCio39Uc+sjt7nI2gzrOI1cbgdvlgrCuAOF7vTDUFzFEl4aL3Jh1AoP 11 | KkjsbsYyatECAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAJenO29Pk2CpRTg9oN+cE 12 | 5F4wVSY37yS2W236AzQ2rSTlB/sK8cgZAOOjECAv4wrv6cKayhU+X655nInJYJhw 13 | LxTXxEluwut1fJ/ZluGlon4rxPg+xXTtTdCHQjkUcjOhOrdkwLyykZaDFtlN/Qm+ 14 | Db3Mq7yA4kZC2hPp5n8dl0M27aIcx/MBRcxj8EJeChZWZG4wACtqFNZTG7FtVcif 15 | KVfnco0FMfXK6ey/c1EsTZpcg4gsXGxWqdp0iZI35MTogr9xO7uiT5SKzyFY2QB0 16 | IOaXLaMTB/u9PFp41GP/q+keaKjZdJeLFGeo+68HYOJxk584sZL38YxjDnH46142 17 | EA== 18 | -----END CERTIFICATE----- 19 | -------------------------------------------------------------------------------- /21-AGIC-End2End-SSL/SSL-SelfSigned-Certs/frontend-ingress.csr: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE REQUEST----- 2 | MIICaDCCAVACAQAwIzEhMB8GA1UEAwwYZnJvbnRlbmQua3ViZW9uY2xvdWQuY29t 3 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAg4ShT7wE8R8YGuZmWk0I 4 | PDT2UPxeyc+dMcR6npNq/Id1/jnYbz2/sM4iD/VTzDGZ1gbzXdvdlnLufKHXxNZw 5 | 7ZFZUVyvxwwEoJdeBFTXAK4OyPvY4OA1XZs3GAPSH44Di0JWye83LaF5yu9McEOH 6 | 9UEu+QWklr8B17N/xaMiffesnv5Hs9oE28h78Y05MLQ5f4OtilJac1Uzdq7mEjVo 7 | Zgu35HqajDGtwi80wYC/+Gj3h5juIk4g7ayUeAhtdkHDeu19FFw0Xufi2BJpfZIe 8 | cKKjf1Rz6yO3ucjaDOs4jVxuB2+WCsK4A4Xu9MNQXMUSXhovcmHUCg8qSOxuxjJq 9 | 0QIDAQABoAAwDQYJKoZIhvcNAQELBQADggEBAD405hendV34FP0gCe136mz3Jh4I 10 | J08htxDR182aK1yTr92J9jwr6WAnC4Y8G4PlKseIewurj5/WGs8p9YLueyDRu1Zk 11 | vcfN8Rxc512JpNnxBZdn8+wmMCZw4wueto0Y8Yhvg7ZxxibaxlcnOkUnEjkv1YT+ 12 | wmdVhExJ5OUz+YrZ78fqKbElmMecOvlEPJn72htiNEWgnZWh8OpgLsJyupirmqG5 13 | sIIDHNg1HFdg/HGwsFlR+LaiJsffF4dBdJ1cDmxIqBk3sJTsKl0QS2n6Pfeeu+ow 14 | B+slL0gBx7/pKpfpEl0D6gpz8UREtziYhDKoEV0K4GfYFsX7nx3hBaCaN9c= 15 | -----END CERTIFICATE REQUEST----- 16 | -------------------------------------------------------------------------------- /21-AGIC-End2End-SSL/SSL-SelfSigned-Certs/frontend-ingress.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCDhKFPvATxHxga 3 | 5mZaTQg8NPZQ/F7Jz50xxHqek2r8h3X+OdhvPb+wziIP9VPMMZnWBvNd292Wcu58 4 | odfE1nDtkVlRXK/HDASgl14EVNcArg7I+9jg4DVdmzcYA9IfjgOLQlbJ7zctoXnK 5 | 70xwQ4f1QS75BaSWvwHXs3/FoyJ996ye/kez2gTbyHvxjTkwtDl/g62KUlpzVTN2 6 | ruYSNWhmC7fkepqMMa3CLzTBgL/4aPeHmO4iTiDtrJR4CG12QcN67X0UXDRe5+LY 7 | Eml9kh5woqN/VHPrI7e5yNoM6ziNXG4Hb5YKwrgDhe70w1BcxRJeGi9yYdQKDypI 8 | 7G7GMmrRAgMBAAECggEAIyK5R8h214YTlggsmv5Ob2tEzPEHT8oP+F5B1gCTSgDU 9 | hIUmrd1ky1Lepb3IU9qCezvjI5WcFtgAn7pLHzKc+9LjdkmZSkeLKu4Vd3nE8NEP 10 | cSFbWQR9LVNMvjUzGywBBWDFN/CZIK8tjwosNSfNeDegWXXo+T7xOpOhVIcXLWiu 11 | IE1nQr2LqAJYyvuhl+TWgD/3oA3sg0sid0E7ZyZ7o2oqdd5olyEqtrd0/tAc2k01 12 | vxYYkSmICZcXOV2QWTTiDOg+AyRV2KAi40eAqJ30GZAPEjQAGUQp624P3B9XDVJk 13 | 5lFYtq5LMFqGzZyTFwc0nl2kgVyKSWv/fK+PjEyAqwKBgQC5seV7Yya0+rS3K0na 14 | wGplIuQBp1X8odm+aMEpMO6A9JciM1MP/O9tOIRbmV+0A7OZXxgl8xjfuX9Bm/FT 15 | hizY3o/76ATPBCnU6lnDqpr7aWoems4CYjzEYw05R/fP9H6sM3KhFeZkzSNYn91j 16 | ulDKcST4S/y4SV3C9mZmWbxjCwKBgQC1T8E6rQ1u1uDyg04k0Kb2aBg/zBDhIWpp 17 | gUvl1EIaoIv1f6mmp3m6bmzSJizwWDEo5wmomwZ6SqQcd++vnwRTGzAGkunJRzVX 18 | 7djf1x+guK/BV2AyVj4C6MedBgcue1MIX6JY3zTFsGfKSXkm/MRHuii4sFct5gR2 19 | UkCbU9/TEwKBgHY6W39pq3VCwdh1STprk9H8muqqncaRTc87ZvBQ5SlZkPgHcXUW 20 | d2I0v6CKUDKOwMR/lSJkWovm0Kz3GnkxTlBts4KRQK6FWhTjeG9pqe80OIpvyYYf 21 | Ac2PuxWjSpYudpAw2WTSSrQXH9AHSK98KoAZ9Y3Y43h5zaaZtqynqZftAoGAY32i 22 | MIppRpsO0MSQis8b7zZrqAZYdNEbTU2v0ivJIkdaxZoKA/L+bvjNKfvcyP3768/r 23 | kuOOiGiQ6TY/BgWiH+BZWCIhu1shwGA5k4q+RjlR6CwEE1sTqBEIB/gY1L7Db2La 24 | +R1yHdCRA4WRv30QT7OtSLsq+3qulCbKYPGDbpUCgYAF0ncxWC0GXvg3tvjrqyXR 25 | jSoZRHhPAaxEI32X4JS/aFeuZYq3lewaf8+L3qO/IqGq+ySugfwqvhrKInYDQPRW 26 | eNsGZH9y18i9ZobIuAGjEgFzFlqe6C23PAVlJXnoq5UA7mNBP2zMIkTcVc/WaIF2 27 | OX+uLfWfyOdyewcQ0B7J+g== 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /21-AGIC-End2End-SSL/kube-manifests/01-myapp-configmap.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: nginx-configfile-cm 5 | data: 6 | default.conf: |- 7 | server { 8 | listen 80 default_server; 9 | listen 443 ssl; 10 | root /usr/share/nginx/html; 11 | index index.html; 12 | ssl_certificate /etc/nginx/ssl/tls.crt; 13 | ssl_certificate_key /etc/nginx/ssl/tls.key; 14 | } 15 | 16 | -------------------------------------------------------------------------------- /21-AGIC-End2End-SSL/kube-manifests/02-myapp-Deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: myapp-nginx-deployment 5 | labels: 6 | app: myapp-nginx 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: myapp-nginx 12 | template: 13 | metadata: 14 | labels: 15 | app: myapp-nginx 16 | spec: 17 | containers: 18 | - name: myapp-nginx 19 | image: ghcr.io/stacksimplify/kubenginx:1.0.0 20 | ports: 21 | - containerPort: 443 22 | volumeMounts: 23 | - mountPath: /etc/nginx/ssl 24 | name: backend-ssl-certs-volume 25 | - mountPath: /etc/nginx/conf.d 26 | name: nginx-configfile-volume 27 | volumes: 28 | - name: backend-ssl-certs-volume 29 | secret: 30 | secretName: backend-tls-secret 31 | - name: nginx-configfile-volume 32 | configMap: 33 | name: nginx-configfile-cm 34 | -------------------------------------------------------------------------------- /21-AGIC-End2End-SSL/kube-manifests/03-myapp-ClusterIP-Service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: myapp-nginx-clusterip-service 5 | labels: 6 | app: myapp-nginx 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | app: myapp-nginx 11 | ports: 12 | - port: 443 13 | targetPort: 443 14 | -------------------------------------------------------------------------------- /21-AGIC-End2End-SSL/kube-manifests/04-Ingress-e2e-ssl.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: ingress-e2e-ssl 5 | annotations: 6 | appgw.ingress.kubernetes.io/ssl-redirect: "true" 7 | # Backend Annotations 8 | appgw.ingress.kubernetes.io/backend-hostname: "backend.kubeoncloud.com" # Optional 9 | appgw.ingress.kubernetes.io/backend-protocol: "https" 10 | appgw.ingress.kubernetes.io/appgw-trusted-root-certificate: "backend-tls" 11 | spec: 12 | ingressClassName: azure-application-gateway 13 | # SSL Certs - Associate using Kubernetes Secrets 14 | tls: 15 | - secretName: frontend-tls-secret 16 | hosts: 17 | - frontend.kubeoncloud.com 18 | rules: 19 | - host: frontend.kubeoncloud.com 20 | http: 21 | paths: 22 | - path: / 23 | pathType: Prefix 24 | backend: 25 | service: 26 | name: myapp-nginx-clusterip-service 27 | port: 28 | number: 443 29 | -------------------------------------------------------------------------------- /22-AGIC-SSL-with-LetsEncrypt/01-CertManager-ClusterIssuer/cluster-issuer.yml: -------------------------------------------------------------------------------- 1 | apiVersion: cert-manager.io/v1 2 | kind: ClusterIssuer 3 | metadata: 4 | name: letsencrypt 5 | spec: 6 | acme: 7 | # The ACME server URL 8 | server: https://acme-v02.api.letsencrypt.org/directory 9 | # Email address used for ACME registration 10 | email: dkalyanreddy@gmail.com 11 | # Name of a secret used to store the ACME account private key 12 | privateKeySecretRef: 13 | name: letsencrypt 14 | solvers: 15 | - http01: 16 | ingress: 17 | class: azure/application-gateway -------------------------------------------------------------------------------- /22-AGIC-SSL-with-LetsEncrypt/02-kube-manifests/01-NginxApp1-Deployment.yaml: -------------------------------------------------------------------------------- 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: ghcr.io/stacksimplify/kube-nginxapp1:1.0.0 20 | ports: 21 | - containerPort: 80 22 | 23 | -------------------------------------------------------------------------------- /22-AGIC-SSL-with-LetsEncrypt/02-kube-manifests/02-NginxApp1-ClusterIP-Service.yaml: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /22-AGIC-SSL-with-LetsEncrypt/02-kube-manifests/03-NginxApp2-Deployment.yaml: -------------------------------------------------------------------------------- 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: ghcr.io/stacksimplify/kube-nginxapp2:1.0.0 20 | ports: 21 | - containerPort: 80 22 | -------------------------------------------------------------------------------- /22-AGIC-SSL-with-LetsEncrypt/02-kube-manifests/04-NginxApp2-ClusterIP-Service.yaml: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /22-AGIC-SSL-with-LetsEncrypt/02-kube-manifests/05-Ingress-SSL-LetsEncrypt.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: ingress-ssl-letsencrypt 5 | annotations: 6 | appgw.ingress.kubernetes.io/ssl-redirect: "true" 7 | cert-manager.io/cluster-issuer: letsencrypt 8 | spec: 9 | ingressClassName: azure-application-gateway 10 | tls: 11 | - secretName: sapp1-kubeoncloud-secret 12 | hosts: 13 | - sapp1.kubeoncloud.com 14 | - secretName: sapp2-kubeoncloud-secret 15 | hosts: 16 | - sapp2.kubeoncloud.com 17 | rules: 18 | - host: sapp1.kubeoncloud.com 19 | http: 20 | paths: 21 | - path: / 22 | pathType: Prefix 23 | backend: 24 | service: 25 | name: app1-nginx-clusterip-service 26 | port: 27 | number: 80 28 | - host: sapp2.kubeoncloud.com 29 | http: 30 | paths: 31 | - path: / 32 | pathType: Prefix 33 | backend: 34 | service: 35 | name: app2-nginx-clusterip-service 36 | port: 37 | number: 80 38 | 39 | -------------------------------------------------------------------------------- /23-AGIC-WAF-OWASP/README.md: -------------------------------------------------------------------------------- 1 | # AGIC WAF - OWASP Default Policies 2 | 3 | ## Step-01: Introduction 4 | - Enable WAFV2 for Application Gateway 5 | - Enable default OWASP rules in WAFV2 6 | - Enable Application Gateway Logs (Send to Log Analytics Workspace) 7 | - Deploy simple k8s Application 8 | - Verify if default OWASP rules working as expected with WAF for our application 9 | - Verify Application Gateway Access and WAF Firewall logs using Queries 10 | 11 | ## Step-02: Enable WAF on Azure Application Gateway 12 | ```t 13 | # Enable WAF on Azure Application Gateway 14 | Go to Portal -> Application Gateway -> agic-appgw -> Settings 15 | 16 | # AppGW Configuration 17 | Tier: WAF V2 18 | Click on Save 19 | 20 | # AppGW Web Application Firewall 21 | ## Configure Tab 22 | Tier: WAF V2 23 | WAF Status: Enabled 24 | WAF Mode: Prevention 25 | 26 | ## Rules Tab 27 | Rules Set: OWASP 3.2 28 | Click on Save 29 | ``` 30 | 31 | ## Step-03: Create Log Analytics Workspace 32 | ```t 33 | # Create Log Analytics Workspace 34 | 1. Go to Portal -> Log Analytics Workspaces -> create 35 | 2. Resource group: agicdemo 36 | 3. Name: agic-log-analytics-workspace 37 | 4. Region: East US 38 | 5. Review + Create 39 | ``` 40 | 41 | ## Step-04: Enable Diagnostic Settings in Azure Application Gateway 42 | ```t 43 | # Enable Diagnostic Settings in AppGW 44 | 1. Go to Portal -> AppGW -> agic-appgw -> Monitoring -> Diagnostic settings 45 | 2. Category groups: all logs 46 | 3. Metrics: All Metrics 47 | 4. Destination details: Send to Log Analytics workspace 48 | 5. Subscription: YOUR-SUBSCRIPTIOn 49 | 6. Log Analytics workspace: agic-log-analytics-workspace 50 | 7. Click on "Save" 51 | ``` 52 | 53 | ## Step-05: Review Kubernetes Manifests 54 | - 01-NginxApp1-Deployment.yaml 55 | - 02-NginxApp1-ClusterIP-Service.yaml 56 | - 03-Ingress-WAF.yaml 57 | 58 | ## Step-06: Deploy Kubernetes Manifests and Verify 59 | ```t 60 | # Change Directory 61 | cd 23-AGIC-WAF-OWASP 62 | 63 | # Deploy Kubernetes Manifests 64 | kubectl apply -f kube-manifests/ 65 | 66 | # List Deployments 67 | kubectl get deploy 68 | 69 | # List Pods 70 | kubectl get pods 71 | 72 | # List Services 73 | kubectl get svc 74 | 75 | # List Ingress Services 76 | kubectl get ingress 77 | 78 | # Describe Ingress Service 79 | kubectl describe ingress ingress-waf 80 | 81 | # Verify external-dns Controller logs 82 | kubectl logs -f $(kubectl get po | egrep -o 'external-dns[A-Za-z0-9-]+') 83 | [or] 84 | kubectl get pods 85 | kubectl logs -f 86 | 87 | # If NO External DNS Installed What we need to do ? 88 | 1. We need to manually add the DNS name in Azure DNS Zones before deploying "kube-manifests" 89 | 2. Get the Public IP from Azure Application Gateway -> agic-appgw -> Overview Tab 90 | 3. Go to DNS Zones -> Add Record set 91 | myapp1.kubeoncloud.com 92 | 93 | # Verify Azure DNS 94 | 1. Go to DNS Zones -> kubeoncloud.com 95 | 2. Review the new DNS record created 96 | ``` 97 | 98 | ## Step-07: Access Application 99 | ```t 100 | # Access Application 101 | http://myapp1.kubeoncloud.com/app1/index.html 102 | Observation: 103 | 1. This should work 104 | 105 | # Access Application (XSS Attack URL) 106 | http://myapp1.kubeoncloud.com/app1/index.html?"" 107 | Observation: 108 | 1. This should throw "403 forbidden" error from "Microsoft-Azure-Application-Gateway/v2" 109 | 2. WAF blocked the XSS Attack, didnt send the request to next level 110 | ``` 111 | 112 | ## Step-08: Verify Application Gateway Logs 113 | - [WAF Log Analytics Queries](https://learn.microsoft.com/en-us/azure/application-gateway/log-analytics) 114 | ```t 115 | # AppGW Logs 116 | 1. Go to Portal -> agic-appgw -> Monitoring -> Logs 117 | 2. Review the logs using below queries 118 | 119 | # Query-1: ApplicationGatewayAccess Log 120 | AzureDiagnostics 121 | | where ResourceType == "APPLICATIONGATEWAYS" and OperationName == "ApplicationGatewayAccess" 122 | 123 | # Query-2: ApplicationGatewayFirewallLog 124 | AzureDiagnostics 125 | | where ResourceProvider == "MICROSOFT.NETWORK" and Category == "ApplicationGatewayFirewallLog" 126 | 127 | Query-3: Matched/Blocked requests by IP 128 | AzureDiagnostics 129 | | where ResourceProvider == "MICROSOFT.NETWORK" and Category == "ApplicationGatewayFirewallLog" 130 | | summarize count() by clientIp_s, bin(TimeGenerated, 1m) 131 | | render timechart 132 | 133 | Query-4: Matched/Blocked requests by URI 134 | AzureDiagnostics 135 | | where ResourceProvider == "MICROSOFT.NETWORK" and Category == "ApplicationGatewayFirewallLog" 136 | | summarize count() by requestUri_s, bin(TimeGenerated, 1m) 137 | | render timechart 138 | ``` 139 | 140 | ## Step-09: Clean-Up 141 | ```t 142 | # Delete Application 143 | kubectl delete -f kube-manifests/ 144 | ``` -------------------------------------------------------------------------------- /23-AGIC-WAF-OWASP/kube-manifests/01-NginxApp1-Deployment.yaml: -------------------------------------------------------------------------------- 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: ghcr.io/stacksimplify/kube-nginxapp1:1.0.0 20 | ports: 21 | - containerPort: 80 22 | 23 | -------------------------------------------------------------------------------- /23-AGIC-WAF-OWASP/kube-manifests/02-NginxApp1-ClusterIP-Service.yaml: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /23-AGIC-WAF-OWASP/kube-manifests/03-Ingress-WAF.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: ingress-waf 5 | spec: 6 | ingressClassName: azure-application-gateway 7 | rules: 8 | - host: myapp1.kubeoncloud.com 9 | http: 10 | paths: 11 | - path: / 12 | pathType: Prefix 13 | backend: 14 | service: 15 | name: app1-nginx-clusterip-service 16 | port: 17 | number: 80 18 | 19 | -------------------------------------------------------------------------------- /24-AGIC-WAF-Policy/01-kube-manifests-scope-RoutePath/01-NginxApp1-Deployment.yaml: -------------------------------------------------------------------------------- 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: ghcr.io/stacksimplify/kube-nginxapp1:1.0.0 20 | ports: 21 | - containerPort: 80 22 | 23 | -------------------------------------------------------------------------------- /24-AGIC-WAF-Policy/01-kube-manifests-scope-RoutePath/02-NginxApp1-ClusterIP-Service.yaml: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /24-AGIC-WAF-Policy/01-kube-manifests-scope-RoutePath/03-Ingress-WAF.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: ingress-waf 5 | annotations: 6 | appgw.ingress.kubernetes.io/waf-policy-for-path: "/subscriptions/82808767-144c-4c66-a320-b30791668b0a/resourceGroups/agicdemo/providers/Microsoft.Network/applicationGatewayWebApplicationFirewallPolicies/myapp1-waf-policy1" 7 | spec: 8 | ingressClassName: azure-application-gateway 9 | rules: 10 | - host: myapp1.kubeoncloud.com 11 | http: 12 | paths: 13 | - path: /app1 14 | pathType: Prefix 15 | backend: 16 | service: 17 | name: app1-nginx-clusterip-service 18 | port: 19 | number: 80 20 | 21 | -------------------------------------------------------------------------------- /24-AGIC-WAF-Policy/02-kube-manifests-scope-listener/01-NginxApp1-Deployment.yaml: -------------------------------------------------------------------------------- 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: ghcr.io/stacksimplify/kube-nginxapp1:1.0.0 20 | ports: 21 | - containerPort: 80 22 | 23 | -------------------------------------------------------------------------------- /24-AGIC-WAF-Policy/02-kube-manifests-scope-listener/02-NginxApp1-ClusterIP-Service.yaml: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /24-AGIC-WAF-Policy/02-kube-manifests-scope-listener/03-Ingress-WAF.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: ingress-waf 5 | annotations: 6 | appgw.ingress.kubernetes.io/waf-policy-for-path: "/subscriptions/82808767-144c-4c66-a320-b30791668b0a/resourceGroups/agicdemo/providers/Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies/myapp1-waf-policy1" 7 | spec: 8 | ingressClassName: azure-application-gateway 9 | rules: 10 | - host: myapp1.kubeoncloud.com 11 | http: 12 | paths: 13 | - path: / 14 | pathType: Prefix 15 | backend: 16 | service: 17 | name: app1-nginx-clusterip-service 18 | port: 19 | number: 80 20 | 21 | -------------------------------------------------------------------------------- /25-AGIC-Private-IP/01-kube-manifests/01-EchoServer-Deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: echoserver-deployment 5 | labels: 6 | app: echoserver 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: echoserver 12 | template: 13 | metadata: 14 | labels: 15 | app: echoserver 16 | spec: 17 | containers: 18 | - name: echoserver 19 | image: k8s.gcr.io/e2e-test-images/echoserver:2.5 20 | ports: 21 | - containerPort: 8080 22 | 23 | -------------------------------------------------------------------------------- /25-AGIC-Private-IP/01-kube-manifests/02-EchoServer-ClusterIP-Service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: echoserver-clusterip-service 5 | labels: 6 | app: echoserver 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | app: echoserver 11 | ports: 12 | - port: 80 13 | targetPort: 8080 14 | -------------------------------------------------------------------------------- /25-AGIC-Private-IP/01-kube-manifests/03-Ingress-privateip.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: ingress-privateip 5 | annotations: 6 | appgw.ingress.kubernetes.io/use-private-ip: "true" 7 | spec: 8 | ingressClassName: azure-application-gateway 9 | rules: 10 | - http: 11 | paths: 12 | - path: / 13 | pathType: Prefix 14 | backend: 15 | service: 16 | name: echoserver-clusterip-service 17 | port: 18 | number: 80 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /25-AGIC-Private-IP/02-kube-manifests-curl/01-curl-pod.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: curl-pod 5 | spec: 6 | containers: 7 | - name: curl 8 | image: curlimages/curl 9 | command: [ "sleep", "600" ] -------------------------------------------------------------------------------- /25-AGIC-Private-IP/README.md: -------------------------------------------------------------------------------- 1 | # AGIC Ingress - Private IP 2 | 3 | ## Step-01: Introduction 4 | - We are going to understand and Implement `private-ip` annotation in Ingress Service 5 | ```yaml 6 | annotations: 7 | appgw.ingress.kubernetes.io/use-private-ip: "true" 8 | ``` 9 | ## Step-02: Configure Private IP in Azure Application Gateway 10 | ```t 11 | # Configure Private IP in Azure Application Gateway 12 | 1. Go to Application Gateway -> agic-appgw -> Settings -> Frontend IP Configurations 13 | 2. Click on "Private" 14 | 3. Name: private-ip-1 15 | 4. Private IP address: 10.225.0.25 16 | 5. Click on "Save" 17 | 18 | # Important Notes: 19 | 1. Private IP selected should be in the range of Azure Application Gateway IP range 20 | 2. In Section-1, during the creation of Application Gateway we used (--appgw-subnet-cidr "10.225.0.0/16"). 21 | 3. So the Private IP we provide should be in the range "10.225.0.0/16" 22 | ``` 23 | 24 | ## Step-03: Review Kubernetes Manifests 25 | - **kube-manifests:** 01-kube-manifests 26 | - 01-EchoServer-Deployment.yaml 27 | - 02-EchoServer-ClusterIP-Service.yaml 28 | - 03-Ingress-privateip.yaml 29 | ```yaml 30 | apiVersion: networking.k8s.io/v1 31 | kind: Ingress 32 | metadata: 33 | name: ingress-privateip 34 | annotations: 35 | appgw.ingress.kubernetes.io/use-private-ip: "true" 36 | spec: 37 | ingressClassName: azure-application-gateway 38 | rules: 39 | - http: 40 | paths: 41 | - path: / 42 | pathType: Prefix 43 | backend: 44 | service: 45 | name: echoserver-clusterip-service 46 | port: 47 | number: 80 48 | ``` 49 | 50 | ## Step-04: Deploy Kubernetes Manifests and Verify 51 | ```t 52 | # Deploy Applications 53 | kubectl apply -f 01-kube-manifests 54 | 55 | # List Deployments 56 | kubectl get deploy 57 | 58 | # List Pods 59 | kubectl get pods 60 | 61 | # List Services 62 | kubectl get svc 63 | 64 | # List Ingress 65 | kubectl get ingress 66 | Observation: 67 | 1. Address will be a private IP 10.225.0.25 68 | 2. Access with AppGW public IP and application is not accessible 69 | 3. This Ingress service is deployed to access only internally with internal private IP 70 | ``` 71 | 72 | ## Step-05: Deploy curl-pod and access the Application using Private IP 73 | ### Step-05-01: Review curl-pod 74 | ```yaml 75 | apiVersion: v1 76 | kind: Pod 77 | metadata: 78 | name: curl-pod 79 | spec: 80 | containers: 81 | - name: curl 82 | image: curlimages/curl 83 | command: [ "sleep", "600" ] 84 | ``` 85 | 86 | ## Step-06: Deploy Curl Pod and Test 87 | ```t 88 | # Deploy curl-pod 89 | kubectl apply -f 02-kube-manifests-curl/ 90 | 91 | # Will open up a terminal session into the container 92 | kubectl exec -it curl-pod -- sh 93 | 94 | # We can now curl external addresses or internal services: 95 | curl http://google.com/ 96 | curl 97 | 98 | # Application Gateway Internal IP 99 | curl http://10.225.0.25/ 100 | ``` 101 | 102 | ## Step-07: Clean-Up 103 | ```t 104 | # Delete Applications 105 | kubectl delete -f 01-kube-manifests 106 | kubectl delete -f 02-kube-manifests-curl 107 | ``` -------------------------------------------------------------------------------- /26-AGIC-and-Nginx-Ingress/README.md: -------------------------------------------------------------------------------- 1 | # AGIC Ingress - Multiple Ingress Controllers 2 | 3 | ## Step-01: Introduction 4 | ### NGINX Ingress Controller: What are we going to learn? 5 | - We are going to create a **Static Public IP** for Ingress in Azure AKS 6 | - Associate that Public IP to **Ingress Controller** during installation. 7 | - We are going to create a namespace `ingress-nginx` for Ingress Controller where all ingress controller related things will be placed. 8 | - Create / Review Ingress Manifest 9 | - We are going to understand about `Ingress Class` and `Ingress Class Name` 10 | - We are going to deploy Applications to both Azure AGIC and Nginx Ingress with `ingressClassName` and Verify 11 | ```yaml 12 | # With ingressClassName in Ingress Manifest 13 | ## This will associate to Nginx Ingress Controller 14 | spec: 15 | ingressClassName: nginx 16 | 17 | ## This will associate to Azure AGIC Controller 18 | spec: 19 | ingressClassName: azure-application-gateway 20 | ``` 21 | 22 | ## Step-02: Create Static Public IP 23 | ```t 24 | # Get the resource group name of the AKS cluster 25 | az aks show --resource-group agicdemo --name agic-cluster --query nodeResourceGroup -o tsv 26 | 27 | # TEMPLATE - Create a public IP address with the static allocation 28 | az network public-ip create --resource-group --name myAKSPublicIPForIngress --sku Standard --allocation-method static --query publicIp.ipAddress -o tsv 29 | 30 | # REPLACE - Create Public IP: Replace Resource Group value 31 | az network public-ip create --resource-group MC_agicdemo_agic-cluster_eastus --name myAKSPublicIPForNginxIngress --sku Standard --allocation-method static --query publicIp.ipAddress -o tsv 32 | ``` 33 | - Make a note of Static IP which we will use in next step when installing Ingress Controller 34 | ```t 35 | # Make a note of Public IP created for Ingress 36 | 20.121.21.149 37 | ``` 38 | 39 | ## Step-03: Install Nginx Ingress Controller 40 | - [ingress-nginx Controller Git Repo](https://github.com/kubernetes/ingress-nginx) 41 | ```t 42 | # List Ingress Class 43 | kubectl get ingressclass 44 | 45 | # Install Helm3 (if not installed) 46 | brew install helm 47 | 48 | # Create a namespace for your ingress resources 49 | kubectl create namespace ingress-nginx 50 | 51 | # Add the official stable repository 52 | helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx 53 | helm repo update 54 | 55 | # Search Helm Repo 56 | helm search repo ingress-nginx 57 | helm search repo ingress-nginx --versions 58 | 59 | # Customizing the Chart Before Installing. 60 | helm show values ingress-nginx/ingress-nginx 61 | 62 | # Use Helm to deploy an NGINX ingress controller 63 | helm install ingress-nginx ingress-nginx/ingress-nginx \ 64 | --namespace ingress-nginx \ 65 | --set controller.replicaCount=2 \ 66 | --set controller.service.externalTrafficPolicy=Local \ 67 | --set controller.service.loadBalancerIP="REPLACE_STATIC_IP" 68 | 69 | # Replace Static IP captured in Step-02 (without beta for NodeSelectors) 70 | helm install ingress-nginx ingress-nginx/ingress-nginx \ 71 | --namespace ingress-nginx \ 72 | --set controller.replicaCount=2 \ 73 | --set controller.service.externalTrafficPolicy=Local \ 74 | --set controller.service.loadBalancerIP="20.121.21.149" 75 | 76 | # List Ingress Class 77 | kubectl get ingressclass 78 | 79 | # List Services with labels 80 | kubectl get service -l app.kubernetes.io/name=ingress-nginx --namespace ingress-nginx 81 | kubectl get service -n ingress-nginx 82 | 83 | # List Pods 84 | kubectl get pods -n ingress-nginx 85 | kubectl get all -n ingress-nginx 86 | 87 | # Helm List 88 | helm list -n ingress-nginx 89 | 90 | # Helm status --show-resources 91 | helm status --show-resources -n ingress-nginx 92 | helm status --show-resources ingress-nginx -n ingress-nginx 93 | Observation: 94 | 1. Will show all the kubernetes resources created as part of this Helm Chart in Helm Release 95 | 96 | 97 | # Access Public IP 98 | http:// 99 | http://20.121.21.149 100 | 101 | # Output should be 102 | 404 Not Found from Nginx 103 | 104 | # Verify Load Balancer on Azure Mgmt Console 105 | Primarily refer Settings -> Frontend IP Configuration 106 | ``` 107 | 108 | ## Step-04: Review Application k8s manifests with Ingress Class 109 | ### Step-04-01: kube-manifests folder: kube-manifests 110 | #### Folder: 01-App1-NginxIC** 111 | - 01-NginxApp1-Deployment.yml 112 | - 02-NginxApp1-ClusterIP-Service.yml 113 | - 03-Ingress.yml 114 | ```yaml 115 | spec: 116 | ingressClassName: nginx 117 | ``` 118 | #### Folder: 02-App2-AGIC 119 | - 01-NginxApp2-Deployment.yml 120 | - 02-NginxApp2-ClusterIP-Service.yml 121 | - 03-Ingress.yml 122 | ```yaml 123 | spec: 124 | ingressClassName: azure-application-gateway 125 | ``` 126 | 127 | ### Step-04-02: Deploy Application k8s manifests and verify 128 | ```t 129 | # Deploy 130 | kubectl apply -R -f kube-manifests 131 | 132 | # List Pods 133 | kubectl get pods 134 | 135 | # List Services 136 | kubectl get svc 137 | 138 | # List Ingress 139 | kubectl get ingress 140 | 141 | # Access Applications 142 | http:///app1/index.html 143 | http:///app2/index.html 144 | 145 | # Verify Load Balancers 146 | 1. Load Balancer 147 | 2. Application Gateway 148 | ``` 149 | 150 | ### Step-04-03: Clean-Up Apps 151 | ```t 152 | # Delete Apps 153 | kubectl delete -R -f kube-manifests 154 | ``` 155 | 156 | 157 | 158 | ## Ingress Annotation Reference 159 | - https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/ 160 | 161 | ## Other References 162 | - https://github.com/kubernetes/ingress-nginx 163 | - https://github.com/kubernetes/ingress-nginx/blob/master/charts/ingress-nginx/values.yaml 164 | - https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.34.1/deploy/static/provider/cloud/deploy.yaml 165 | - https://kubernetes.github.io/ingress-nginx/deploy/#azure 166 | - https://helm.sh/docs/intro/install/ 167 | - https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#ingress-v1-networking-k8s-io 168 | - [Kubernetes Ingress API Reference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#ingress-v1-networking-k8s-io) 169 | - [Ingress Path Types](https://kubernetes.io/docs/concepts/services-networking/ingress/#path-types) 170 | 171 | ## Important Note 172 | ``` 173 | Ingress Admission Webhooks 174 | With nginx-ingress-controller version 0.25+, the nginx ingress controller pod exposes an endpoint that will integrate with the validatingwebhookconfiguration Kubernetes feature to prevent bad ingress from being added to the cluster. This feature is enabled by default since 0.31.0. 175 | ``` 176 | -------------------------------------------------------------------------------- /26-AGIC-and-Nginx-Ingress/kube-manifests/01-App1-NginxIC/01-NginxApp1-Deployment.yaml: -------------------------------------------------------------------------------- 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: ghcr.io/stacksimplify/kube-nginxapp1:1.0.0 20 | ports: 21 | - containerPort: 80 22 | 23 | -------------------------------------------------------------------------------- /26-AGIC-and-Nginx-Ingress/kube-manifests/01-App1-NginxIC/02-NginxApp1-ClusterIP-Service.yaml: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /26-AGIC-and-Nginx-Ingress/kube-manifests/01-App1-NginxIC/03-Ingress.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: app1-ingress-nginxic 5 | spec: 6 | ingressClassName: nginx 7 | rules: 8 | - http: 9 | paths: 10 | - path: / 11 | pathType: Prefix 12 | backend: 13 | service: 14 | name: app1-nginx-clusterip-service 15 | port: 16 | number: 80 17 | 18 | 19 | -------------------------------------------------------------------------------- /26-AGIC-and-Nginx-Ingress/kube-manifests/02-App2-AGIC/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: ghcr.io/stacksimplify/kube-nginxapp2:1.0.0 20 | ports: 21 | - containerPort: 80 22 | -------------------------------------------------------------------------------- /26-AGIC-and-Nginx-Ingress/kube-manifests/02-App2-AGIC/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 | -------------------------------------------------------------------------------- /26-AGIC-and-Nginx-Ingress/kube-manifests/02-App2-AGIC/03-Ingress.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: app2-ingress-agic 5 | spec: 6 | ingressClassName: azure-application-gateway 7 | rules: 8 | - http: 9 | paths: 10 | - path: / 11 | pathType: Prefix 12 | backend: 13 | service: 14 | name: app2-nginx-clusterip-service 15 | port: 16 | number: 80 17 | 18 | 19 | -------------------------------------------------------------------------------- /27-AGIC-Install-using-Helm/helm-config.yaml: -------------------------------------------------------------------------------- 1 | # This file contains the essential configs for the ingress controller helm chart 2 | 3 | # Verbosity level of the App Gateway Ingress Controller 4 | verbosityLevel: 3 5 | 6 | ################################################################################ 7 | # Specify which application gateway the ingress controller will manage 8 | # 9 | appgw: 10 | subscriptionId: 82808767-144c-4c66-a320-b30791668b0a 11 | resourceGroup: agic-helm 12 | name: agic-appgw-helm 13 | usePrivateIP: false 14 | 15 | # Setting appgw.shared to "true" will create an AzureIngressProhibitedTarget CRD. 16 | # This prohibits AGIC from applying config for any host/path. 17 | # Use "kubectl get AzureIngressProhibitedTargets" to view and change this. 18 | shared: false 19 | 20 | ################################################################################ 21 | # Specify which kubernetes namespace the ingress controller will watch 22 | # Default value is "default" 23 | # Leaving this variable out or setting it to blank or empty string would 24 | # result in Ingress Controller observing all acessible namespaces. 25 | # 26 | # kubernetes: 27 | # watchNamespace: 28 | 29 | ################################################################################ 30 | # Specify the authentication with Azure Resource Manager 31 | # 32 | # Two authentication methods are available: 33 | # - Option 1: AAD-Pod-Identity (https://github.com/Azure/aad-pod-identity) 34 | armAuth: 35 | type: workloadIdentity 36 | identityClientID: ec9544f7-3a0a-492d-82ad-518ff4dfd80b 37 | 38 | ## Alternatively you can use Service Principal credentials 39 | # armAuth: 40 | # type: servicePrincipal 41 | # secretJSON: < --sdk-auth | base64 -w0" >> 42 | 43 | ################################################################################ 44 | # Specify if the cluster is RBAC enabled or not 45 | rbac: 46 | enabled: true # true/false -------------------------------------------------------------------------------- /27-AGIC-Install-using-Helm/kube-manifests/01-NginxApp1-Deployment.yaml: -------------------------------------------------------------------------------- 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: ghcr.io/stacksimplify/kube-nginxapp1:1.0.0 20 | ports: 21 | - containerPort: 80 22 | 23 | -------------------------------------------------------------------------------- /27-AGIC-Install-using-Helm/kube-manifests/02-NginxApp1-ClusterIP-Service.yaml: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /27-AGIC-Install-using-Helm/kube-manifests/03-Ingress-HTTP-Paths.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: nginxapp1-ingress-service 5 | spec: 6 | ingressClassName: azure-application-gateway 7 | rules: 8 | - http: 9 | paths: 10 | - path: /app1 11 | pathType: Prefix 12 | backend: 13 | service: 14 | name: app1-nginx-clusterip-service 15 | port: 16 | number: 80 17 | 18 | 19 | -------------------------------------------------------------------------------- /28-AGIC-Shared-AppGateway/01-kube-manifests/01-myapp-Deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: myapp-nginx-deployment 5 | labels: 6 | app: myapp-nginx 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: myapp-nginx 12 | template: 13 | metadata: 14 | labels: 15 | app: myapp-nginx 16 | spec: 17 | containers: 18 | - name: myapp-nginx 19 | image: ghcr.io/stacksimplify/kubenginx:1.0.0 20 | ports: 21 | - containerPort: 80 22 | 23 | -------------------------------------------------------------------------------- /28-AGIC-Shared-AppGateway/01-kube-manifests/02-myapp-ClusterIP-Service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: myapp-nginx-clusterip-service 5 | labels: 6 | app: myapp-nginx 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | app: myapp-nginx 11 | ports: 12 | - port: 80 13 | targetPort: 80 14 | -------------------------------------------------------------------------------- /28-AGIC-Shared-AppGateway/01-kube-manifests/03-Ingress-myapp.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: myapp-ingress-service 5 | spec: 6 | ingressClassName: azure-application-gateway 7 | rules: 8 | - http: 9 | paths: 10 | - path: / 11 | pathType: Prefix 12 | backend: 13 | service: 14 | name: myapp-nginx-clusterip-service 15 | port: 16 | number: 80 17 | 18 | 19 | -------------------------------------------------------------------------------- /28-AGIC-Shared-AppGateway/02-prohibit-files/prohibit-all-targets.yaml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stacksimplify/azure-kubernetes-service-agic/8855a9b2d627362865c514914c99475b6842e79b/28-AGIC-Shared-AppGateway/02-prohibit-files/prohibit-all-targets.yaml -------------------------------------------------------------------------------- /28-AGIC-Shared-AppGateway/02-prohibit-files/prohibit-myaciapp1.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: appgw.ingress.k8s.io/v1 2 | kind: AzureIngressProhibitedTarget 3 | metadata: 4 | name: prohibit-myaciapp1 5 | spec: 6 | hostname: myaciapp1.kubeoncloud.com -------------------------------------------------------------------------------- /28-AGIC-Shared-AppGateway/README.md: -------------------------------------------------------------------------------- 1 | # AGIC - Shared Application Gateway 2 | 3 | ## Step-01: Introduction 4 | 1. Learn to implement on using AGIC in combination with Shared Application Gateway 5 | 2. In this demo we are going to share Azure Application Gateway with two other Azure Container Instances in addition to AKS Apps 6 | 7 | ## Step-02: Update "shared: true" in helm-config.yaml 8 | - **File:** helm-config-shared-true.yaml 9 | ```yaml 10 | appgw: 11 | subscriptionId: 82808767-144c-4c66-a320-b30791668b0a 12 | resourceGroup: agic-helm 13 | name: agic-appgw-helm 14 | usePrivateIP: false 15 | 16 | # Setting appgw.shared to "true" will create an AzureIngressProhibitedTarget CRD. 17 | # This prohibits AGIC from applying config for any host/path. 18 | # Use "kubectl get AzureIngressProhibitedTargets" to view and change this. 19 | shared: true 20 | ``` 21 | 22 | ## Step-03: Upgrade Helm Release and Verify 23 | ```t 24 | # List Helm Releases 25 | helm list 26 | 27 | # Upgrade Helm Release 28 | helm upgrade ingress-azure application-gateway-kubernetes-ingress/ingress-azure -f helm-config-shared-true.yaml 29 | 30 | # List Helm Releases 31 | helm list 32 | Observation: 33 | 1. Helm release will be updated with new revision 34 | 35 | # List Kubernetes Pods 36 | kubectl get pods 37 | 38 | # List Prohibited Targets 39 | kubectl get AzureIngressProhibitedTargets 40 | Observation: 41 | 1. Setting appgw.shared to "true" will create an AzureIngressProhibitedTarget CRD. 42 | 2. This prohibits AGIC from applying config for any host/path. 43 | 44 | # Describe Prohibited Target 45 | kubectl describe AzureIngressProhibitedTargets prohibit-all-targets 46 | 47 | # YAML Output for Prohibited Target 48 | kubectl get AzureIngressProhibitedTargets prohibit-all-targets -o yaml 49 | ``` 50 | 51 | ## Step-04: Deploy Ingress Service and Verify on Application Gateway 52 | ```t 53 | # Deploy Kubernetes Application 54 | kubectl apply -f 01-kube-manifests 55 | Observation: 56 | 1. "prohibit-all-targets" prohibits AGIC from applying config for any host/path. 57 | 2. Ingress Service created in AKS cluster but AGIC will not be able to populate the equivalent config on Azure Application Gateway 58 | 59 | # Clean-Up 60 | kubectl delete -f 01-kube-manifests 61 | ``` 62 | 63 | ## Step-05: myaciapp1: Create Azure Container Instance App and Configure it in Application Gateway 64 | - We are going to share our Azure Application Gateway with Azure Container Instances 65 | 66 | ### Step-05-01: Create myaciapp1 Container Instance 67 | ```t 68 | # Create myaciapp1 69 | #### BASICS TAB 70 | Resource Group: agic-helm 71 | Container Name: myaciapp1 72 | Region: East US 73 | Availability Zones: NONE (LEAVE TO DEFAULT) 74 | SKU: Standard (LEAVE TO DEFAULT) 75 | Image Source: Other Registry 76 | Image Type: Public 77 | Image: ghcr.io/stacksimplify/kube-nginxapp1:1.0.0 78 | OS Type: Linux 79 | Size: 1 vcpu, 1.5 GB Memory (LEAVE TO DEFAULTS) 80 | 81 | #### Networking 82 | Networking Type: Public 83 | DNS Label: myaciapp1 84 | DNS Label scope reuse: Tenant (LEAVE TO DEFAULTS) 85 | Ports: 80 86 | 87 | #### ADVANCED TAB 88 | LEAVE TO DEFAULTS 89 | 90 | #### TAGS TAB 91 | LEAVE TO DEFAULTS 92 | 93 | REVIEW AND CREATE 94 | CREATE 95 | ``` 96 | 97 | ### Step-05-02: Create myaciapp1 Application Gateway Configurations 98 | ```t 99 | # Application Gateway: agic-appgw-helm 100 | ## Backend Pool 101 | Name: myaciapp1-bpool 102 | Target: myaciapp1.ejaxevaacmbzhegf.eastus.azurecontainer.io 103 | LEAVE ALL TO DEFAULTS AND CREATE 104 | 105 | ## Backend Settings 106 | Name: myaciapp1-bset 107 | LEAVE ALL DEFAULTS AND CREATE 108 | 109 | ## Listener 110 | Name: myaciapp1-listener 111 | Listener Type: Multisite 112 | Host type: Multiple/wildcard 113 | Host names: myaciapp1.kubeoncloud.com 114 | LEAVE ALL TO DEFAULTS AND CREATE 115 | 116 | ## Rules 117 | Name: myaciapp1-rule 118 | Priority: 100 119 | Listener: myaciapp1-listener 120 | Target Type: Backend Pool 121 | Backend Target: myaciapp1-bpool 122 | Backend Settings: myaciapp1-bset 123 | LEAVE ALL TO DEFAULTS AND CREATE 124 | ``` 125 | 126 | ### Step-05-03: Create DNS Record in Azure DNS Zones and Access Application 127 | ```t 128 | # DNS Zones: kubeoncloud.com 129 | Name: myaciapp1 130 | IP Address: PUBLIC-IP of AppGw 131 | Final DNS Name looks like: myaciapp1.kubeoncloud.com 132 | 133 | # Verify Application 134 | http://myaciapp1.kubeoncloud.com/app1/index.html 135 | ``` 136 | 137 | 138 | ## Step-06: myaciapp2: Create Azure Container Instance App and Configure it in Application Gateway 139 | - We are going to share our Azure Application Gateway with Azure Container Instances 140 | 141 | ### Step-06-01: Create myaciapp1 Container Instance 142 | ```t 143 | # Create myaciapp2 144 | #### BASICS TAB 145 | Resource Group: agic-helm 146 | Container Name: myaciapp2 147 | Region: East US 148 | Availability Zones: NONE (LEAVE TO DEFAULT) 149 | SKU: Standard (LEAVE TO DEFAULT) 150 | Image Source: Other Registry 151 | Image Type: Public 152 | Image: ghcr.io/stacksimplify/kube-nginxapp2:1.0.0 153 | OS Type: Linux 154 | Size: 1 vcpu, 1.5 GB Memory (LEAVE TO DEFAULTS) 155 | 156 | #### Networking 157 | Networking Type: Public 158 | DNS Label: myaciapp1 159 | DNS Label scope reuse: Tenant (LEAVE TO DEFAULTS) 160 | Ports: 80 161 | 162 | #### ADVANCED TAB 163 | LEAVE TO DEFAULTS 164 | 165 | #### TAGS TAB 166 | LEAVE TO DEFAULTS 167 | 168 | REVIEW AND CREATE 169 | CREATE 170 | ``` 171 | 172 | ### Step-06-02: Create myaciapp2 Application Gateway Configurations 173 | ```t 174 | # Application Gateway: agic-appgw-helm 175 | ## Backend Pool 176 | Name: myaciapp2-bpool 177 | Target: myaciapp1.ejaxevaacmbzhegf.eastus.azurecontainer.io 178 | LEAVE ALL TO DEFAULTS AND CREATE 179 | 180 | ## Backend Settings 181 | Name: myaciapp2-bset 182 | LEAVE ALL DEFAULTS AND CREATE 183 | 184 | ## Listener 185 | Name: myaciapp2-listener 186 | Listener Type: Multisite 187 | Host type: Multiple/wildcard 188 | Host names: myaciapp2.kubeoncloud.com 189 | LEAVE ALL TO DEFAULTS AND CREATE 190 | 191 | ## Rules 192 | Name: myaciapp2-rule 193 | Priority: 100 194 | Listener: myaciapp2-listener 195 | Target Type: Backend Pool 196 | Backend Target: myaciapp2-bpool 197 | Backend Settings: myaciapp2-bset 198 | LEAVE ALL TO DEFAULTS AND CREATE 199 | ``` 200 | 201 | ### Step-06-03: Create DNS Record in Azure DNS Zones and Access Application 202 | ```t 203 | # DNS Zones: kubeoncloud.com 204 | Name: myaciapp2 205 | IP Address: PUBLIC-IP of AppGw 206 | Final DNS Name looks like: myaciapp2.kubeoncloud.com 207 | 208 | # Verify Application 209 | http://myaciapp2.kubeoncloud.com/app2/index.html 210 | ``` 211 | 212 | ## Step-07: Deploy prohibit-myaciapp1 AzureIngressProhibitedTarget and Remove prohibit-all-targets 213 | ```t 214 | # List AzureIngressProhibitedTargets 215 | kubectl get AzureIngressProhibitedTargets 216 | 217 | # Deply prohibit-myaciapp1 AzureIngressProhibitedTarget 218 | kubectl apply -f 02-prohibit-files/prohibit-myaciapp1.yaml 219 | Observation: 220 | 1. We will ensure AGIC prohibits touching myaciapp1 configs 221 | 2. We will not create any prohibit for myaciapp2 and see how AGIC clears all the myaciapp2 configs from Azure Application Gateway 222 | 223 | # List AzureIngressProhibitedTargets 224 | kubectl get AzureIngressProhibitedTargets 225 | 226 | # Delete prohibit-all-targets 227 | kubectl delete AzureIngressProhibitedTargets prohibit-all-targets 228 | ``` 229 | 230 | ## Step-08: Deploy Sample Application and see what happens in Azure Application Gateway 231 | ```t 232 | # Deploy k8s Application 233 | kubectl apply -f 01-kube-manifests 234 | Observation: 235 | 1. AGIC creates myapp configs in AppGw 236 | 2. AGIC doesnt touch myaciapp1 configs in AppGw because we created "prohibit-myaciapp1" 237 | 3. AGIC deletes myaciapp2 configs in AppGw 238 | ``` 239 | 240 | ## Step-09: Clean-Up 241 | ```t 242 | # Delete k8s Applications 243 | kubectl delete -f 01-kube-manifests 244 | 245 | # Delete myaciapp1 and myaciapp2 246 | 1. Delete myaciapp1 Container Instance 247 | 2. Delete myaciapp2 Container Instance 248 | 249 | # Cleanup myaciapp1 related configs in AppGw 250 | 1. Listener 251 | 2. Rule 252 | 3. Backend Setting 253 | 4. Backend Pool 254 | ``` 255 | 256 | -------------------------------------------------------------------------------- /28-AGIC-Shared-AppGateway/helm-config-shared-true.yaml: -------------------------------------------------------------------------------- 1 | # This file contains the essential configs for the ingress controller helm chart 2 | 3 | # Verbosity level of the App Gateway Ingress Controller 4 | verbosityLevel: 3 5 | 6 | ################################################################################ 7 | # Specify which application gateway the ingress controller will manage 8 | # 9 | appgw: 10 | subscriptionId: 82808767-144c-4c66-a320-b30791668b0a 11 | resourceGroup: agic-helm 12 | name: agic-appgw-helm 13 | usePrivateIP: false 14 | 15 | # Setting appgw.shared to "true" will create an AzureIngressProhibitedTarget CRD. 16 | # This prohibits AGIC from applying config for any host/path. 17 | # Use "kubectl get AzureIngressProhibitedTargets" to view and change this. 18 | shared: true 19 | 20 | ################################################################################ 21 | # Specify which kubernetes namespace the ingress controller will watch 22 | # Default value is "default" 23 | # Leaving this variable out or setting it to blank or empty string would 24 | # result in Ingress Controller observing all acessible namespaces. 25 | # 26 | # kubernetes: 27 | # watchNamespace: 28 | 29 | ################################################################################ 30 | # Specify the authentication with Azure Resource Manager 31 | # 32 | # Two authentication methods are available: 33 | # - Option 1: AAD-Pod-Identity (https://github.com/Azure/aad-pod-identity) 34 | armAuth: 35 | type: workloadIdentity 36 | identityClientID: ec9544f7-3a0a-492d-82ad-518ff4dfd80b 37 | 38 | ## Alternatively you can use Service Principal credentials 39 | # armAuth: 40 | # type: servicePrincipal 41 | # secretJSON: < --sdk-auth | base64 -w0" >> 42 | 43 | ################################################################################ 44 | # Specify if the cluster is RBAC enabled or not 45 | rbac: 46 | enabled: true # true/false -------------------------------------------------------------------------------- /29-AGIC-Watch-Namespaces/01-app1-staging-kube-manifests/01-NginxApp1-Deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: app1-nginx-deployment 5 | labels: 6 | app: app1-nginx 7 | namespace: staging 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: ghcr.io/stacksimplify/kube-nginxapp1:1.0.0 21 | ports: 22 | - containerPort: 80 23 | 24 | -------------------------------------------------------------------------------- /29-AGIC-Watch-Namespaces/01-app1-staging-kube-manifests/02-NginxApp1-ClusterIP-Service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: app1-nginx-clusterip-service 5 | labels: 6 | app: app1-nginx 7 | namespace: staging 8 | spec: 9 | type: ClusterIP 10 | selector: 11 | app: app1-nginx 12 | ports: 13 | - port: 80 14 | targetPort: 80 15 | -------------------------------------------------------------------------------- /29-AGIC-Watch-Namespaces/01-app1-staging-kube-manifests/03-Ingress-app1.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: ingress-app1 5 | namespace: staging 6 | spec: 7 | ingressClassName: azure-application-gateway 8 | rules: 9 | - http: 10 | paths: 11 | - path: /app1 12 | pathType: Prefix 13 | backend: 14 | service: 15 | name: app1-nginx-clusterip-service 16 | port: 17 | number: 80 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /29-AGIC-Watch-Namespaces/02-app2-production-kube-manifests/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 | namespace: production 8 | spec: 9 | replicas: 1 10 | selector: 11 | matchLabels: 12 | app: app2-nginx 13 | template: 14 | metadata: 15 | labels: 16 | app: app2-nginx 17 | spec: 18 | containers: 19 | - name: app2-nginx 20 | image: ghcr.io/stacksimplify/kube-nginxapp2:1.0.0 21 | ports: 22 | - containerPort: 80 23 | -------------------------------------------------------------------------------- /29-AGIC-Watch-Namespaces/02-app2-production-kube-manifests/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 | namespace: production 8 | spec: 9 | type: ClusterIP 10 | selector: 11 | app: app2-nginx 12 | ports: 13 | - port: 80 14 | targetPort: 80 15 | 16 | -------------------------------------------------------------------------------- /29-AGIC-Watch-Namespaces/02-app2-production-kube-manifests/03-Ingress-app2.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: ingress-app2 5 | namespace: production 6 | spec: 7 | ingressClassName: azure-application-gateway 8 | rules: 9 | - http: 10 | paths: 11 | - path: /app2 12 | pathType: Prefix 13 | backend: 14 | service: 15 | name: app2-nginx-clusterip-service 16 | port: 17 | number: 80 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /29-AGIC-Watch-Namespaces/README.md: -------------------------------------------------------------------------------- 1 | # AGIC - Watch Namespaces 2 | 3 | ## Step-01: Introduction 4 | - How to direct AGIC to wathc specific namespaces by updating helm-config.yaml ? 5 | ```yaml 6 | ################################################################################ 7 | # Specify which kubernetes namespace the ingress controller will watch 8 | # Default value is "default" 9 | # Leaving this variable out or setting it to blank or empty string would 10 | # result in Ingress Controller observing all acessible namespaces. 11 | # 12 | kubernetes: 13 | watchNamespace: production 14 | ``` 15 | 16 | ## Step-02: Create Namespaces 17 | ```t 18 | # Create Namespaces 19 | kubectl create namespace staging 20 | kubectl create namespace production 21 | ``` 22 | 23 | ## Step-03: Review App1 and App2 Kubernetes Manifests 24 | ```t 25 | # Folder: 01-app1-staging-kube-manifests 26 | 01-NginxApp1-Deployment.yaml 27 | 02-NginxApp1-ClusterIP-Service.yaml 28 | 03-Ingress-app1.yaml 29 | 30 | # Folder: 02-app2-production-kube-manifests 31 | 01-NginxApp2-Deployment.yml 32 | 02-NginxApp2-ClusterIP-Service.yml 33 | 03-Ingress-app2.yaml 34 | ``` 35 | 36 | ## Step-04: Deploy App1 and App2 Applications 37 | ```t 38 | # Deploy App1 to Staging Namespace 39 | kubectl apply -f 01-app1-staging-kube-manifests 40 | 41 | # Deploy App2 to Production Namespace 42 | kubectl apply -f 02-app2-production-kube-manifests 43 | 44 | # Review App1 and App2 in Application Gateway 45 | Backend Pools 46 | Backend Settings 47 | Rules 48 | Listeners 49 | 50 | # List Pods 51 | kubect get pods -n staging 52 | kubect get pods -n production 53 | 54 | # List Ingress 55 | kubectl get ingress -n staging 56 | kubectl get ingress -n production 57 | 58 | # Access App1 and App2 59 | http://APPGW-IP/app1/index.html 60 | http://APPGW-IP/app2/index.html 61 | 62 | # Clean-Up 63 | kubectl delete -f 01-app1-staging-kube-manifests 64 | kubectl delete -f 02-app2-production-kube-manifests 65 | ``` 66 | 67 | ## Step-05: Review helm-config-watch-prod-namespace.yaml 68 | - **File:** helm-config-watch-prod-namespace.yaml 69 | ```yaml 70 | # This file contains the essential configs for the ingress controller helm chart 71 | 72 | # Verbosity level of the App Gateway Ingress Controller 73 | verbosityLevel: 3 74 | 75 | ################################################################################ 76 | # Specify which application gateway the ingress controller will manage 77 | # 78 | appgw: 79 | subscriptionId: 82808767-144c-4c66-a320-b30791668b0a 80 | resourceGroup: agic-helm 81 | name: agic-appgw-helm 82 | usePrivateIP: false 83 | 84 | # Setting appgw.shared to "true" will create an AzureIngressProhibitedTarget CRD. 85 | # This prohibits AGIC from applying config for any host/path. 86 | # Use "kubectl get AzureIngressProhibitedTargets" to view and change this. 87 | shared: true 88 | 89 | ################################################################################ 90 | # Specify which kubernetes namespace the ingress controller will watch 91 | # Default value is "default" 92 | # Leaving this variable out or setting it to blank or empty string would 93 | # result in Ingress Controller observing all acessible namespaces. 94 | # 95 | kubernetes: 96 | watchNamespace: production 97 | 98 | ################################################################################ 99 | # Specify the authentication with Azure Resource Manager 100 | # 101 | # Two authentication methods are available: 102 | # - Option 1: AAD-Pod-Identity (https://github.com/Azure/aad-pod-identity) 103 | armAuth: 104 | type: workloadIdentity 105 | identityClientID: ec9544f7-3a0a-492d-82ad-518ff4dfd80b 106 | 107 | ## Alternatively you can use Service Principal credentials 108 | # armAuth: 109 | # type: servicePrincipal 110 | # secretJSON: < --sdk-auth | base64 -w0" >> 111 | 112 | ################################################################################ 113 | # Specify if the cluster is RBAC enabled or not 114 | rbac: 115 | enabled: true # true/false 116 | ``` 117 | 118 | 119 | ## Step-06: Upgrade Helm Release and Verify 120 | ```t 121 | # List Helm Releases 122 | helm list 123 | 124 | # Add Helm Repository (if not added in local terminal) 125 | helm repo add application-gateway-kubernetes-ingress https://appgwingress.blob.core.windows.net/ingress-azure-helm-package/ 126 | 127 | # Upgrade Helm Release 128 | helm upgrade ingress-azure application-gateway-kubernetes-ingress/ingress-azure -f helm-config-watch-prod-namespace.yaml 129 | 130 | # List Helm Releases 131 | helm list 132 | helm list --output=yaml 133 | Observation: 134 | 1. Helm release will be updated with new revision 135 | 136 | # List Kubernetes Pods 137 | kubectl get pods 138 | ``` 139 | 140 | ## Step-07: Deploy App1 and App2 Applications 141 | ```t 142 | # Deploy App1 to Staging Namespace 143 | kubectl apply -f 01-app1-staging-kube-manifests 144 | 145 | # Deploy App2 to Production Namespace 146 | kubectl apply -f 02-app2-production-kube-manifests 147 | 148 | # Review App1 and App2 in Application Gateway 149 | Backend Pools 150 | Backend Settings 151 | Rules 152 | Listeners 153 | Observation: 154 | 1. Only App2 deployed to production namespace related entries will be present in Application Gateway 155 | 156 | # List Pods 157 | kubect get pods -n staging 158 | kubect get pods -n production 159 | 160 | # List Ingress 161 | kubectl get ingress -n staging 162 | kubectl get ingress -n production 163 | Observation: 164 | 1. Only App2 from production namespace will have the AppGw Public IP 165 | 2. For App1 from staging namespace will not have any IP associated 166 | 167 | # Access App2 from Production Namespace 168 | http://APPGW-IP/app2/index.html 169 | 170 | # Clean-Up 171 | kubectl delete -f 01-app1-staging-kube-manifests 172 | kubectl delete -f 02-app2-production-kube-manifests 173 | ``` 174 | 175 | ## Step-08: Clean-up 176 | ```t 177 | # Helm Uninstall 178 | helm list 179 | helm uninstall ingress-azure 180 | 181 | # Delete Resource Group 182 | Resource Group: agic-helm 183 | 1. Verify AKS Cluster got deleted 184 | 2. Veify AppGw got deleted 185 | ``` -------------------------------------------------------------------------------- /29-AGIC-Watch-Namespaces/helm-config-watch-prod-namespace.yaml: -------------------------------------------------------------------------------- 1 | # This file contains the essential configs for the ingress controller helm chart 2 | 3 | # Verbosity level of the App Gateway Ingress Controller 4 | verbosityLevel: 3 5 | 6 | ################################################################################ 7 | # Specify which application gateway the ingress controller will manage 8 | # 9 | appgw: 10 | subscriptionId: 82808767-144c-4c66-a320-b30791668b0a 11 | resourceGroup: agic-helm 12 | name: agic-appgw-helm 13 | usePrivateIP: false 14 | 15 | # Setting appgw.shared to "true" will create an AzureIngressProhibitedTarget CRD. 16 | # This prohibits AGIC from applying config for any host/path. 17 | # Use "kubectl get AzureIngressProhibitedTargets" to view and change this. 18 | shared: true 19 | 20 | ################################################################################ 21 | # Specify which kubernetes namespace the ingress controller will watch 22 | # Default value is "default" 23 | # Leaving this variable out or setting it to blank or empty string would 24 | # result in Ingress Controller observing all acessible namespaces. 25 | # 26 | kubernetes: 27 | watchNamespace: production 28 | 29 | ################################################################################ 30 | # Specify the authentication with Azure Resource Manager 31 | # 32 | # Two authentication methods are available: 33 | # - Option 1: AAD-Pod-Identity (https://github.com/Azure/aad-pod-identity) 34 | armAuth: 35 | type: workloadIdentity 36 | identityClientID: ec9544f7-3a0a-492d-82ad-518ff4dfd80b 37 | 38 | ## Alternatively you can use Service Principal credentials 39 | # armAuth: 40 | # type: servicePrincipal 41 | # secretJSON: < --sdk-auth | base64 -w0" >> 42 | 43 | ################################################################################ 44 | # Specify if the cluster is RBAC enabled or not 45 | rbac: 46 | enabled: true # true/false -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [Azure Kubernetes Service AGIC Ingress: 30 Real-World Demos](https://links.stacksimplify.com/azure-kubernetes-service-agic) 2 | 3 | [![Image](azure-agic1.png "Azure Kubernetes Service AGIC Ingress: 30 Real-World Demos")](https://links.stacksimplify.com/azure-kubernetes-service-agic) 4 | 5 | 6 | 7 | ## [Course Details](https://links.stacksimplify.com/azure-kubernetes-service-agic) 8 | - **Title:** [Azure Kubernetes Service AGIC Ingress: 30 Real-World Demos](https://links.stacksimplify.com/azure-kubernetes-service-agic) 9 | - **Sub Title:** Ingress URL & Domain Routing, Health Probes, Helm, Cert-Manager, External DNS, Lets Encrypt, E2E SSL, WAF, Rewrite Rules 10 | 11 | ## [Course Modules](https://links.stacksimplify.com/azure-kubernetes-service-agic) 12 | 01. AGIC Install Greenfield 13 | 02. AGIC Default Backend 14 | 03. AGIC Ingress Paths 15 | 04. AGIC Ingress URLRouting 16 | 05. AGIC Backend Path Prefix 17 | 06. AGIC Backend Hostname 18 | 07. AGIC Cookie-based Affinity 19 | 08. AGIC Override Frontend Port 20 | 09. AGIC Rewrite Rule Set 21 | 10. AGIC Probes Default and HTTP 22 | 11. AGIC Probes Readniess Liveness 23 | 12. AGIC Probes Annotations 24 | 13. Delegate Domain from AWS Route53 to Azure DNS Zones 25 | 14. ExternalDNS for AzureDNS on AKS 26 | 15. AGIC ExternalDNS Basic 27 | 16. AGIC Domain Name Routing 28 | 17. AGIC Ingress TLS 29 | 18. AGIC SSL Redirect 30 | 19. AGIC Upload SSLCert Application Gateway 31 | 20. AGIC Backend SSL Application 32 | 21. AGIC End2End SSL 33 | 22. AGIC SSL with LetsEncrypt 34 | 23. AGIC WAF OWASP 35 | 24. AGIC WAF Policy 36 | 25. AGIC Private IP 37 | 26. AGIC and Nginx Ingress 38 | 27. AGIC Install using Helm 39 | 28. AGIC Shared Application Gateway 40 | 29. AGIC Watch Namespaces 41 | 42 | 43 | ## [What will students learn in your course?](https://links.stacksimplify.com/azure-kubernetes-service-agic) 44 | - You will master each and every Ingress concept on Azure Application Gateway Ingress Controller (AGIC) with 30+ Real-World Demos 45 | - You will implement Path based and Domain based Routing using Ingress Service 46 | - You will implement 5 demos for Health Probes in combination with Ingress Annotations, Readiness, liveness probes 47 | - You will install External DNS and implement automatic addition of DNS records in Azure DNS Zones 48 | - You will implement automatic provisioning of production grade SSL Certificates using Cert-Manager and Lets Encrypt 49 | - You will implement 6 demos on Ingress SSL which includes SSL TLS, End to End SSL and many more. 50 | - You will implement Azure Web Application Firewall usecases in combination with Ingress Service 51 | - You will use Helm CLI to install Azure Application Gateway Ingress Controller (AGIC) on Azure AKS Cluster 52 | - You will implement a Shared Azure Application Gateway concept with a practical demo 53 | - You will implement Azure Application Gateway Ingress Controller (AGIC) Watch Namespaces concept with 2 practical demos. 54 | - You will also implement Ingress important concepts cookie based affinity, backend path prefix, backend hostname, override frontend ports and Rewrite Rule sets 55 | 56 | ## [What are the requirements or prerequisites for taking your course?](https://links.stacksimplify.com/azure-kubernetes-service-agic) 57 | - You must have Kubernetes knowledge and experience to follow with me for hands-on activities. 58 | 59 | ## [Who is this course for?](https://links.stacksimplify.com/azure-kubernetes-service-agic) 60 | - This course is designed for students who have completed my Azure Kubernetes Service with Azure DevOps and Terraform course 61 | - Infrastructure Architects or Sysadmins or Developers or DevOps Engineers who are planning to master Internet Edge traffic for Azure AKS Clusters using Load Balancers 62 | 63 | ## [Github Repositories used for this course](https://links.stacksimplify.com/azure-kubernetes-service-agic) 64 | - [azure-kubernetes-service-agic](https://github.com/stacksimplify/azure-kubernetes-service-agic) 65 | - [Course Presentation](https://github.com/stacksimplify/azure-kubernetes-service-agic/tree/main/course-presentation) 66 | - **Important Note:** Please go to these repositories and FORK these repositories and make use of them during the course. 67 | 68 | ## [Each of my courses come with](https://links.stacksimplify.com/azure-kubernetes-service-agic) 69 | - Amazing Hands-on Step By Step Learning Experiences 70 | - Practical demos for each and every concept 71 | - Friendly Support in the Q&A section 72 | - "30-Day "No Questions Asked" Money Back Guaranteed by Udemy" 73 | 74 | ## My Other AWS Courses 75 | - [Udemy Enroll](https://www.stacksimplify.com/azure-aks/courses/stacksimplify-best-selling-courses-on-udemy/) 76 | 77 | ## Stack Simplify Udemy Profile 78 | - [Udemy Profile](https://www.udemy.com/user/kalyan-reddy-9/) 79 | 80 | # HashiCorp Certified: Terraform Associate - 50 Practical Demos 81 | [![Image](https://stacksimplify.com/course-images/hashicorp-certified-terraform-associate-highest-rated.png "HashiCorp Certified: Terraform Associate - 50 Practical Demos")](https://links.stacksimplify.com/hashicorp-certified-terraform-associate) 82 | 83 | # AWS EKS - Elastic Kubernetes Service - Masterclass 84 | [![Image](https://stacksimplify.com/course-images/AWS-EKS-Kubernetes-Masterclass-DevOps-Microservices-course.png "AWS EKS Kubernetes - Masterclass")](https://www.udemy.com/course/aws-eks-kubernetes-masterclass-devops-microservices/?referralCode=257C9AD5B5AF8D12D1E1) 85 | 86 | 87 | # Azure Kubernetes Service with Azure DevOps and Terraform 88 | [![Image](https://stacksimplify.com/course-images/azure-kubernetes-service-with-azure-devops-and-terraform.png "Azure Kubernetes Service with Azure DevOps and Terraform")](https://www.udemy.com/course/azure-kubernetes-service-with-azure-devops-and-terraform/?referralCode=2499BF7F5FAAA506ED42) 89 | 90 | # Terraform on AWS with SRE & IaC DevOps | Real-World 20 Demos 91 | [![Image](https://stacksimplify.com/course-images/terraform-on-aws-best-seller.png "Terraform on AWS with SRE & IaC DevOps | Real-World 20 Demos")](https://links.stacksimplify.com/terraform-on-aws-with-sre-and-iacdevops) 92 | 93 | # Azure - HashiCorp Certified: Terraform Associate - 70 Demos 94 | [![Image](https://stacksimplify.com/course-images/azure-hashicorp-certified-terraform-associate-highest-rated.png "Azure - HashiCorp Certified: Terraform Associate - 70 Demos")](https://links.stacksimplify.com/azure-hashicorp-certified-terraform-associate) 95 | 96 | # Terraform on Azure with IaC DevOps and SRE | Real-World 25 Demos 97 | 98 | [![Image](https://stacksimplify.com/course-images/terraform-on-azure-with-iac-azure-devops-sre-1.png "Terraform on Azure with IaC DevOps and SRE | Real-World 25 Demos")](https://links.stacksimplify.com/terraform-on-azure-with-iac-devops-sre) 99 | 100 | # [Terraform on AWS EKS Kubernetes IaC SRE- 50 Real-World Demos](https://links.stacksimplify.com/terraform-on-aws-eks-kubernetes-iac-sre) 101 | 102 | [![Image](https://stacksimplify.com/course-images/terraform-on-aws-eks-kubernetes.png "Terraform on AWS EKS Kubernetes IaC SRE- 50 Real-World Demos ")](https://links.stacksimplify.com/terraform-on-aws-eks-kubernetes-iac-sre) 103 | 104 | # [Helm Masterclass: 50 Practical Demos for Kubernetes DevOps](https://links.stacksimplify.com/helm-masterclass-kubernetes-devops) 105 | [![Image](images/helm-highest-rated.png "Helm Masterclass: 50 Practical Demos for Kubernetes DevOps")](https://links.stacksimplify.com/helm-masterclass-kubernetes-devops) 106 | 107 | -------------------------------------------------------------------------------- /azure-agic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stacksimplify/azure-kubernetes-service-agic/8855a9b2d627362865c514914c99475b6842e79b/azure-agic.png -------------------------------------------------------------------------------- /azure-agic1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stacksimplify/azure-kubernetes-service-agic/8855a9b2d627362865c514914c99475b6842e79b/azure-agic1.png -------------------------------------------------------------------------------- /course-presentation/Azure-AKS-AGIC-v2.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stacksimplify/azure-kubernetes-service-agic/8855a9b2d627362865c514914c99475b6842e79b/course-presentation/Azure-AKS-AGIC-v2.pptx -------------------------------------------------------------------------------- /git-deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "Add files and do local commit" 4 | git add . 5 | git commit -am "Welcome to StackSimplify" 6 | 7 | echo "Pushing to Github Repository" 8 | git push 9 | --------------------------------------------------------------------------------