Request an exact quote
Load Balancers / ADC migration path

From A10 Thunder ADC to HAProxy

Drop per-instance A10 Thunder ADC licensing and rebuild your virtual servers, health monitors, SSL termination, and aFleX logic as version-controlled HAProxy config with keepalived HA.

Effort
Medium
Est. timeline
~15 wks
HAProxy model
Free (Enterprise optional)
Open source
Yes
▶ Model your savings in the interactive calculator

A10 Thunder is a capable ADC, but the per-instance licensing model gets expensive fast when you scale horizontally or spin up dev and staging copies of production. HAProxy gives you the L4/L7 load balancing, TLS termination, and persistence you actually use day to day, with no license to count. The catch: you trade an integrated appliance for config-as-code and a bit of assembly. This guide maps the A10 objects you have today onto HAProxy primitives.

Map the object model first

A10’s vocabulary translates cleanly, so build a mapping table before touching config:

  • A10 slb virtual-server plus its port becomes an HAProxy frontend (one bind per VIP:port).
  • A10 slb service-group becomes a backend with its server lines.
  • A10 health monitor becomes an HAProxy option httpchk or a custom check.
  • A10 source-IP or cookie persistence becomes stick-table plus stick on.
  • aFleX scripts become ACLs, http-request rules, and map files.

Write this mapping down as a table before you touch any config. It becomes the checklist you validate against during cutover, and it surfaces the objects that do not map one to one, an aFleX script doing something procedural, a monitor with an unusual expect string, a persistence template with a short timeout, early enough to plan for rather than discover mid-migration. Include the scheduling method per service-group too, since A10 load-balancing methods map to HAProxy balance algorithms and a silent default change alters how traffic spreads.

A minimal frontend/backend looks like this:

frontend vs_web
    bind 203.0.113.10:443 ssl crt /etc/haproxy/certs/web.pem
    default_backend sg_web

backend sg_web
    balance roundrobin
    option httpchk GET /healthz
    http-check expect status 200
    server web1 10.0.1.11:8080 check inter 2s fall 3 rise 2
    server web2 10.0.1.12:8080 check inter 2s fall 3 rise 2

Translate health monitors and persistence

A10 health monitors with expect strings map directly. An HTTP monitor matching a response body becomes http-check expect string OK. For raw TCP groups, drop the option httpchk and let the default connect check stand. Set inter, fall, and rise to match your A10 retry and interval values so failover timing does not surprise you.

Persistence is where people get tripped up. A10 source-IP persistence maps to a stick-table keyed on src:

backend sg_app
    stick-table type ip size 200k expire 30m
    stick on src
    server app1 10.0.2.11:443 check
    server app2 10.0.2.12:443 check

Cookie-based session affinity becomes cookie SRV insert indirect nocache with a cookie value per server line. That is genuinely cleaner than A10’s persist templates once you see it.

Move aFleX logic to ACLs and maps

aFleX is A10’s TCL scripting hook, and most real-world aFleX does header inspection, URI routing, or redirects. None of that needs scripting in HAProxy. Host and path routing becomes ACLs:

acl is_api hdr(host) -i api.example.com
acl is_static path_beg /static/
use_backend sg_api if is_api
use_backend sg_static if is_static

For large lookup tables (geo routing, customer-to-pool mapping), use a map file with req.hdr(host),map(/etc/haproxy/hosts.map) instead of a giant if/else chain. Reserve Lua for the rare cases that actually need procedural logic.

SSL/TLS and observability

Concatenate cert plus key plus chain into a single PEM and point crt at it, or use a crt directory for SNI. Tune ssl-default-bind-ciphers and set ssl-default-bind-options ssl-min-ver TLSv1.2. For metrics, enable the runtime stats socket and run the official Prometheus exporter on /metrics, then alert on backend up count and 5xx rate.

Rebuilding VRRP with keepalived

A10 gives you VRRP in the box. Rebuild it with keepalived: two HAProxy nodes, a shared virtual IP, and a vrrp_script that checks pidof haproxy so the VIP moves when the process dies, not just when the box does. Test the failover paths you actually care about before go-live: kill the HAProxy process, pull a network link, and reboot a node, confirming each time that the VIP relocates cleanly and that connections drain the way they did on the A10 pair. HA that has never been exercised is not HA.

Cut over one VIP at a time

Resist the urge to flip everything at once. Recreate a single virtual server as a frontend and backend, complete with its checks, TLS, and persistence, and run it in parallel with the A10 still serving production. Point a test hostname or a small, controlled slice of traffic at the HAProxy VIP and compare behaviour directly, watching health-check accuracy, persistence, and TLS/SNI resolution against what the A10 does for the same requests.

