Skip to main content
This guide walks you through deploying a demo API to a Kubernetes cluster using an APIOps workflow. It consolidates the backend API service, Kubernetes configurations, and API policy definitions into a single repository that defines the desired state of your deployment. It covers:
  • ngrok’s out-of-the-box API Gateway
  • The ngrok Kubernetes Operator, which adds secure public ingress and middleware execution with declarative CRDs
  • The Kubernetes Gateway API, for role-oriented load balancing and routing with developer-defined paths to production APIs
  • Argo CD, a declarative GitOps tool for Kubernetes that version-controls definitions, configurations, and environments—including an API gateway

What you’ll need

  • Argo CD installed locally.
  • An existing remote or local Kubernetes cluster OR minikube to create a new demo cluster locally, which will be referred to as <YOUR-CLUSTER>.
  • 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, which you can get in the ngrok dashboard or with the ngrok API.
    • You can choose from an ngrok subdomain or bring your own custom branded domain, like https://api.example.com.
    • This guide refers to this domain as <NGROK_DOMAIN>.

Deploy Argo CD

Set up Argo CD on your cluster to enable GitOps.
  1. Create a namespace for Argo CD:
    kubectl create namespace argocd
    
  2. 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
    
  3. Verify you’ve 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
    
  4. Log into the Argo CD web UI 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 is admin, 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.
  5. Log in to Argo CD via the CLI to enable administration.
    argocd login <YOUR-CLUSTER>:8080
    

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 have an existing API and GitOps configuration, you can skip to step 4 while adopting the Argo CD CLI commands to your Git repository.
  1. Create a new ngrok static domain. Go to the Domains section of the ngrok dashboard and click Create Domain or New Domain. This static domain (for example, example.ngrok.app) will be your NGROK_DOMAIN for the remainder of this guide.
  2. Fork the repository for the demo API at ngrok-samples/apiops-demo.
  3. In your fork, open gateway.yaml and replace the values of lines 18 and 37 with the ngrok domain you just created (for example, one-two-three.ngrok.app).
  4. Add, commit, and push these changes to your fork.

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.
  1. Register the demo app with Argo CD, replacing <YOUR-GITHUB-USERNAME> with 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-demo
    
    Refresh the Argo CD UI to see your app. The Missing and OutOfSync status report are not errors; they reflect that Argo CD doesn’t automatically sync and deploy a newly registered app. You can click the app to view additional details about the deployment and the Git repository on which it is based.
  2. 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 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. You can curl your deployed API; ngrok’s API gateway handles ingress and TLS automatically. You’ll only see null in response, but that confirms your demo API is working.
    curl \
      -X GET \
      -H "Content-Type: application/json" \
      https://<NGROK-DOMAIN>/legend
    

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.
  1. Enable auto sync of your app to 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.
    The default interval at which Argo CD looks for changes to the desired state in your Git repo is 3 minutes. You can alter this in Argo CD’s configuration.
  2. Optionally, test auto sync by editing the number of replicas of the demo API in your cluster. In your Git repository, open the deployment.yaml file and edit the replicas value:
    spec:
      replicas: 5
    
    To 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 main
    
    Argo CD will soon poll your repository, identify changes, and reconcile the deployed state to increase the number of replicas.

Configure your API gateway with Traffic Policies

The Traffic Policy module can be used alongside the Kubernetes Gateway API. This lets you place all your Traffic Policy actions into a single NgrokTrafficPolicy CRD and control your ngrok-powered API gateway with an APIOps workflow using version-controlled, declarative manifests. The project includes a basic example in traffic-policy.yaml. See traffic-policy.yaml for details. Because rate limiting is typically the first step in protecting any API from abuse, that process is outlined below.
  1. 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:
        on_http_request:
          - 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.
  2. Insert the YAML below into the HTTPRoute in your deployment.yaml. This defines a filter that runs during the request or response lifecycle, letting you inject policy into all traffic arriving at 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
    
  3. Add, commit, and push this change to your Git repository. Argo CD will auto sync and reconcile the deployed state with the changes to the NgrokTrafficPolicy CRD and HTTPRoute. Once the ngrok Kubernetes Operator picks up those changes, it will push definitions to your ngrok Edge—you can verify those changes directly in your ngrok dashboard.
  4. 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 ; \
    done
    
    You 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. For more Traffic Policy options, see the Auth0 JWT integration and the Traffic Policy docs for the full list of actions and syntax. The library of “drop-in” examples contains additional use cases like blocking traffic from specific countries, deprecating API versions, event logging, and more.