Deploy a production API and gateway with APIOps using Argo CD and ngrok
To use the ngrok Kubernetes Operator alongside Argo CD for production-ready APIOps:
Using this guide, you'll deploy a demo API to a Kubernetes cluster using an APIOps workflow. This process consolidates the backend API service, Kubernetes configurations, and API policy definitions into a single repository that defines the desired state of your deployment.
Here is what you'll be building with:
- ngrok's out-of-the-box API Gateway, which instantly tunnels production API traffic through the globally available ngrok network without requiring additional infrastructure or complex configurations.
- The ngrok Kubernetes Operator, which adds secure public ingress and middleware execution to Kubernetes deployments with declarative CRDs.
- The new Kubernetes Gateway API, a role-oriented mechanism for provisioning load-balancing infrastructure and routing traffic, with fantastic support for developer-defined paths to deploying production APIs.
- Argo CD, a declarative, GitOps continuous delivery tool for Kubernetes that lets you version-control all your definitions, configurations, and environments—even an API gateway.
- An ngrok account at any tier.
- An existing remote or local Kubernetes cluster OR minikube to create a
new demo cluster locally, which will be referred to as
[YOUR-CLUSTER]
. - Argo CD installed locally.
- kubectl installed locally.
- Helm 3.0.0+ installed locally.
Step 1: Deploy the ngrok Kubernetes Operator
Start by deploying the ngrok Kubernetes Operator to your Kubernetes cluster. This will operate as your production-grade API gateway.
-
Add the Helm repository:
helm repo add ngrok https://ngrok.github.io/kubernetes-ingress-controller
-
Install the latest Gateway API CRDs to your cluster:
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.1.0/standard-install.yaml
-
Set up the
AUTHTOKEN
andAPI_KEY
exports, which allows Helm to install the Ingress Controller using your ngrok credentials. Find yourAUTHTOKEN
under Your Authtoken in the ngrok dashboard.To create a new API key, navigate to the API section of the ngrok dashboard, click the New API Key button, change the description or owner, and click the Add API Key button. Copy the API key token shown in the modal window before closing it, as the ngrok dashboard will not show you the token again.
export NGROK_AUTHTOKEN=[YOUR-AUTHTOKEN]
export NGROK_API_KEY=[YOUR-API-KEY] -
Install the ngrok Ingress Controller with Helm under a new
ngrok-ingress-controller
namespace, using theuseExperimentalGatewayApi=true
option.helm install ngrok-ingress-controller ngrok/kubernetes-ingress-controller \
--namespace apiops-demo \
--create-namespace \
--set credentials.apiKey=$NGROK_API_KEY \
--set credentials.authtoken=$NGROK_AUTHTOKEN \
--set useExperimentalGatewayApi=true -
Verify you have deployed the ngrok Kubernetes Operator successfully via a single running pod.
kubectl get pods --namespace apiops-demo
NAME READY STATUS RESTARTS AGE
ngrok-ingress-controller-kubernetes-ingress-controller-man2fg5p 1/1 Running 0 2m23s
Step 2: Deploy Argo CD
Next, set up Argo CD on your cluster to enable GitOps.
-
Create a namespace for Argo CD:
kubectl create namespace argocd
-
Apply Argo CD's default manifest to your Kubernetes cluster.
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
-
Verify you have deployed Argo CD successfully via a single running pod.
kubectl get pods --namespace argocd
NAME READY STATUS RESTARTS AGE
argocd-application-controller-0 1/1 Running 0 44s
argocd-applicationset-controller-65bb5ff89-lcmbk 1/1 Running 0 45s
argocd-dex-server-6f898cbd9-slg8h 1/1 Running 0 45s
argocd-notifications-controller-64bc7c9f7-dgnfm 1/1 Running 0 45s
argocd-redis-5df55f45b7-2sf62 1/1 Running 0 45s
argocd-repo-server-74d5f58dc5-dgbnr 0/1 Running 0 45s
argocd-server-5b86767ddb-57xlj 0/1 Running 0 44s -
Log into the Argo CD web UI, first by creating a new port-forwarding session.
kubectl port-forward svc/argocd-server -n argocd 8080:443
When you navigate to
http://[YOUR-CLUSTER]:8080
, you'll first see a warning about self-signed certificates, which you can accept to proceed. Finally, Argo CD prompts you to login with a username and password. The username isadmin
, and you can retrieve the automatically-generated administrator password with the following:argocd admin initial-password -n argocd
Once logged in, you'll have access to the Argo CD UI.
-
Finally, log in to Argo CD via the CLI to enable administration.
argocd login [YOUR-CLUSTER]:8080
Step 3: Set up the demo API
Next, you need to set up the Git repository for the API you'll deploy behind your ngrok API gateway. GitOps (and thus APIOps) requires declarative and version-controlled configuration, and that includes the hostname for your deployment. You can't simply clone the demo API repository and apply it to your cluster, as the ngrok-supplied hostname will already be in use.
If you're curious about the fundamentals of using the ngrok Kubernetes Operator with the Kubernetes Gateway API, such as how to set up your GatewayClass
, Gateway
, and HTTPRoute
, check out our getting started guide.
If you have an existing API and GitOps configuration, you're more than welcome to skip to step 4 while adopting the Argo CD CLI commands to your Git repository.
-
Create a new ngrok static domain. Navigate to the Domains section of the ngrok dashboard and click Create Domain or New Domain. This static domain, which will look like
example.ngrok.app
, will be yourNGROK_DOMAIN
for the remainder of this guide. -
Fork the repository for the demo API at ngrok-samples/apiops-demo.
-
In your fork, open
gateway.yaml
and replace the values of lines 18 and 37 with the ngrok domain you just created (e.g.one-two-three.ngrok.app
). -
Add, commit, and push these changes to your fork.
Step 4: Deploy your demo API with Argo CD
Now that your demo API is forked and properly configured on GitHub, you can connect it to Argo CD to sync, reconcile, and deploy.
-
Register the demo app with Argo CD, replacing
[YOUR-GITHUB-USERNAME]
to point to your fork of the demo API repository.argocd app create apiops-demo \
--repo https://github.com/[YOUR-GITHUB-USERNAME]/apiops-demo.git \
--path . \
--dest-server https://kubernetes.default.svc \
--dest-namespace apiops-demoRefresh the Argo CD UI to see your app. Take note of the Missing and OutOfSync status report—they are not errors, but rather reflect the fact that Argo CD doesn't automatically sync and deploy a newly registered app.
You can still click on the app to view additional details about the deployment and the Git repository on which it is based.
-
Use the Argo CD CLI to perform a manual first sync of your registered app against your Git repository.
argocd app sync apiops-demo
Refresh the UI to see that your demo API is properly synced and deployed.
You can also navigate to the Edges view of your ngrok dashboard, then click on the Edge associated with the ngrok domain you created earlier, to see that the ngrok Kubernetes Operator pushed its definitions to the ngrok Edge via secure tunnel.
Finally, you can
curl
your deployed API, with ngrok's API gateway functionality handling ingress and TLS automatically on your behalf. You'll only seenull
in response, but it's still proof your demo API is working as expected.curl \
-X GET \
-H "Content-Type: application/json" \
https://[YOUR-NGROK-DOMAIN]/legend
Step 5: Enable APIOps in Argo CD
A fundamental component of GitOps, and thus APIOps, is that because your Git repository contains the latest version of your desired state, your deployment toolkit should automatically update the production deployment without any manual processes.
-
Enable auto sync of your app the Git repository that stores your desired state.
argocd app set apiops-demo --sync-policy automated
You can confirm this change in the Argo CD UI:
noteThe default polling interval, at which Argo CD looks for changes to the desired state in your Git repo, is 3 minutes. You can alter this behavior with the
timeout.reconciliation
value in Argo CD's configuration. -
Optionally, you can test auto sync by editing the number of replicas of the demo API deployed in your cluster. In your Git repository, open the
deployment.yaml
file and edit thereplicas
value:spec:
replicas: 5To push these changes to your production cluster, add, commit, and push them to your Git repository.
git add .
git commit -m "Increase replicas to 5"
git push origin mainArgo CD will soon poll your repository, identify changes, and reconcile the deployed state to increase the number of replicas.
Step 6: Configure your API gateway with traffic policies
The ngrok team recently rolled out support for using the Traffic Policy module alongside the Kubernetes Gateway API. This allows you to place all your Traffic Policy actions into a single NgrokTrafficPolicy
CRD, controlling your ngrok-powered API gateway with an APIOps workflow with version-controlled and declarative manifests.
The project comes with a basic example of such a Traffic Policy—see traffic-policy.yaml
for details—but because rate limiting is typically the first order of business in protecing any API from abuse, let's walk through that process.
-
In your fork of the demo API project, create a new file called
rate-limiting.yaml
. Open the file and add the following YAML:kind: NgrokTrafficPolicy
apiVersion: ngrok.k8s.ngrok.com/v1alpha1
metadata:
name: traffic-policy-rate-limiting
spec:
policy:
inbound:
- name: "Rate limiting"
actions:
- type: "rate-limit"
config:
name: "Only allow 10 requests per minute"
algorithm: "sliding_window"
capacity: 10
rate: "60s"
bucket_key:
- "req.headers['host']"This example policy includes a low limit for demonstration purposes, but you can change the
capacity
value to your needs in production. -
Next, insert the highlight YAML below into the
HTTPRoute
in yourdeployment.yaml
.This defines a filter, which must be processes during the request or response lifecycle, allowing you to inject policy into all traffic arriving to your API through your ngrok API gateway.
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: apiops-demo-route
namespace: apiops-demo
spec:
parentRefs:
- kind: Gateway
name: apiops-demo-gateway
namespace: apiops-demo
hostnames:
- "apiops-demo.ngrok.app"
rules:
- matches:
- path:
type: PathPrefix
value: /
filters:
- type: ExtensionRef
extensionRef:
group: ngrok.k8s.ngrok.com
kind: NgrokTrafficPolicy
name: "traffic-policy-rate-limiting"
backendRefs:
- name: apiops-demo-service
port: 80
kind: Service -
Add, commit, and push this change to your Git repository. Argo CD will auto sync this latest commit then reconcile the deployed state with those changes to the
NgrokTrafficPolicy
CRD andHTTPRoute
.Once the Kubernetes Operator picks up those changes, it will push definitions to your ngrok Edge—you can verify those changes directly in your ngrok dashboard:
-
Optionally, test your new rate limiting policy by
curl
-ing your API in a quick loop.for i in `seq 1 50`; do \
curl -s -o /dev/null \
-w "\n%{http_code}" \
-X GET https://apiops-demo.ngrok.app/legend ; \
doneYou should see
429
response codes as your ngrok API gateway rate-limits your IP address.
What's next?
You've now built a proof of concept for deploying an API to production using ngrok and Argo CD. You can use this combination to deploy real-world API behind a production-grade gateway with no arcane configurations or expensive external infrastructure.
In a real-world deployment, you would also integrate your Git repository with a proper CI/CD pipeline, which would run tests for security, governance, and code quality. By only merging changes that pass your CI/CD pipeline, you can better guarantee the production-readiness of your API.
If you're looking for more Traffic Policy opportunities, check out our guide to integrate with Auth0 for JWT-based authentication. Our library of "drop-in" examples contains additional use cases like blocking traffic from specific countries, deprecating API versions, event logging, and more. The Traffic Policy docs also contains an exhaustive list of actions and syntax reference.