When a service matches, cut its VIP over by lowering the DNS TTL ahead of the change so clients pick up the new target quickly, then swing DNS or move the IP in a planned window while watching the stats page. Keep the A10 configured and ready so rollback is a single DNS or IP move rather than a rebuild. Migrate VIP by VIP, and deliberately leave the services that lean on A10-specific capabilities, hardware SSL offload at extreme rates, integrated WAF, GSLB, until their replacements are proven. That ordering keeps the risky pieces last, when you have the most operational confidence.

Where A10 still wins

Be honest about this. Keep A10 when you need hardware SSL offload at very high connection rates, where the dedicated crypto silicon beats commodity CPU. Keep it for integrated WAF and DDoS mitigation, GSLB across sites, and a vendor TAC to call at 3am. HAProxy can do most of that with extra components, but you are now the integrator and the support line.

The short version

A10 Thunder to HAProxy is a methodical rebuild, not a converter run. You map virtual servers to frontends, service groups to backends, monitors to checks, and aFleX to ACLs and maps, then layer keepalived for HA. The payoff is eliminated per-instance licensing and config that lives in Git. Model the license savings against the engineering and HA-hardware time in the calculator above before you commit a cutover date.

Tooling & automation for this path

Recreate virtual services as HAProxy frontends/backends; port aFleX to ACLs; migrate certs and health checks; cut over via DNS/VIP.

Primary references: official HAProxy documentation ↗ and the A10 Thunder ADC documentation ↗ , always verify version-specific behavior against them before you migrate.

Frequently asked questions

How much of my aFleX will actually need scripting in HAProxy?

Usually very little. Most aFleX in the wild does header inspection, URI routing, or redirects, and every one of those becomes native HAProxy ACLs with http-request rules and, for large tables, map files, with no scripting at all. Reserve Lua for the rare aFleX that carries genuinely procedural logic or mid-request state. Audit your scripts first and you will typically find the scripting workload is smaller than expected.

How do I move A10 SSL termination and certificates onto HAProxy?

Concatenate cert, key, and chain into a single PEM per site and point crt at it, or use a crt directory so HAProxy selects by SNI. Set ssl-default-bind-ciphers and pin a minimum TLS version with ssl-default-bind-options ssl-min-ver TLSv1.2 to reproduce your A10 SSL policy. Verify the full chain against an external client before cutover, because a missing intermediate validates locally yet fails for real users.

How do I translate A10 health monitors and persistence templates accurately?

A10 HTTP monitors with expect strings become option httpchk with http-check expect string, while raw TCP groups use the default connect check, and you set inter, fall, and rise to the A10 interval and retry values so failover timing does not shift. Source-IP persistence becomes a stick-table keyed on src with stick on src, and cookie affinity becomes cookie SRV insert indirect nocache per server. Validate every check against the live A10 behaviour before you trust it.

How do I rebuild A10's in-box VRRP high availability with keepalived?

Run two HAProxy nodes with keepalived holding a shared virtual IP, and add a vrrp_script that checks the HAProxy process so the VIP moves when the daemon dies rather than only when the box does. Test failover deliberately by killing the process and rebooting a node before go-live. Cut over one VIP at a time by lowering DNS TTL ahead of the move and watching the stats page as traffic shifts.

Model your 3-year cost

Pre-filled for A10 Thunder ADC → HAProxy; adjust every figure with your own numbers. Estimates are illustrative, not vendor quotes, see our methodology.

Sized at 40 ADC instances, cost is computed on this.

Recommended for your requirements: Recommended class: Small virtual appliance (≤10 Gbps), size for 10 Gbps L7 throughput and ~50k SSL/TLS TPS. Confirm: SSL offload, WAF, GSLB, and health-check needs; deploy active/standby for HA.

Stay on A10 Thunder ADC (3yr)
$480,000
Move to HAProxy (3yr + migration)
$84,000
Projected savings
$396,000 (83%)
Payback period
4.7 mo
Build a decision report from these numbers:

Illustrative, editable figures, not vendor pricing (defaults reviewed May 2026).

Request a vendor-accurate HAProxy quote

A guided builder that turns your estimates into a requirements report (RFQ) you can send to a vendor, partner, or distributor for a binding quote, then feed the real prices back into the calculator above. How our estimates work.

  1. 1Size it
  2. 2Requirements
  3. 3Your details
  4. 4Channels & export

How big is your A10 Thunder ADC estate?

Count active plus standby instances. Not sure? Enter rough numbers, the distributor confirms exact counts later.

40 ADC instances
Default mid-size assumption (40 ADC instances)