This guide explains how to run the ngrok Kubernetes Operator on AWS EKS to add secure ingress to your services.
The ngrok Kubernetes Operator is the official open-source controller for adding public and secure ingress traffic to your k8s services.
It works with an AWS EKS Kubernetes cluster to provide ingress to your services as long as the cluster has outbound access to the ngrok service.
What you’ll need
- An AWS EKS cluster.
- An ngrok account.
- kubectl and Helm 3.0.0+ installed on your local workstation.
- The ngrok Kubernetes Operator installed on your cluster.
- A reserved domain from the ngrok dashboard or API; this guide refers to it as
<NGROK_DOMAIN>.
Ensure kubectl can speak with your cluster
With an AWS EKS cluster, authentication for kubectl uses a credential helper.
To deploy the ngrok Kubernetes Operator, ensure you can use the aws CLI and that the credential helper is available.
Recent versions of eksctl rely on the aws eks get-token command, which requires the aws CLI to be at least version 1.16.156.
Ensure that you have the aws CLI installed and configured with your AWS credentials.
You can confirm this works and you’re authenticated correctly by running the following command:
aws --version
aws sts get-caller-identity
If this works, you can now request a kubeconfig:
# This will merge the cluster into your $KUBECONFIG or ~/.kube/config
aws eks update-kubeconfig --region <region-code> --name <my-cluster>
# To keep your kubeconfig isolated, use:
aws eks update-kubeconfig --kubeconfig kubeconfig --region <region-code> --name <my-cluster>
export KUBECONFIG=$(pwd)/kubeconfig
Install a sample application and Kubernetes ingress
Create a manifest file (for example ngrok-manifest.yaml) with the following contents.
This deploys the tinyllama demo LLM application from ngrok-samples/tinyllama.
You will need to replace the NGROK_DOMAIN on line 50 with your own custom value.
This is the URL you will use to access your service from anywhere.
If you’re on a free account, it must be on a static subdomain which you can claim by logging into your account and following the instructions on the claim static subdomain banner.
For paid accounts, you can use a custom domain or a subdomain of ngrok.app or ngrok.dev (for example, username-loves-ingress.ngrok.app or k8s.example.com).
apiVersion: v1
kind: Service
metadata:
name: tinyllama
spec:
ports:
- name: http
port: 80
targetPort: 8080
selector:
app: tinyllama
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: tinyllama
spec:
replicas: 1
selector:
matchLabels:
app: tinyllama
template:
metadata:
labels:
app: tinyllama
spec:
containers:
- name: tinyllama
image: ghcr.io/ngrok-samples/tinyllama:main
ports:
- name: http
containerPort: 8080
---
# Configuration for ngrok's Kubernetes Operator
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tinyllama-ingress
namespace: default
spec:
ingressClassName: ngrok
rules:
- host: <NGROK_DOMAIN>
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: tinyllama
port:
number: 80
Apply the manifest file to your cluster.
kubectl apply -f ngrok-manifest.yaml
Troubleshooting: If you get an error when applying the manifest, double-check that you’ve updated the NGROK_DOMAIN value and try again.
Access your ingress URL using the subdomain you chose in the manifest (for example, https://my-awesome-k8s-cluster.ngrok.app) to confirm the tinyllama app is accessible from the internet.
Add edge security to your app
With the Traffic Policy system and the oauth action, ngrok manages OAuth protection entirely at its cloud service.
ngrok’s edge authenticates and authorizes all requests before allowing ingress and access to your endpoint, meaning you don’t need to add any additional services to your cluster, or alter any routes.
To enable the oauth action, you’ll create a new NgrokTrafficPolicy custom resource and apply it to your entire Ingress with an annotation.
You can apply the policy to just a specific backend or as the default backend for an Ingress.
See the documentation on using the Operator with Ingresses.
Edit your existing ngrok-manifest.yaml manifest with the following, leaving the Service and Deployment as they were.
Note the new annotations field and the NgrokTrafficPolicy CR.
...
---
# Configuration for ngrok's Kubernetes Operator
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tinyllama-ingress
namespace: default
annotations:
k8s.ngrok.com/traffic-policy: oauth
spec:
ingressClassName: ngrok
rules:
- host: <NGROK_DOMAIN>
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: tinyllama
port:
number: 80
---
# Traffic Policy configuration for OAuth
apiVersion: ngrok.k8s.ngrok.com/v1alpha1
kind: NgrokTrafficPolicy
metadata:
name: oauth
namespace: default
spec:
policy:
on_http_request:
- type: oauth
config:
provider: google
Re-apply your ngrok-manifest.yaml configuration.
kubectl apply -f ngrok-manifest.yaml
When you open your demo app again, you’ll be asked to log in via Google.
That’s a start, but what if you want to authenticate only yourself or colleagues?
You can use expressions and CEL interpolation to filter out and reject OAuth logins that don’t contain example.com.
Update the NgrokTrafficPolicy portion of your manifest after changing example.com to your domain.
# Traffic Policy configuration for OAuth
apiVersion: ngrok.k8s.ngrok.com/v1alpha1
kind: NgrokTrafficPolicy
metadata:
name: oauth
namespace: default
spec:
policy:
on_http_request:
- type: oauth
config:
provider: google
- expressions:
- "!actions.ngrok.oauth.identity.email.endsWith('@example.com')"
actions:
- type: custom-response
config:
body: Hey, no auth for you ${actions.ngrok.oauth.identity.name}!
status_code: 400
Check out your deployed tinyllama app once again.
If you log in with an email that doesn’t match your domain, ngrok rejects your request.