Ziti Edge Tunnel as Sidecar on AWS ECS Fargate

I’m exploring the possibility of using Ziti Edge Tunnel as a sidecar container in AWS ECS Fargate and had a few questions around feasibility and best practices:

Has anyone on the NetFoundry / OpenZiti community or support implemented the Ziti Edge Tunnel as a sidecar within AWS ECS Fargate tasks?

If so, are there any reference examples, patterns, or architectural guidance (Docker/ECS task definition configs, IAM networking considerations, etc.) available?

Are there known limitations or recommended approaches for running the Edge Tunnel in a sidecar container on a serverless container platform like Fargate?

Any insights, experiences, or links to documentation/examples would be greatly appreciated.

@qrkourier do you have any suggestions?

I think your goal is to publish a Ziti service for consumption by a Fargate task, not the inverse: publish a Fargate task as a Ziti service. Can you confirm?

I don't think Fargate allows privileged containers, so you wouldn't be able to create a Fargate sidecar based on the Kubernetes sidecar example to create a transparent proxy for your Fargate task (Kubernetes Sidecar Proxy | NetFoundry Documentation).

ziti-edge-tunnel run (a privileged, system-wide transparent proxy that cannot be restricted to a container) is not applicable to Fargate (or most any container/cloud environment) for the same reason: Fargate does not allow you to create a privileged task because they reserve administrative privilege on the container runtime's host.

If I understood correctly that you wish your Fargate task to call a Ziti service, and if you are running a newer, prerelease version of Ziti (1.7+), then you could run a separate Fargate task or a Fargate sidecar based on the Kubernetes sidecar example (same container image, volume, env vars) with command/arg args: ["proxy"] (instead of "tproxy"). This is a "dynamic proxy" run mode that makes the Ziti tunnel act as a TCP/UDP reverse proxy for any dialable services you attach a Ziti config of type proxy.v1 to. The end result is that this Fargate task will listen on the TCP/UDP port specified in your proxy.v1 config (spec), forwarding packet data to the Ziti service's terminator.

You can do something similar if you're running latest stable Ziti (1.6), which does not have the new proxy.v1 config type, and so you must supply the list of <service name>:<TCP proxy port> pairs on which to listen on the Fargate task's IP. See ziti tunnel proxy --help for usage hints.

Yes, that is correct — my goal is for an application running in an AWS Fargate task to dial / consume a Ziti service, not to publish the Fargate task as a Ziti service.

I originally tried using the Ziti SDK in the application, but I ran into issues related to our async runtime, so I am exploring using the tunneler / proxy approach instead.

One clarification question regarding versions:

At the moment my controller is running ziti-controller 1.1.15.

From your explanation, it sounds like the recommended approach would be to run a tunneler sidecar in proxy mode (not tproxy), using either:

the new proxy.v1 service config (available in 1.7+), or

the older ziti tunnel proxy command in 1.6.

Can you please confirm:

Does the proxy.v1 config type require the controller to be upgraded to 1.7+ as well, or is it only a tunneler feature?

If I stay on controller 1.1.15, is the only supported option the legacy ziti tunnel proxy mode?

Also, just to confirm my understanding:

With the proxy mode approach, my Fargate application would connect to a local TCP port exposed by the sidecar container, and not directly resolve the Ziti service by its DNS name — correct?

Correct, if you don't upgrade your controller to 1.7+ you'll need a sidecar or separate task that runs ziti tunnel proxy <service name>:<tcp port> [<service name>:<tcp port>].

If a sidecar, then the main app could call the Ziti service on the loopback port on which you're listening with the reverse proxy tunnel.

If a separate task, then you could use CloudMap, optionally with ServiceConnect, to publish the Ziti tunnel's reverse proxy port(s) as VPC services discoverable in VPC DNS.

Additionally, the Ziti Router provides the same reverse-proxy capability, but the list of service:port pairs must be configured in its YAML file, not as run args. This might be appealing to you if you wish to have a single Fargate task performing both functions: Ziti router and reverse proxy fronting Ziti service(s) on the task loopback as a sidecar or as a VPC service.

Thanks for the clarification. Let me restate my use case more accurately.

The endpoints

- https://hospital1.xxx.example.com

- https://hospital2.xxx.example.com

are not external/public services.

These are services hosted on IoT devices, where each device is running a Ziti tunneler and binding a Ziti service.

Those services are already reachable over Ziti today.

My goal is simply:

An application running in an AWS Fargate task should dial those existing Ziti services hosted by the IoT devices.

Today, to make this work without changing the application URLs, I point

hospital*.xxx.example.com in Route 53 to an IP that forwards traffic to a Ziti router running on EC2.

This allows my app to continue using the same URLs, but it introduces an EC2-based entry point that I would like to eliminate for scalability and operational reasons.

What I would ideally like is:

From inside the Fargate task, my application continues to call:

- https://hospital1.xxx.example.com

- https://hospital2.xxx.example.com

and those calls are routed to the corresponding Ziti services (bound on the IoT devices) via a Ziti tunnel running in the Fargate task (sidecar or separate task), without relying on an external IP or router front-end.

Given the Fargate constraints (no privileged containers / no tproxy), can you confirm whether it is possible to:

hospital1.xxx.example.com → Ziti tunnel/proxy inside the Fargate task → Ziti service bound on the IoT device

hospital2.xxx.example.com → Ziti tunnel/proxy inside the Fargate task → Ziti service bound on the IoT device

while keeping the same hostnames and URLs in the application?

From your earlier explanation, it sounds like the answer is no, and that the only supported pattern on Fargate is:

application → local TCP port(s) exposed by "ziti tunnel proxy" → Ziti service

I would appreciate confirmation specifically for this “existing DNS names for IoT-bound Ziti services” scenario.

Thank you.

I understand you want your client apps to discover the Ziti services by domain names, even when the entrypoint is a sidecar. The Fargate limitation you mentioned prevents the Ziti tunnel from configuring a DNS resolver, so you must use VPC or global DNS. You could accomplish that with CloudMap, e.g., with a separate Fargate task running ziti tunnel proxy <service>:<port> (or ziti router run w/ config YAML listing the service:port pairs). In CloudMap, you'd need to configure a DNS zone, e.g., xxx.example.com, mirroring your Ziti intercepts, or a distinct DNS zone to avoid the split horizon problem, since it's a separate system and Fargate doesn't allow Ziti to configure DNS directly.

Since you strongly prefer your client apps to call a domain name instead of the loopback address, e.g., 127.0.0.1:3000, there's little benefit to using the sidecar pattern because that would involve adding the loopback address to your VPC or global DNS zone, which seems awkward at best.