Secure AKS Ingress using Application Gateway and Let's Encrypt
Secure AKS Ingress using Application Gateway and Let’s Encrypt
Introduction
When deploying applications in Azure Kubernetes Service (AKS), exposing services to the internet securely is an important requirement.
Azure provides Application Gateway Ingress Controller (AGIC) which allows Azure Application Gateway to function as an ingress controller for Kubernetes workloads.
In this guide we will cover the complete workflow:
- Enable Application Gateway Ingress Controller
- Deploy a demo NGINX application
- Expose the application using Kubernetes Ingress
- Verify application access over HTTP
- Install cert-manager
- Configure Let’s Encrypt TLS certificates
- Enable HTTPS for secure access
By the end of this guide, your application will be accessible securely using HTTPS.
Architecture Overview
User
↓
DNS (test.yourdomain.com)
↓
Azure Application Gateway
↓
Application Gateway Ingress Controller (AGIC)
↓
Kubernetes Service
↓
NGINX Pod
For HTTPS certificate issuance:
cert-manager
↓
Let's Encrypt
↓
TLS Certificate
↓
Application Gateway HTTPS Listener
Prerequisites
Before starting this tutorial ensure the following requirement is satisfied.
- An Azure Kubernetes Service (AKS) cluster is already created and running
- You have access to Azure Portal
- kubectl is installed and connected to the cluster
- helm is installed
- A domain name (required later for HTTPS)
Verify cluster connectivity:
kubectl get nodes
Step 1 — Enable Application Gateway Ingress
The first step is to enable Application Gateway Ingress Controller (AGIC).
Steps:
- Navigate to Azure Portal
- Open your AKS Cluster
- Select Networking
- Locate Application Gateway Ingress
- Click Enable Application Gateway Ingress
Azure will automatically deploy the AGIC controller inside the AKS
cluster.
Step 2 — Verify AGIC Controller
kubectl get pods -n kube-system
Expected output:
ingress-appgw-xxxxx Running
Step 3 — Deploy Demo NGINX Application
Create nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-demo
spec:
replicas: 1
selector:
matchLabels:
app: nginx-demo
template:
metadata:
labels:
app: nginx-demo
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
Apply:
kubectl apply -f nginx-deployment.yaml
Step 4 — Create Kubernetes Service
service.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-demo-service
spec:
selector:
app: nginx-demo
ports:
- port: 80
targetPort: 80
Apply:
kubectl apply -f service.yaml
Step 5 — Create Ingress Resource
ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-demo-ingress
annotations:
kubernetes.io/ingress.class: azure/application-gateway
spec:
rules:
- host: test.yourdomain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-demo-service
port:
number: 80
Apply:
kubectl apply -f ingress.yaml
Step 6 — Verify Application (HTTP)
Ensure DNS points to the Application Gateway public IP.
Open:
http://test.yourdomain.com
You should see the NGINX welcome page.
Step 7 — Install cert-manager
helm repo add jetstack https://charts.jetstack.io helm repo update
helm install cert-manager jetstack/cert-manager --namespace cert-manager
--create-namespace --set installCRDs=true
Verify:
kubectl get pods -n cert-manager
Expected output:
cert-manager
cert-manager-webhook
cert-manager-cainjector
Step 8 — Create ClusterIssuer
cluster-issuer.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
email: your-email@example.com
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: azure/application-gateway
Apply:
kubectl apply -f cluster-issuer.yaml
Verify:
kubectl get clusterissuer
Step 9 — Enable TLS in Ingress
Add TLS configuration in ingress.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-demo-ingress
annotations:
kubernetes.io/ingress.class: azure/application-gateway
cert-manager.io/cluster-issuer: letsencrypt-prod
acme.cert-manager.io/http01-edit-in-place: "true"
appgw.ingress.kubernetes.io/ssl-redirect: "true"
cert-manager.io/acme-challenge-type: http01
spec:
tls:
- hosts:
- test.yourdomain.com
secretName: test.yourdomain.com-tls
rules:
- host: test.yourdomain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-demo-service
port:
number: 80
Step 10 — Verify Certificate
kubectl get certificate
Expected:
test.yourdomain.com-tls True
Check secret:
kubectl get secret test.yourdomain.com-tls
Step 11 — Verify HTTPS
Open browser:
https://test.yourdomain.com
You should see a secure connection.
Certificate issued by:
Let’s Encrypt
Troubleshooting
Certificate not issued
Check:
kubectl get challenge
kubectl get orders
kubectl describe certificate
DNS issues
Ensure domain points to Application Gateway IP.
nslookup test.yourdomain.com
AGIC issues
Check logs:
kubectl logs -n kube-system deploy/ingress-appgw
Conclusion
In this guide we:
- Enabled Application Gateway Ingress Controller
- Deployed an NGINX application
- Exposed it using Ingress
- Verified HTTP access
- Installed cert-manager
- Configured Let’s Encrypt
- Enabled HTTPS for secure access
This setup provides automated TLS certificate management for applications running in AKS.