Microservices on AWS ECS
with Consul
A working reference implementation — and detailed written guide — for deploying a multi-service architecture on Amazon ECS using Consul for service discovery and Envoy as the sidecar proxy. Built to answer the question: how do you actually wire this together in production?
# Consul ingress gateway config
Kind = "ingress-gateway"
Name = "ingress-service"
Listeners = [{
Port = 80
Protocol = "http"
Services = [{ Name = "*" }]
}]
# Route to a service via Host header
curl -H "Host: users.consul.*" http://{ingress-ip}The problem with microservices
Splitting an application into services is the easy part. The hard part is what happens at runtime — how services find each other, how you know which ones are healthy, how you control which services are allowed to communicate, and how you get visibility into what's happening across the whole system.
Most tutorials stop at "here's how to run two containers." This project goes further: a complete, working multi-cluster deployment with a real service mesh, automated deployments, and an ingress layer.
Why Consul and Envoy
Consul handles the coordination layer — service registration, health checking, and intentions (which service is allowed to call which). Envoy handles the data plane — all network traffic flows through it, giving you load balancing, retries, and mutual TLS without changing any application code.
Together they give you a production-grade service mesh that works in any language, on any container platform. The guide covers why this stack was chosen over alternatives like Istio and Linkerd.
Architecture overview
What's covered
Multi-cluster ECS deployment
Four separate ECS clusters — two service clusters, a dedicated Consul server cluster, and an ingress gateway cluster — wired together into a single mesh.
Consul service mesh
Every service registers itself with Consul on startup. Consul handles service discovery, health checking, and authorising which services are allowed to talk to each other.
Envoy sidecar proxies
Each service runs with an Envoy proxy alongside it. All traffic between services goes through Envoy — which handles retries, load balancing, and mutual TLS automatically.
Ingress gateway
A dedicated ingress cluster accepts external traffic and routes it to the correct internal service using the Host header — no direct exposure of service IPs.
Automated CI/CD
GitHub Actions pipelines build, tag, and push Docker images to ECR, then update and redeploy the ECS task definitions — zero manual steps to ship a change.
Step-by-step guide
The repository doubles as a complete written tutorial — covering architecture decisions, Consul configuration, Dockerfile structure, and supervisord setup.