π Prerequisites
- An ngrok account with an ngrok API key.
- The ngrok API documentation.
- Tools like
curlor Postman (or ngrokβs own API libraries). - Understanding of your existing edge configurations.
- YAML formatting skills for creating traffic policies.
- A text editor to prepare YAML payloads.
β What Youβll Be Migrating
| Edge Type | Replaced By | Policy Phases Used |
|---|---|---|
| HTTPS | Cloud Endpoint + Agent Endpoint | on_http_request, on_http_response |
| TLS/TCP | Cloud Endpoint + Agent Endpoint | on_tcp_connect |
βοΈ 1. Set Up Environment
Make sure you have:- NGROK_API_TOKEN (your personal or organization token).
- API Base URL:
https://api.ngrok.com.
π 2. List Your Edges
Use the ngrok API to list all existing edges:next_page_uri youβll want to follow it until it is null:
/edges/tls/edges/tcp
π§ 3. Determine the Target URL
Each edge has one or morehostports. Use those to define a cloud endpoint url:
| Edge Type | URL Format |
|---|---|
| HTTPS | https://yourdomain.com |
| TLS | tls://yourdomain.com:443 |
| TCP | tcp://yourdomain.com:12345 |
hostport attached to an edge if you want multiple hostports to service the same traffic flow.
π οΈ 4. Create a Traffic Policy
Each cloud endpoint will have a YAML traffic policy. Here is the base structure of a Traffic Policy:π 5. Migrate Routes (HTTPS Only)
HTTPS edges have routes, and we will need to convert each routeβs to a CEL expression based on itβsmatch_type for use on every rule that is defined.
Here are some example CEL expressions for routes based on the match_type:
| Match Type | CEL Expression |
|---|---|
exact_path | req.url.path == "/foo" |
path_prefix | req.url.path.startsWith("/api") |
expressions: block in your policy rules.
π§ 6. Convert Modules to Actions
Each module on the edge or its routes maps to one or more policy actions:| Module | Actions |
|---|---|
oauth | oauth + set-vars + custom-response for restriction |
oidc | oidc with optional auth_id + session durations |
ip_restrictions | restrict-ips |
request_headers | add-headers, remove-headers |
response_headers | add-headers, remove-headers |
circuit_breaker | circuit-breaker |
webhook_verification | verify-webhook |
compression | compress-response |
user_agent_filter | set-vars + deny (based on user-agent match) |
websocket_tcp_converter | β οΈ Not supported |
π― 7. Convert Backends
Your edgeβs backend defines where traffic goes. These should be placed after all other actions you defined above. These should be added to the end of the phase.Tunnel Group Backends
If the edge uses atunnel_group backend (identified by labels):
- Construct an internal domain for each label (for example,
service=appβservice-app.internal) - Forward traffic to each internal domain using the
forward-internalaction and fall through with theforward-internalaction. - Run the agent or create a cloud endpoint with that internal domain to receive traffic.
forward-internal to forward to https://service-app.internal and when an error occurs (like the endpoint being offline) fallback to some custom text (by leveraging on_error: continue and custom-response) describing how to get back online (this is optional).
Running internal agent endpoint via the CLI:
https://service-app.internal which points to a service running locally on the machine on port 80.
TCP/TLS Backends
These are generally Tunnel Groups and should follow the same rules as above. However, wanted to call out that you should use theon_tcp_connect phase here instead:
custom-response action for an HTTP fallback.
HTTP Response Backends
Usecustom-response to serve static content:
Failover Backends
- Loop through the list of failover backends
- For each backend type, applying the same rules in group in sequence but on each Tunnel Group, use
on_error: continueto fall-through to the next group, or HTTP Response backend.
Weighted Backends β Not yet supported
These are not officially supported today in traffic policies. You can pseudo-replicate this functionality today using multiple internal endpoints and therand macro to randomly send traffic:
βοΈ 8. Create the Cloud Endpoint
Each edgehostport should become a separate cloud endpoint with its configuration represented as JSON, and the traffic_policy embedded as stringified YAML.
Endpoint configuration object
β οΈ Ensure all newlines (\n) and indentations are preserved when stringifying YAML into JSON. Itβs best to use a library or third-party service to stringify your YAML into an object and then generate the resulting cloud endpoint JSON object.Submit to:
π§Ή 9. Clean Up the Old Edge
Once you have validated that your edge has been migrated and works, you can clean up the edge from your account:β Final Checklist
| Step | Done? |
|---|---|
Listed all edges and their hostports | |
| Converted modules to policy actions | |
Converted backends to forward-internal or custom-response | |
| Created necessary internal endpoints | |
| Created cloud endpoints | |
| Deleted the old edge |