โšก Onwuachi Control Plane

TLS/SSL Certificate Renewal Process (HAProxy, Multi-Environment)

TLS/SSL Certificate Renewal Process (HAProxy, Multi-Environment)

1. Overview

Standard process for renewing, validating, and deploying TLS/SSL certificates across a multi-environment platform (Production, UAT, Dev).

Covers: certificate inventory, deployment locations, HAProxy certificate reloads, validation steps, rollback procedures, troubleshooting, and operational best practices.

Scope: HAProxy, application layer, MMP, and other TLS-enabled services across Production/UAT/Dev.

2. Deployment Mapping

Maintaining an explicit mapping of certificate โ†’ environment โ†’ host โ†’ storage โ†’ container โ†’ path โ†’ reload method is one of the most valuable things a team can have on hand โ€” it turns an emergency into a checklist. Example shape:

CertificateEnvironmentStorageContainerReload Method
*.example.comProdShared network storagehaproxyHUP
*.example.comStageShared network storagehaproxyHUP

3. Renewal Preparation

Before making changes:

4. Deployment Procedure

  1. Upload new certificate
  2. Replace PEM
  3. Verify permissions (ls -l)
  4. Validate configuration:
    docker exec haproxy-<env> \
      sh -c "haproxy -f /usr/local/etc/haproxy/haproxy.cfg -c"
    
    Expected: Configuration file is valid (warnings may also appear โ€” see below).

Important: the following warnings are expected and do not indicate a failed deployment:

option httplog not usable...
option forwardfor ignored...

These occur because several frontends/backends operate in TCP mode while those directives only apply to HTTP mode. Deployment should continue provided the configuration is reported as valid.

5. Graceful HAProxy Reload

Instead of restarting the container:

docker kill -s HUP haproxy-<env>

Expected log output:

New worker forked
Reexecuting Master process
Stopping backend...

This indicates: existing connections drain, the new worker accepts traffic, zero-downtime reload.

6. Validation Checklist

ValidationCommandExpected
Confighaproxy -cValid
Reloaddocker kill -s HUPSuccess
ProcesspsNew worker
ConnectionsssActive connections
Certificateopenssl s_clientNew cert
Containersdocker psHealthy
Logsdocker logsNo persistent alerts
docker exec haproxy-<env> sh -c "haproxy -f /usr/local/etc/haproxy/haproxy.cfg -c"
docker kill -s HUP haproxy-<env>
docker logs -f haproxy-<env>
ps -eo pid,etime,cmd | grep haproxy
watch -n1 "ss -ntp | grep haproxy"
openssl s_client -connect <host>:443
docker ps

Expected openssl s_client output:

Verify return code: 0 (ok)
TLSv1.3
TLS_AES_256_GCM_SHA384

7. Expected Log Messages

This is the section most runbooks skip, and it’s the most useful part.

Expected:

Configuration file is valid
New worker forked
Reexecuting Master process
Server ... UP
Layer6 check passed

Acceptable during reload (only if they immediately recover):

Server DOWN
Layer4 timeout
backend has no server available

Requires investigation:

Configuration file is invalid
cannot bind socket
Permission denied
Verify return code != 0
Backend remains DOWN

8. Rollback

Restore previous PEM โ†’ validate configuration โ†’ send HUP again โ†’ verify certificate โ†’ monitor logs.

9. Troubleshooting

ProblemCauseResolution
Config invalidPEM formattingVerify certificate chain
Verify return code != 0Missing intermediateRebuild bundle
Backend stays DOWNService unavailableVerify backend container
TLS still shows old certReload not completedVerify new worker

10. Post-Deployment Validation

System Context

โ† Back to Kb