When I’ve done it, it’s been:
- One ACME client responsible for issuing and renewing the certificate
- Certificate private key pre-distributed to each node (i.e. it never changes)
- On renewal, the ACME client pushes the renewed certificate to S3 bucket
- On consumers, daily cron task to pull the certificate from S3 and graceful reload haproxy
This was convenient because each node already had common access to an S3 bucket, but obviously you can choose whatever tech variations you want.
I’ve also experimented with using serverless frameworks to issue and renew certificates (and then push to bucket) for reliable execution and no SPOF, and it allows you to give IAM role to update DNS zone only to the e.g. serverless task, instead of your server(s).